Créer une copie d'une UIView en Swift
Car les objets sont des types référence, pas de types de valeur, si vous définissez un UIView
égale à une autre UIView
, les points de vue sont le même objet. Si vous modifiez l'un de vous aurez la modification de l'autre.
J'ai une situation intéressante où je voudrais ajouter un UIView
comme une sous-vue dans un autre point de vue, alors j'ai du faire quelques modifications, et ces modifications ne devraient pas affecter l'original UIView
. Comment puis-je faire une copie de la UIView
donc, je peux assurer que j'ai ajouter cette copie comme une sous-vue au lieu d'une référence à l'original UIView
?
Remarque que je ne peux pas recréer la vue de la même manière que l'original a été créé, j'ai besoin d'un moyen de créer une copie de donnée tout UIView
objet.
Vous devez vous connecter pour publier un commentaire.
Vous ne pouvez pas arbitrairement copier un objet. Seuls les objets qui implémentent l'
NSCopying
protocole peut être copié.Cependant, il existe une solution de contournement: Depuis
UIView
s peut être sérialisé sur le disque (par exemple pour charger à partir d'un XIB), vous pouvez utiliserNSKeyedArchiver
etNSKeyedUnarchiver
pour créer un sérialiséNSData
décrivant votre point de vue, puis de sérialiser que nouveau afin d'obtenir un indépendant, mais identique de l'objet.Vous pouvez faire une UIView extension. Dans l'exemple ci-dessous, la fonction copyView retourne un AnyObject de sorte que vous pouvez copier toute sous-classe d'une UIView, ie UIImageView. Si vous souhaitez copier seulement UIView vous pouvez changer le type de retour de UIView.
Exemple d'utilisation:
-initWithCoder:
et-encodeWithCoder:
pour sérialiser l'ensemble de ses propriétés.archivedData(withRootObject:)
etunarchivedObject(with:)
sont deprecated comme d'iOS 12.0.Mise à jour pour iOS 12.0
Méthodes
archivedData(withRootObject:)
etunarchivedObject(with:)
sont obsolète depuis iOS 12.0.Ici est une mise à jour de @Ivan Porcolab de la réponse à l'aide de l'API plus récente (depuis 11.0), a également fait plus de général à l'appui d'autres types.
Je pense que vous devriez avoir un lien vous UIView avec un .plume et il suffit de créer un nouveau.
Propriété ne sera pas la même, mais vous gardez l'apparence et les méthodes.
Cette réponse montre comment faire ce que @uliwitness suggéré. C'est, obtenir un objet identique par l'archivage et puis désarchivage il. (Il est aussi, fondamentalement, ce que Ivan Porkolab n'a, dans sa réponse, mais dans un format plus lisible, je pense.)
Notes
AnyObject
. Nous avons utiliséas! UIView
de type de le jeter en arrière pour unUIView
car nous savons que c'est ce qu'il est. Si notre point de vue, unUITextView
, puis nous avons pu type de voter pour elleas! UITextView
.myViewCopy
n'a plus de parent vue.UIImage
. Cependant, voir cette et cette réponse.Mis à jour à Swift 3.0
UIView()
. Il ne semble familier?view.top = view.bottom
comme une contrainte et c'est pourquoi je ne la vois pas dans la vue de la hiérarchie.Vous devez utiliser le pattern Prototype
Exemple du prototype:
Un exemple de l'utilisation de prototype:
Un plus solution pourrait être de créer un nouveau
UIView
puis copiez-dessus de toute critique propriétés. Cela peut ne pas fonctionner dans le cas des OP cas, mais il pourrait très bien fonctionner pour d'autres cas.Par exemple, avec un
UITextView
, probablement tout ce que vous avez besoin est le cadre et le texte attribué:En outre, vous pouvez utiliser ce modèle à copier-Vue-contrôleur de vue
Vous pourriez avoir besoin de ce pour la mise en cache-vue-contrôleur ou le clonage.