【问题标题】:Can UIView be copied?UIView 可以复制吗?
【发布时间】:2011-05-24 11:31:37
【问题描述】:

简单地使用这种方式:

UIView* view2 = [view1 copy]; // view1 existed

这将导致模拟器无法启动此应用。

尝试保留,

UIView* view2 = [view1 retain]; // view1 existed
// modify view2 frame etc

view2 的任何修改都将适用于view1,我知道view2view1 共享相同的内存。

为什么不能复制UIView?是什么原因?

【问题讨论】:

    标签: ios objective-c uiview copy


    【解决方案1】:

    这可能对您有用...存档视图,然后立即取消存档。这应该会给你一个视图的深层副本:

    id copyOfView = 
    [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:originalView]];
    

    【讨论】:

    • 这看起来有点像 hack,但工作起来就像做梦一样。 ssj 在下面的回答基本上是一个“复制构造函数”,适用于小类。您也许可以使用 obj-c 运行时一次复制所有属性。这仍然更容易;)
    • 这行得通,但对于琐碎的视图树来说似乎很慢。
    • 它有效,但要小心!它不会为@IBOutlets 设置值,“复制”后它们都为零
    • 这似乎忽略了UIImageViews :(
    • 谢谢,效果很好!还请注意,复制的视图没有父视图(父视图)、约束和手势识别器(如果父视图有的话)。
    【解决方案2】:

    您的应用可能会因以下原因崩溃:

     [UIView copyWithZone:]: unrecognized selector sent to instance 0x1c6280
    

    原因是UIView没有实现复制协议,所以UIView中没有copyWithZone选择器。

    【讨论】:

    • 如何实现UIView的拷贝?
    • 所以如果你有 UIView 的某种组合并且想多次使用它,你需要子类化这样的 UIView?
    • 是的,使用返回该视图的预配置实例的类级工厂方法进行子类化或类别。
    【解决方案3】:

    您可以制作 UIView 扩展。在下面的示例 swift sn-p 中,函数 copyView 返回一个 AnyObject,因此您可以复制 UIView 的任何子类,ie UIImageView。 如果你想复制 only UIViews,你可以将返回类型更改为 UIView。

    //MARK: - UIView Extensions
    
        extension UIView
        {
           func copyView<T: UIView>() -> T {
                return NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: self)) as! T
           }
        }
    

    示例用法:

    let sourceView = UIView()
    let copiedView = sourceView.copyView()
    

    【讨论】:

    • 谢谢,效果很好!还请注意,复制的视图没有父视图(父视图)、约束和手势识别器(如果父视图有的话)。
    【解决方案4】:

    对于 swift3.0.1:

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

    【讨论】:

      【解决方案5】:

      UIView 没有实现NSCoping 协议,参见UIView.h中的声明:

      @interface UIView : UIResponder &lt;NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem, UITraitEnvironment, UICoordinateSpace, UIFocusEnvironment&gt;

      所以,如果我们想要有一个copy 类似的方法,我们需要在一个类别中实现NSCoping 协议。

      【讨论】:

        【解决方案6】:

        你可以制作这样的方法:

        -(UILabel*)copyLabelFrom:(UILabel*)label{
        //add whatever needs to be copied
        UILabel *newLabel = [[UILabel alloc]initWithFrame:label.frame];
        newLabel.backgroundColor = label.backgroundColor;
        newLabel.textColor = label.textColor;
        newLabel.textAlignment = label.textAlignment;
        newLabel.text = label.text;
        newLabel.font = label.font;
        
        return [newLabel autorelease];
        
        }
        

        然后您可以将您的 ivar 设置为返回值并像这样保留它:

        myLabel = [[self copyLabelFrom:myOtherLabel] retain];
        

        【讨论】:

        • 这不是在回答问题。
        • 如果您的标签有其他自定义参数,如 numberOfLines 或 tag 怎么办?你会设置所有属性吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-18
        • 1970-01-01
        • 2014-12-13
        • 2012-08-25
        • 2011-12-31
        • 2012-09-03
        相关资源
        最近更新 更多