2011-02-15 13 views
21

Tengo una UIView que está vinculada a un UIViewController a través del Interface Builder. ¿Es posible duplicar, clonar o copiar esta vista para poder usarla más de una vez?Duplicar, clonar o copiar UIView

+0

[respuesta Swift] (http://stackoverflow.com/a/37050633/3681880) – Suragch

Respuesta

1

Sure. La documentación tiene un good example of how to achieve that; es para UITableViewCell, pero es un buen enfoque para usar aquí también.

Dependiendo de la complejidad de su vista, es posible que desee convertirla en una clase de vista personalizada y otorgarle sus propias propiedades IBOutlet para las subvistas que tenga; en ese caso, establecería la "Identidad de clase" de la vista en el Creador de interfaz para esa clase. Entonces su controlador de vista podría acceder a esas vistas en cualquier vista cargada XIB dada, por ejemplo, myLoadedView.someLabel, en lugar de tener que usar, por ejemplo, [myLoadedView viewWithTag:3] como lo sugiere la documentación anteriormente mencionada.

+2

El UITableViewCell sólo es cargado varias veces, nunca clonado. – geon

+1

La diferencia es? –

+8

Supongo que @geon está sugiriendo que, aunque crear un objeto nuevo al desarchivar un plumín varias veces parece resolver las necesidades del OP, no sirve como una solución general al problema, como lo implica el título de la pregunta. Esto no funcionará en el caso general de una UIView creada en código, por ejemplo, con '[UIView alloc] initWithFrame: aFrame];'. La respuesta es correcta, pero el título de la pregunta es engañoso. – clozach

30

La siguiente categoría podría no ser particularmente eficiente, pero trabajó para mí en un proyecto:

@implementation UIView (OPCloning) 

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

@end 

yo no había implemento de la copia o -copyWithZone: como Apple podría hacerlo en el futuro. Tenga en cuenta que no todas las vistas implementan el archivo en la misma medida. Definitivamente tendrá que implementar los métodos de NSCoding para clonar las propiedades personalizadas de sus subclases NSView (de lo contrario, se convertirá en nil en la vista clonada). Aún más fácil que escribir código de clonación personalizado.

+1

Debería ser más eficiente que cargar varias veces un plumín para eso, ya que no tiene acceso al almacenamiento externo. – osxdirk

+0

En mi caso, archivar y desarchivar en conjunto llevó entre un 20% y un 25% más de tiempo que la carga del paquete (almacenamiento externo). De todos modos, todavía estoy buscando la manera de mejorar el rendimiento de loadNibNamed. –

+0

Las imágenes de la vista clonada se están cargando demasiado lento en iOS 9. – Suresh

13

Aquí es un nuevo método que puede utilizar: Método de Uso UIView:

- (UIView *)snapshotViewAfterScreenUpdates:(BOOL)afterUpdates 

Esta es la manera más rápida para dibujar una vista. Disponible en iOS 7.

+1

Nota: Si bien esta es una buena solución para un caso de uso muy específico, este método en realidad no crea una nueva vista del mismo tipo que el original. Solo crea una vista que parece que la vista mira en este momento (es decir, "toma una captura de pantalla" de la vista), que puede usar como suplente, p. durante los efectos de transición o al volver a cargar/recrear vistas. – uliwitness

2

Usted puede tratar con Swift 3.0.1 a continuación:

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