22

The object inherits from NSObject.

Is there a method to create a copy of it as a new object?

Fattie
  • 35,446
  • 61
  • 386
  • 672
James Skidmore
  • 47,132
  • 31
  • 107
  • 135

6 Answers6

65

UIButton does not conform to NSCopying, so you cannot make a copy via -copy.

However, it does conform to NSCoding, so you can archive the current instance, then unarchive a 'copy'.

NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject: button];
UIButton *buttonCopy = [NSKeyedUnarchiver unarchiveObjectWithData: archivedData];

Afterwards, you'll have to assign any additional properties that weren't carried over in the archive (e.g. the delegate) as necessary.

Jim Correia
  • 7,034
  • 1
  • 32
  • 24
4

UIButton doesn't conform to the NSCopying protocol, so you have copy it by hand. On the other hand, it is not a bad thing, since it is not exactly clear what does it mean to copy a button. For example, should it add the button copy to the same view the original is in? Should it fire the same methods when tapped?

Marco Mustapic
  • 3,859
  • 1
  • 19
  • 20
3

To add to Jim's answer above using a category

 @implementation UIButton (NSCopying)

 - (id)copyWithZone:(NSZone *)zone {
     NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:self];
     UIButton *buttonCopy = [NSKeyedUnarchiver unarchiveObjectWithData: archivedData];
     return buttonCopy;
 }

 @end

if you wanted to copy all of the actions from one button to another, add something like this:

 for (id target in button.allTargets) {
    NSArray *actions = [button actionsForTarget:target forControlEvent:UIControlEventTouchUpInside];
    for (NSString *action in actions) {
        [newButton addTarget:target action:NSSelectorFromString(action) forControlEvents:UIControlEventTouchUpInside];
    }
 }
Joel Teply
  • 3,140
  • 1
  • 28
  • 21
0

If it implements the NSCopying protocol, then the -copy method should do the trick.

Stephen Darlington
  • 50,715
  • 11
  • 102
  • 148
0

You can get more information about the -copy method and how it works with sub-objects on the ADC reference site. As Stephen Darlington mentions, you need to implement the NSCopying protocol in your object.

documentation

Brad Gilbert
  • 33,211
  • 10
  • 77
  • 125
Weegee
  • 2,259
  • 1
  • 17
  • 16
0

Swift 3/4 version would be:

let archivedData = NSKeyedArchiver.archivedData(withRootObject: button as Any)
let buttonCopy = NSKeyedUnarchiver.unarchiveObject(with: archivedData) as? UIButton
Aron
  • 3,169
  • 2
  • 25
  • 40