2012-03-07 1 views
1

UIView의 서브 클래스를 생성하고 그것을 nib 파일로로드한다고 가정 해 보겠습니다.nib 파일로 생성 된 UIView를 서브 클래 싱하고 오버라이드

MySubView.m 

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"MySubView" owner:self options:nil]; 

     [self release]; 
     self = [[nib objectAtIndex:0] retain]; 
     self.tag = 1; 
     [self fire]; 
    } 
    return self; 
} 

- (void)fire { 
    NSLog(@"Fired MySubView"); 
} 

가 지금은 어떤 변화를 만들려면,하지만 난 nib 파일을 복사하지 않는, 그래서 배경 색상 변경과 같은 MySubView 하위 클래스하려고 :
나는 이렇게

RedMySubView.m 


- (id)initWithFrame:(CGRect)frame 
    { 
     self = [super initWithFrame:frame]; 
    if (self) { 
     self.backgroundColor = [UIColor redColor]; 
     [self fire]; 
    } 
    return self; 
} 

- (void)fire { 
    NSLog(@"Fired RedMySubView"); 
} 

보기가 작성되고 배경색은 변경되지만 화재 조치는 서브 클래스에 의해 대체되지 않습니다. fire 메서드를 호출하면 결과는 콘솔에 Fired MySubView이됩니다.
어떻게 해결할 수 있습니까?
펜촉 레이아웃을 유지하고 싶지만 새로운 클래스를 제공하십시오.

+0

이것을 확인하십시오. question iNeal

답변

0

MySubview 초기화 프로그램 인 initWithFrame의 [자체 릴리스]를 사용하면 이니셜 라이저를 사용하여 생성하려는 클래스를 버리고 있다고 말할 수 있습니다. 클래스는 loadNibName 메소드에 의해로드되고 따라서 nib에 정의 된 것과 동일한 클래스를가집니다. 그래서 하위 클래스에서 이니셜 라이저를 호출하는 것은 쓸모가 없습니다. 이제 정말 펜촉 해당 파일을 찾아 볼 경우 RedMySubview

- (id) initWithNibFile:(NSString *) nibName withFrame:(CGRect) frame { 
self = [super initWithNibFile:mynib withFrame:MyCGRect]; 
if (self) 
.... 

이 생성자를

- (id) initWithNibFile:(NSString *) nibName withFrame:(CGRect) frame 

등을 호출

봅니다 MySubview에서 자신의 펜촉 생성자 (예 : initWithNibFile)를 구현하는 RedMySubview 클래스가 있으면 불이 으로 대체되어야합니다. MySubview와 RedMySubview를 모두 사용하는 경우 xib를 복제해야합니다. 또는 당신은 당신이 만들려는 initWithNibFile 이니셜 라이저와 UIViews 그것의 서브 클래스 구현하는 추상 클래스 (그루터기)를 만들 : 당신은 당신이 기본적으로되기 위해 당신의 "자기"개체를 무시 self = [[nib objectAtIndex:0] retain] 전화

MyAbstractNibUIView initWithNibFile:withFrame: 
MyRedSubview : MyAbstractNibUIView  red.xib 
MyGreenSubview :MyAbstractNibUIView  green.xib 
MyBlueSubview : MyAbstractNibUIView  blue.xib 
0

MySubView는 nib 파일의 기본 객체이므로 MySubView입니다. 호출 클래스가 RedMySubView이면 MySubView로 재정의되므로 이는 바람직하지 않습니다.

대신이에 MySubView에 - (id)initWithFrame:(CGRect)frame을 변경하려면 : 화재가 두 번 발광하는 것을 제외하고는 MySubView에 모두를 호출하기 때문에

지금
- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"MySubview" owner:self options:nil]; 

     // The base of the nib file. Don't set self to this, instead copy all of its 
     // subviews, and "self" will always be the class you intend it to be. 
     UIView *baseView = [nib objectAtIndex:0]; 

     // Add all the subviews of the base file to your "MySubview". This 
     // will make it so that any subclass of MySubview will keep its properties. 
     for (UIView *v in [baseView subviews]) 
      [self addSubview:v]; 

     self.tag = 1; 
     [self fire]; 
    } 
    return self; 
} 

, 모든, "MyRedSubView"의 이니셜에서 작동합니다 및 RedMySubView.

관련 문제