Create a copy of a UIView in Swift

swift copy object
swift copy struct
swift copy dictionary
swift copy constructor
swift copy data
swift create copy of instance
example of swift copy
copy attribute swift

Because objects are reference types, not value types, if you set a UIView equal to another UIView, the views are the same object. If you modify one you'll modifying the other as well.

I have an interesting situation where I would like to add a UIView as a subview in another view, then I make some modifications, and those modifications should not affect the original UIView. How can I make a copy of the UIView so I can ensure I add that copy as a subview instead of a reference to the original UIView?

Note that I can't recreate the view in the same way the original was created, I need some way to create a copy given any UIView object.

You can't arbitrarily copy an object. Only objects that implement the NSCopying protocol can be copied.

However, there is a workaround: Since UIViews can be serialized to disk (e.g. to load from a XIB), you could use NSKeyedArchiver and NSKeyedUnarchiver to create a serialized NSData describing your view, then de-serialize that again to get an independent but identical object.

Create a copy of a UIView in Swift, Because objects are reference types, not value types, if you set a UIView equal to another UIView , the views are the same object. If you modify  An addition solution could be to just create a new UIView and then copy over any critical properties. This may not work in the OP’s case, but it could very well work for other cases. This may not work in the OP’s case, but it could very well work for other cases.

You can make an UIView extension. In example snippet below, function copyView returns an AnyObject so you could copy any subclass of an UIView, ie UIImageView. If you want to copy only UIView 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: UIView = sourceView.copyView()

iOS Quick tip, Since UIButton (which is a UIView ) can be archived, we can use NSKeyedArchiver and NSKeyedUnarchiver to create an NSData object  Create a New file → View → Give the name you want to your view (I usually use the same) → Next. Select target desired → Create First of all, we have to configure the view as freeform in the xib

Update for iOS 12.0

Methods archivedData(withRootObject:) and unarchivedObject(with:) are deprecated as of iOS 12.0.

Here is an update to @Ivan Porcolab's answer using the newer API (since 11.0), also made more general to support other types.

extension NSObject {
    func copyObject<T:NSObject>() throws -> T? {
        let data = try NSKeyedArchiver.archivedData(withRootObject:self, requiringSecureCoding:false)
        return try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? T
    }
}

How to copy objects in Swift using copy(), Well, one of the key areas is down to copying: two variables can that Swift creates a full copy so that changing the copy does not affect the  Create PDF from UIView. You can easily create a PDF file from UIView. Create an Extension of UIView and add below code in your UIView Extension file. Extension UIView { // Export pdf from Save pdf in drectory and return pdf file path func exportAsPdfFromView() -> String { let pdfPageFrame = self.bounds let pdfData = NSMutableData() UIGraphicsBeginPDFContextToData(pdfData, pdfPageFrame, nil) UIGraphicsBeginPDFPageWithInfo(pdfPageFrame, nil) guard let pdfContext = UIGraphicsGetCurrentContext()

I think that you should link you UIView with a .nib and just create a new one.

Property will not be the same, but you keep appearance and methods.

How to copy a UIView object by value / clone, So i have a UIViewController and it has a UIView property in which i draw stuff in and such. Any changes you make to the clone view will not be performed on the Mac Swift & Mac OS X/macOS system compatibility? 5. Override Both UIView Initializers. This is where things get a little tricky. UIViews can be created in two ways — in the interface builder (i.e. a storyboard or XIB), or directly in the code.

ios - Can UIView be copied?, 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,  4: Create a custom file UIView extended file (like CustomUIView.swift) Create the custom file UIView Same as .xib file but you want to select the option in source “Cocoa Touch Class” and create the new file with name CustomUIView.swift which have UIView subclass. 5: Set .xib File owner to custom class (It must be same as class name )

UIView, Views can be nested inside other views to create view hierarchies, which offer a convenient way to organize related content. Nesting a view creates a parent-child​  Custom UIView with XIB file is a very common practice in iOS Development. Custom UIView classes don’t contain XIB files when you create them. That’s why we have to make sure that we connect

Deep copy vs. shallow copy, Copying reference types creates a shallow copy. In the above code,. Lines 1 to 8: Address class type; Line 10: a1 — an instance of  You must implement this method and use it to create your view object. Configure the view using your app's current data and contents of the context parameter. The system calls this method only once, when it creates your view for the first time. For all subsequent updates, the system calls the update UIView(_: context:) method.

UIView Fundamentals, Let's add another view to the screen. First we create a frame for it. Then we instantiate a new UIView object with that frame. And to make it visible  In this Swift code snipped you will learn: How to create UIView in Swift programmatically How to add UIView as a Subview Change UIView background colour Add a border around UIView Change UIView border colour Make UIView corners rounded import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup…

Comments
  • @DannyBravo Where do you get that from? My UIView.h only declares conformance to NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem, UITraitEnvironment, UICoordinateSpace, UIFocusItem and CALayerDelegate. No NSCopying in there as far as I can see.
  • You are totally right, I got mixed up there for a bit. I'm removing my answer.
  • How is this not a factory method on UIView?
  • But it seems to lose IBOutlet bindings
  • Doesn't work if I have a custom view. the view losses it's view properties and elements.
  • Then your view is not correctly implementing -initWithCoder: and -encodeWithCoder: to serialize all its properties.
  • Methods archivedData(withRootObject:) and unarchivedObject(with:) are deprecated as of iOS 12.0.
  • not working for subclass , like class MyView:UIView , then while copying MyView it returns UIView instead.
  • That's also a good approach. If you already have a XIB that you define the object in, and you're mostly concerned about setting it up correctly, and the attributes you change on it are few, you can just load the XIB a second time (you can have XIBs with a single free-floating view in them).
  • if it's xib based.
  • I implemented this and for a second I thought it was working. But i'm copying an UIView that has subviews and the result i'm getting are the subviews, but not the view itself. I saw it debugging the view hierarchy. The view that im copying is an IBOutlet instead of UIView(). Does it sounds familiar?
  • I'm sorry. When debugging a little more what is happening is that in the copied view I get view.top = view.bottom as a constraint and that's why i don`t see it in the view hierarchy.