22

The object inherits from NSObject.

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

Fattie
  • 27,874
  • 70
  • 431
  • 719
James Skidmore
  • 49,340
  • 32
  • 108
  • 136

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,064
  • 1
  • 33
  • 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,879
  • 1
  • 21
  • 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,260
  • 1
  • 31
  • 21
0

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

Stephen Darlington
  • 51,577
  • 12
  • 107
  • 152
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,846
  • 11
  • 78
  • 129
Weegee
  • 2,225
  • 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,419
  • 3
  • 30
  • 42