2010-01-25 7 views
9

Je dois dupliquer une vue, avec toutes ses sous-vues.UIView dupliquer

Est-ce que quelqu'un sait comment le faire?

Répondre

23

Le moyen le plus simple (mais probablement le plus rapide) est de l'archiver dans un objet NSData et de le désarchiver immédiatement.

NSData *tempArchive = [NSKeyedArchiver archivedDataWithRootObject:myView]; 
UIView *myViewDuplicate = [NSKeyedUnarchiver unarchiveObjectWithData:tempArchive]; 
+11

Malheureusement, cela ne fonctionnera pas si votre vue a des sous-vues/objets qui ne peut pas être archivé (comme un UIImage). – rcw3

+0

Donc vous dites que cela ne fonctionnera pas pour UIImageViews? – fatuhoku

+1

@fatuhoku, Oui, cela ne fonctionne pas pour 'UIImageView's –

3

Pour archiver tout objet UIImage de les convertir à une imagerep d'une sorte ou d'une autre (PNG par exemple) et archive objet NSData, puis dans unarchiver vous remplacerai les UIImage avec imageWithData:

0

ici est une nouvelle méthode que vous pouvez utiliser: Utiliser la méthode de UIView:

- (UIView *)snapshotViewAfterScreenUpdates:(BOOL)afterUpdates 

Ceci est le moyen le plus rapide pour dessiner une vue. Disponible dans iOS 7.

0

On peut facilement copier un UIView en procédant à l'archivage et au désarchivage.

NSData *tempArchive = [NSKeyedArchiver archivedDataWithRootObject:myView]; 
UIView *myViewDuplicate = [NSKeyedUnarchiver unarchiveObjectWithData:tempArchive]; 

Mais cela ne tient pas UIImageView, donc pour UIImageView le faire de cette façon,

UIImage *img = [UIImage imageNamed: @"myImage"]; 
UIImage *img2 = [UIImage imageWithCGImage:img.CGImage scale:img.scale orientation:img.imageOrientation]; 
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:img2]; 
UIImage *imgCopy = [NSKeyedUnarchiver unarchiveObjectWithData:data]; 
NSLog(@"%@, %@", imgCopy, NSStringFromCGSize(imgCopy.size)); // -> <UIImage: 0x7fa013e766f0>, {50, 53} 

Refrence from here.

0

Version Swift

Cette réponse montre comment faire la même chose dans Swift comme la réponse acceptée le fait en Objective-C.

let tempArchive = NSKeyedArchiver.archivedDataWithRootObject(myView) 
let myViewDuplicate = NSKeyedUnarchiver.unarchiveObjectWithData(tempArchive) as! UIView 

Ma réponse complète avec plus de notes est here.

0

enter image description here

Vous pouvez faire glisser votre vue personnalisée en dehors de la vue racine du viewController. Dans l'implémentation de la classe de vue personnalisée, remplacez les méthodes enconde/decode. Réalisez que les connexions IBOutlets et IBActions ne seront pas archivées en mémoire.

@implementation MyCustomView 

-(MyCustomView*)aCopy{ 
    NSData *temp = [NSKeyedArchiver archivedDataWithRootObject:self]; 
    return [NSKeyedUnarchiver unarchiveObjectWithData:temp]; 
} 


- (void)encodeWithCoder:(NSCoder *)coder { 
    [super encodeWithCoder:coder]; 

    [coder encodeObject:self.btnBack forKey:@"btnBack"]; 
    [coder encodeObject:self.lbl1 forKey:@"lbl1"]; 
} 

-(instancetype)initWithCoder:(NSCoder *)aDecoder{ 

    self = [super initWithCoder:aDecoder]; 
    if (self) { 
     self.btnBack = [aDecoder decodeObjectForKey:@"btnBack"]; 
     self.lbl1 = [aDecoder decodeObjectForKey:@"lbl1"]; 
     [_btnBack addTarget:self action:@selector(onBtnBack) forControlEvents:UIControlEventTouchUpInside]; 
    } 
    return self; 
} 

- (IBAction)onBtnBack{ 
    //. . . 

MyCustomView.h:

#import <UIKit/UIKit.h> 

@interface MyCustomView : UIView 

@property (weak, nonatomic) IBOutlet UILabel *lbl1; 
@property (weak, nonatomic) IBOutlet UIButton *btnBack; 

-(MyCustomView*)aCopy; 

@end 

Exemple de réutilisation de la vue personnalisée dans ViewController.m:

#import "ViewController.h" 
#import "MyCustomView.h" 

@interface ViewController() 
@property (strong, nonatomic) IBOutlet MyCustomView *myCustomView; 
@property (weak, nonatomic) IBOutlet UIView *vwPlaceHolder; 
@end 

@implementation ViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    [self.view addSubview:_myCustomView]; 
} 

-(void)viewDidAppear:(BOOL)animated{ 
    [super viewDidAppear:animated]; 
    MyCustomView *vwCopy = [_myCustomView aCopy]; 
    vwCopy.lbl1.text = @"My other msg"; 
    vwCopy.frame = _vwPlaceHolder.frame; 
    [_vwPlaceHolder removeFromSuperview]; 
    [self.view addSubview:vwCopy]; 

} 
@end