2010-01-25 1 views
9

Мне нужно дублировать представление, со всеми его представлениями.UIView duplicate

Кто-нибудь знает, как это сделать?

ответ

23

Самый простой (но, вероятно, не самый быстрый) способ заключается в том, чтобы архивировать его в объект NSData и сразу разблокировать его.

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

К сожалению, это не будет работать, если ваш взгляд имеет какие-либо подвиды/объекты которые не могут быть заархивированы (например, UIImage). – rcw3

+0

Значит, вы говорите, что это не будет работать для UIImageViews? – fatuhoku

+1

@fatuhoku, Да, это не работает для 'UIImageView' –

3

Чтобы заархивировать любой объект UIImage просто конвертировать их в imagerep одного вида или другого (PNG, например) и архив, который объект NSData, то в разархивировать восстановлении UIImage с imageWithData:

0

Здесь это новый метод, который вы можете использовать: Используйте метод UIView:

- (UIView *)snapshotViewAfterScreenUpdates:(BOOL)afterUpdates 

Это самый быстрый способ сделать вид. Доступно в iOS 7.

0

Можно легко скопировать UIView путем архивирования и разборки процесса.

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

Но это игнорирует UIImageView, так что для UIImageView сделать это таким образом,

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

Swift версия

Этот ответ показывает, как сделать то же самое в Swift, как принято в Objective-C.

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

Мой полный ответ с большим количеством нот here.

0

enter image description here

Вы можете перетащить пользовательский вид вне корневого зрения ViewController. В реализации пользовательского класса просмотра переопределить методы enconde/decode. Реализовать соединения IBOutlets и IBActions не будут архивироваться в памяти.

@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 

Пример многократного использования настраиваемого представления в 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