iOS 復制一個UIView對象,項目中要做一個新手引導,也就是給某個頁面加個遮罩,然後突出顯示出一塊視圖,在寫點提示啥的。
我的思路是加一個一模一樣的視圖到遮罩上,但是問題來瞭,簡單的視圖是可以這麼搞,復雜一點的難道也要創建一個一模一樣的嗎,那樣豈不是太麻煩瞭。
能不能直接復制一份出來,然後加到遮罩上呢?
我們都知道復制數組、字典、字符串這些用copy,mutableCopy,然後我就想當然的用我的自定義View調瞭一下copy,結果很尷尬,直接給崩瞭,說是要實現copyWithZone這個方法。
總不能所有的自定義View都是實現一遍一個方法吧!
網友們給出這麼一個方法,我欣喜若狂,趕緊拿去試一試
NSData *archiveData = [NSKeyedArchiver archivedDataWithRootObject:view]; UIView *copyView = [NSKeyedUnarchiver unarchiveObjectWithData:archiveData];
然而這個方法並不完美,在復制的copyView中,雖然所有的子控件都能顯示出來,但是地址都是nii,當然這不是問題的關鍵,最致命的是子控件裡面包含圓角的話,復制出來後,子控件的圓角都麼得啦。這就不能忍瞭,於是就有瞭這篇博客,我想瞭笨方法,給復制出來的View的子控件,加上本該有的圓角!
一言不合就上代碼:
@implementation GuideView - (instancetype)init { self = [super init]; if (self) { self.backgroundColor = [UIColor colorWithWhite:0 alpha:0.3]; self.frame = [UIScreen mainScreen].bounds; self.alpha = 0; } return self; } + (instancetype)guideView{ return [[GuideView alloc] init]; } - (void)addToView:(UIView *)view{ [self addToView:view containCorner:NO]; } /** 加給某個View上*/ - (void)addToView:(UIView *)view containCorner:(BOOL)containCorner{ // 這樣復制後,如果有子控件設置瞭圓角,復制後圓角會失效,而且所有子控件雖然都能顯示正確,但地址都是nil NSData *archiveData = [NSKeyedArchiver archivedDataWithRootObject:view]; UIView *copyView = [NSKeyedUnarchiver unarchiveObjectWithData:archiveData]; // 子控件如果包含圓角 if (containCorner == YES) { // 替換子控件 NSData * subData = [NSKeyedArchiver archivedDataWithRootObject:view.subviews]; NSArray* subViews = [NSKeyedUnarchiver unarchiveObjectWithData:subData]; [copyView removeAllSubviews]; for (UIView *subview in subViews) { [copyView addSubview:subview]; } // 在原View中找到設置瞭圓角的子控件 for (UIView *subView in view.subviews) { if (subView.layer.cornerRadius != 0) { // 在復制好的View的子控件中遍歷,找到與之對應的子控件 for (UIView *copySubView in copyView.subviews) { // 給找到的控件設置上圓角,這裡通過frame確定是否是同一個控件 if ([NSStringFromCGRect(copySubView.frame) isEqualToString:NSStringFromCGRect(subView.frame)]) { copySubView.layer.cornerRadius = subView.layer.cornerRadius; copySubView.layer.masksToBounds = YES; break; } } } } } copyView.frame = [view convertRect:view.bounds toView:kAppDelegate.window]; [self addSubview:copyView]; } - (void)show{ [kAppDelegate.window addSubview:self]; [UIView animateWithDuration:0.3 animations:^{ self.alpha = 1; }]; } - (void)disMiss{ [UIView animateWithDuration:0.3 animations:^{ self.alpha = 1; } completion:^(BOOL finished) { [self removeFromSuperview]; }]; } //- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ // [super touchesBegan:touches withEvent:event]; // [self disMiss]; //} @end
效果圖
: