可以复制UIView吗?

时间:2010-12-13 05:04:03

标签: ios objective-c uiview copy

只需使用这种方式:

UIView* view2 = [view1 copy]; // view1 existed

这将导致模拟器无法启动此应用。

尝试保留,

UIView* view2 = [view1 retain]; // view1 existed
// modify view2 frame etc

view2的任何修改都将适用于view1,我了解view2view1共享相同的内存。

为什么不能复制UIView?是什么原因?

6 个答案:

答案 0 :(得分:158)

这可能对您有用...存档视图,然后立即取消存档。这应该为您提供视图的深层副本:

id copyOfView = 
[NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:originalView]];

答案 1 :(得分:33)

您的应用可能会崩溃,例如:

 [UIView copyWithZone:]: unrecognized selector sent to instance 0x1c6280

原因是UIView没有实现复制协议,因此UIView中没有copyWithZone选择器。

答案 2 :(得分:23)

您可以制作UIView扩展程序。在下面的示例swift片段中,函数copyView返回AnyObject,因此您可以复制UIView的任何子类, UIImageView。 如果您只想复制 UIViews,可以将返回类型更改为UIView。

//MARK: - UIView Extensions

    extension UIView
    {
       func copyView<T: UIView>() -> T {
            return NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: self)) as! T
       }
    }

使用示例:

let sourceView = UIView()
let copiedView = sourceView.copyView()

答案 3 :(得分:6)

for swift3.0.1:

extension UIView{
 func copyView() -> AnyObject{
    return NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: self))! as AnyObject
 }
}

答案 4 :(得分:1)

UIView没有实现NSCoping协议,请参阅 UIView.h 中的声明:

@interface UIView : UIResponder <NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem, UITraitEnvironment, UICoordinateSpace, UIFocusEnvironment>

因此,如果我们想要一个类似copy的方法,我们需要在类别左右实现NSCoping协议。

答案 5 :(得分:-6)

您可以使用以下方法制作方法:

-(UILabel*)copyLabelFrom:(UILabel*)label{
//add whatever needs to be copied
UILabel *newLabel = [[UILabel alloc]initWithFrame:label.frame];
newLabel.backgroundColor = label.backgroundColor;
newLabel.textColor = label.textColor;
newLabel.textAlignment = label.textAlignment;
newLabel.text = label.text;
newLabel.font = label.font;

return [newLabel autorelease];

}

然后你可以将你的ivar设置为返回值并保留它:

myLabel = [[self copyLabelFrom:myOtherLabel] retain];