2010-12-13 12 views
71

Simplemente usando esta manera¿Se puede copiar UIView?

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

Esto hará que el simulador no se puede poner en marcha esta aplicación.

Intenta retener,

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

Cualquier modificación a VIEW2 se aplicará a VIEW1, entiendo que la cuota View2 misma memoria con Vista1.

¿Por qué no se puede copiar UIView? ¿Cual es la razon?

Respuesta

31

Su aplicación se bloquea, probablemente con algo como:

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

La razón es que UIView no implementa el protocolo de copia, y por lo tanto no hay copyWithZone selectora en UIView.

+9

¿Qué debo hacer para poner en práctica la copia de UIView? – Satyam

+1

Entonces, si tiene una cierta combinación de UIView y quiere usarla varias veces, ¿tendrá que subclasificar tal UIView? –

+0

Sí, subclases o categoría con métodos de fábrica de nivel de clase que devuelven instancias preconfiguradas de esa vista. –

-5

Usted puede hacer método de algo como esto:

-(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]; 

} 

entonces se puede establecer su Ivar al valor de retorno y retenerlo así:

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

esto no responde la pregunta. – bluefloyd8

+0

¿Qué sucede si su etiqueta tiene otros parámetros personalizados como numberOfLines o tag? ¿Establecerá todas las propiedades? – iamirzhan

150

esto podría funcionar para usted ... archivar la vista y luego desarchivarla inmediatamente después. Esto debería proporcionarle una copia en profundidad de una vista:

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

Parece un truco, pero funciona como un sueño.La respuesta de ssj a continuación es básicamente un "constructor de copia" que está bien para clases pequeñas. Tal vez puedas usar el tiempo de ejecución de obj-c para copiar todas las propiedades a la vez ... Esto es aún más fácil;) – Patrick

+0

Esto suena bien para ser verdad. En mi caso arroja una excepción NSInvalidArgumentException ('NSConcreteAttributedString initWithString :: nil value') para un UILabel en el árbol de la subvista. –

+1

Esto funciona, pero parece ser muy lento incluso para árboles de vistas triviales. –

19

Puede hacer una extensión UIView. En el siguiente fragmento de código rápido, la función copyView devuelve un AnyObject para que pueda copiar cualquier subclase de un UIView, , es decir, UIImageView. Si desea copiar solo UIViews puede cambiar el tipo de devolución a UIView.

//MARK: - UIView Extensions 

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

Ejemplo de uso:

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

¡Gracias, funciona genial! TAMBIÉN tenga en cuenta que la vista copiada no tiene supervista (principal), sin restricciones y sin reconocedores de gestos (si el padre tenía alguno). – Sajjon

+0

Copiar pero con errores, algunas subvistas no se procesan – jose920405

0

UIView no implementa el protocolo NSCoping, ver la declaración de UIView.h:

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

Por lo tanto, si queremos para tener un método similar al copy, necesitamos implementar el NSCoping protocolo en una categoría más o menos.

4

para swift3.0.1:

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