只需使用这种方式:
UIView* view2 = [view1 copy]; // view1 existed
这将导致模拟器无法启动此应用。
尝试保留,
UIView* view2 = [view1 retain]; // view1 existed
// modify view2 frame etc
对view2
的任何修改都将适用于view1
,我了解view2
与view1
共享相同的内存。
为什么不能复制UIView
?是什么原因?
答案 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];