Can UIView be copied?
Solution 1
Your app probably crashes with something like:
[UIView copyWithZone:]: unrecognized selector sent to instance 0x1c6280
The reason is that UIView does not implement the copying protocol, and therefore there is no copyWithZone
selector in UIView.
Solution 2
this might work for you ... archive the view and then unarchive it right after. This should give you a deep copy of a view:
id copyOfView =
[NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:originalView]];
Solution 3
You can make an UIView extension. In example swift snippet below, function copyView returns an AnyObject so you could copy any subclass of an UIView, ie UIImageView. If you want to copy only UIViews you can change the return type to UIView.
//MARK: - UIView Extensions
extension UIView
{
func copyView<T: UIView>() -> T {
return NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: self)) as! T
}
}
Example usage:
let sourceView = UIView()
let copiedView = sourceView.copyView()
Solution 4
for swift3.0.1:
extension UIView{
func copyView() -> AnyObject{
return NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: self))! as AnyObject
}
}
Solution 5
UIView
doesn't implement the NSCoping
protocol, see the declaration in UIView.h:
@interface UIView : UIResponder <NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem, UITraitEnvironment, UICoordinateSpace, UIFocusEnvironment>
So, if we want to have a copy
like method, we need to implement the NSCoping
protocol in a category or so.
Related videos on Youtube
Forrest
iOS developer with 10+ years software building experience Shanghai,China Skype: forrest.shi.ef Recent App: PushUp! https://itunes.apple.com/us/app/pushup!/id750845921?mt=8
Updated on August 09, 2020Comments
-
Forrest over 3 years
Simply using this way:
UIView* view2 = [view1 copy]; // view1 existed
This will cause simulator can not launch this app.
Try retain,
UIView* view2 = [view1 retain]; // view1 existed // modify view2 frame etc
Any modifications to
view2
will apply toview1
, I understand thatview2
share same memory withview1
.Why can't
UIView
be copied? What is the reason? -
Satyam almost 12 yearsWhat should I do to implement the copy of UIView?
-
Anonymous White over 11 yearsSo if you have a certain combination of UIView and want to use that several time you will need to subclass such UIView?
-
Engin Kurutepe over 11 yearsYes, subclassing or category with class-level factory methods that return preconfigured instances of that view.
-
Patrick Borkowicz over 11 yearsThat seems like a bit of a hack but works like a dream. ssj's answer below is basically a 'copy constructor' which is fine for small classes. You can maybe use the obj-c runtime to copy all the properties at once.. This is still easier ;)
-
bluefloyd8 about 11 yearsthis isn't answering the question.
-
Ortwin Gentz over 10 yearsThis sounds to good to be true. In my case it throws an NSInvalidArgumentException (
NSConcreteAttributedString initWithString:: nil value
) for a UILabel in the subview tree. -
Ian Newson about 10 yearsThis works, but seems to be very slow for even trivial view trees.
-
nalexn over 9 yearsIt works, but beware! It does not set values for @IBOutlets, all of them are nil after "copying"
-
Iulian Onofrei almost 9 yearsThis seems to ignore
UIImageView
s :( -
Sajjon about 8 yearsThanks, works great! ALSO please note that the copied view has no superview (parent), no constraints and no gesture recognizers (if the parent had any).
-
Sajjon about 8 yearsThanks, works great! ALSO please note that the copied view has no superview (parent), no constraints and no gesture recognizers (if the parent had any).
-
Nick Entin almost 7 yearsagree with @IanNewson, just tried 2 approaches. A method, which: 1. instantiates new view and configure it 2. instantiates new view, configures it and archive. If archivation happened already, just call unarchiveObjectsWithData on saved data. 1. result of instantiation of 200 views, where this one is a subview ~ 0.5 sec. 2. result of instantiation of 200 views, where this one is a subview ~ 0.8 sec. The view is only UIImageView with couple autoresizing masks. I would not recommend archiving/unarchiving for duplication of views...
-
iamirzhan almost 7 yearswhat if your label has other custom parameters like numberOfLines or tag? Will you set all properties?
-
paulvs over 6 yearsThis throws a
value for key (UIHighlighted) is not a boolean
exception when usingUIImageView
s. You can uselet copyView = aView.snapshotView(afterScreenUpdates: true)
instead.