欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS 复制一个UIView对象实现方法

程序员文章站 2022-11-08 21:55:56
ios 复制一个uiview对象,项目中要做一个新手引导,也就是给某个页面加个遮罩,然后突出显示出一块视图,在写点提示啥的。 我的思路是加一个一模一样的视图到遮罩上,但是问题来了,简单的视图是可以这...

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

效果图

iOS 复制一个UIView对象实现方法

:iOS 复制一个UIView对象实现方法