iOS 複製一個UIView對象實現方法,iosuiview對象實現
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
: