复制、克隆或复制 UIView

Posted

技术标签:

【中文标题】复制、克隆或复制 UIView【英文标题】:Duplicate, clone or copy UIView 【发布时间】:2011-02-15 13:12:08 【问题描述】:

我有一个通过 Interface Builder 链接到 UIViewController 的 UIView。 是否可以复制、克隆或复制此视图以便我可以多次使用它?

【问题讨论】:

Swift answer 【参考方案1】:

以下类别可能不是特别有效,但在一个项目中对我有用:

@implementation UIView (OPCloning)

- (id) clone 
    NSData *archivedViewData = [NSKeyedArchiver archivedDataWithRootObject: self];
    id clone = [NSKeyedUnarchiver unarchiveObjectWithData:archivedViewData];
    return clone;


@end

我不会实现 -copy 或 -copyWithZone:,因为 Apple 将来可能会这样做。 请注意,并非所有视图都以相同的程度实现归档。您肯定需要为要克隆的 NSView 子类的自定义属性实现 NSCoding 方法(否则在克隆视图中将变为 nil)。仍然比编写自定义克隆代码更容易。

【讨论】:

它应该比重复加载笔尖更有效,因为它不访问外部存储。 在我的例子中,归档和取消归档比从包中加载 nib(外部存储)多花费大约 20-25% 的时间。无论如何,我仍在寻找提高 loadNibNamed 性能的方法。 克隆视图中的图像在 ios 9 中加载太慢。 Nib 加载基本上使用引擎盖下的键控归档,因此性能应该相同。它不在这里的原因是 Nib 在构建过程中已经被存档,现在被多次取消存档。此代码每次都进行归档和取消归档。如果您缓存 archivedViewData 并重用它,您应该会看到类似的性能。但是,如果您需要克隆在程序运行期间发生变化的实际特征,那么 Nib 应该会更慢。【参考方案2】:

这是一个你可以使用的新方法:使用 UIView 的方法:

- (UIView *)snapshotViewAfterScreenUpdates:(BOOL)afterUpdates

这是绘制视图的最快方法。在 iOS 7 中可用。

【讨论】:

注意:虽然这对于非常具体的用例来说是一个很好的解决方案,但此方法实际上并不会创建与原始视图相同类型的新视图。它只创建一个看起来像此时视图的视图(即,它“截取”视图的屏幕截图),您可以将其用作替代品,例如在过渡效果期间或重新加载/重新创建视图时。【参考方案3】:

你可以试试下面的 Swift 3.0.1:

extension UIView
func copyView() -> AnyObject
    return NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: self))! as AnyObject
 

【讨论】:

【参考方案4】:

当然。该文档有一个good example of how to achieve that;它适用于UITableViewCell,但也是在这里使用的好方法。

根据视图的复杂性,您可能希望将其设为自定义视图类,并为其拥有的任何子视图赋予其自己的IBOutlet 属性;在这种情况下,您需要将 Interface Builder 中视图的“类标识”设置为该类。然后,您的视图控制器可以通过例如myLoadedView.someLabel 访问任何给定的加载了 XIB 的视图上的这些视图,而不必按照上述文档的建议使用例如 [myLoadedView viewWithTag:3]

【讨论】:

UITableViewCell 只加载了几次,从不克隆。 我的猜测是@geon 暗示,虽然通过多次取消归档笔尖来创建新对象似乎可以解决 OP 的需求,但它并不能作为暗示的问题的一般解决方案按问题的标题。这不适用于在代码中创建的 UIView 的一般情况,例如使用[UIView alloc] initWithFrame:aFrame];。答案是正确的,但问题标题具有误导性。

以上是关于复制、克隆或复制 UIView的主要内容,如果未能解决你的问题,请参考以下文章

如何在 kotlin 中克隆或复制列表

复制或克隆带有约束的 SQL 表

linux虚拟机系统的复制或克隆后续问题解决!

linux虚拟机系统的复制或克隆后续问题解决!

复制或克隆MySQL中的一行或多行

反射实现java深度克隆