UIViewをコピーできますか?


81

この方法を使用するだけです。

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

これにより、シミュレーターはこのアプリを起動できなくなります。

保持してみてください、

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

に変更view2が適用される場合はview1、とview2同じメモリを共有することを理解していますview1

なぜUIViewコピーできないのですか?理由は何ですか?

回答:


33

アプリはおそらく次のようなものでクラッシュします:

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

その理由は、UIViewがコピープロトコルを実装していないため、copyWithZoneUIViewにセレクターがないためです。


10
UIViewのコピーを実装するにはどうすればよいですか?
サティヤム2012年

1
したがって、UIViewの特定の組み合わせがあり、それを数回使用したい場合は、そのようなUIViewをサブクラス化する必要がありますか?
匿名ホワイト

はい、そのビューの事前構成されたインスタンスを返すクラスレベルのファクトリメソッドを使用したサブクラス化またはカテゴリ。
Engin Kurutepe 2012年

162

これはあなたのために働くかもしれません...ビューをアーカイブし、その後すぐにアーカイブを解除します。これにより、ビューの詳細なコピーが得られます。

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

1
それはちょっとしたハックのように見えますが、夢のように機能します。以下のssjの答えは、基本的に「コピーコンストラクタ」であり、小さなクラスには問題ありません。obj-cランタイムを使用して、すべてのプロパティを一度にコピーできます。これはさらに簡単です;)
Patrick Borkowicz 2012

1
これは機能しますが、些細なビューツリーでも非常に遅いようです。
イアンニューソン2014

6
それは動作しますが、注意してください!@IBOutletsの値は設定されません。「コピー」後は、すべてnilになります
nalexn 2014年

1
これはUIImageViewsを無視しているようです:(
Iulian Onofrei 2015

1
ありがとう、うまくいきます!また、コピーされたビューには、スーパービュー(親)、制約、およびジェスチャ認識機能(親に存在する場合)がないことに注意してください。
Sajjon 2016年

25

UIView拡張機能を作成できます。たとえば、迅速で、あなたがUIViewの、のいずれかのサブクラスにコピーできるよう機能copyViewはANYOBJECTを返し、以下のスニペットすなわちUIImageViewを。UIViewのみをコピーする場合は、戻り値の型を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()

1
ありがとう、うまくいきます!また、コピーされたビューには、スーパービュー(親)、制約、およびジェスチャ認識機能(親に存在する場合)がないことに注意してください。
Sajjon 2016年

6

swift3.0.1の場合:

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

1

UIViewNSCopingプロトコルを実装していません。UIView.hの宣言を参照してください。

@interface UIView : UIResponder <NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem, UITraitEnvironment, UICoordinateSpace, UIFocusEnvironment>

したがって、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];

14
これは質問に答えていません。
bluefloyd8 2013年

1
ラベルにnumberOfLinesやtagなどの他のカスタムパラメータがある場合はどうなりますか?すべてのプロパティを設定しますか?
iamirzhan 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.