如何在Objective-C中复制一个UIButton?

22

该对象继承自NSObject类。

是否有一种方法可以创建该对象的副本作为一个新的对象?


2
你为什么要复制一个UIButton?也许有更好的方法... - Kendall Helmstetter Gelner
3
复制 UIButton 有什么缺点吗?我需要基于现有的一个按钮动态创建新的按钮。 - James Skidmore
你可以复制一个按钮,比如说,制作一排按钮。@JamesSkidmore 这是完整的代码 http://stackoverflow.com/a/26438692/294884 - Fattie
6个回答

65

UIButton不符合NSCopying要求,所以无法通过-copy方法进行复制。

但是,它符合NSCoding要求,因此您可以对当前实例进行归档,然后解档一个“副本”。

NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject: button];
UIButton *buttonCopy = [NSKeyedUnarchiver unarchiveObjectWithData: archivedData];
之后,您需要根据需要分配任何未在存档中保留的其他属性(例如委托)。

6
聪明!我本来可能会只通过一个分类添加“-copy”,但这个方法更好。=) - Dave DeLong
3
这速度有点慢,不是吗? - mattsven

4

UIButton 没有遵循 NSCopying 协议,因此您需要手动复制它。另一方面,这并不是一件坏事,因为复制按钮的含义并不是很清楚。例如,复制按钮应该添加到与原始按钮相同的视图中吗?在点击时是否应该触发相同的方法?


3
为了补充Jim的回答,使用一个类别:
 @implementation UIButton (NSCopying)

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

 @end

如果你想将一个按钮的所有操作复制到另一个按钮,请添加以下内容:
 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];
    }
 }

0

Swift 3/4 版本将会是:

let archivedData = NSKeyedArchiver.archivedData(withRootObject: button as Any)
let buttonCopy = NSKeyedUnarchiver.unarchiveObject(with: archivedData) as? UIButton

0
如果它实现了NSCopying协议,那么-copy方法就可以解决问题了。

我正在尝试复制一个UIButton。有什么想法吗? - James Skidmore

0
您可以在ADC参考网站上获取有关-copy方法及其如何与子对象一起使用的更多信息。正如Stephen Darlington所提到的,您需要在对象中实现NSCopying协议。

documentation


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接