2010-04-27 2 views
8

내가 그것을 작동하지 않았다 때awakeFromNib에서보기에 액세스 하시겠습니까?

[imageView setBackgroundColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:1.0]]; 

로 awakeFromNib에있는 UIImageView 배경 색상 (아래 참조)을 설정하기 위해 시도하고있다, 나는 깨달았다는 것을 아마보기가 아직로드되지 않았으며 나는 색상 변화를 이동해야하기 때문에 viewDidLoad.

나는이 권리가 있음을 확인할 수 있습니까?

게리

EDIT_002 :

난 그냥 깨끗한 처음부터이를 확인하기 위해 새로운 프로젝트를 시작했다. 나는 항상 내가하는 것처럼보기를 설정했다. 결과는 컨트롤이 실제로 awakeFromNib에서 (null)로 설정된다는 것입니다. 여기에 내가 무엇을 가지고 :

CODE :

@interface iPhone_TEST_AwakeFromNibViewController : UIViewController { 
    UILabel *myLabel; 
    UIImageView *myView; 
} 
@property(nonatomic, retain)IBOutlet UILabel *myLabel; 
@property(nonatomic, retain)IBOutlet UIImageView *myView; 
@end 

.

@synthesize myLabel; 
@synthesize myView; 

-(void)awakeFromNib { 
    NSLog(@"awakeFromNib ..."); 
    NSLog(@"myLabel: %@", [myLabel class]); 
    NSLog(@"myView : %@", [myView class]); 
    //[myLabel setText:@"AWAKE"]; 
    [super awakeFromNib]; 

} 

-(void)viewDidLoad { 
    NSLog(@"viewDidLoad ..."); 
    NSLog(@"myLabel: %@", [myLabel class]); 
    NSLog(@"myView : %@", [myView class]); 
    //[myLabel setText:@"VIEW"]; 
    [super viewDidLoad]; 
} 

출력 :

awakeFromNib ... 
myLabel: (null) 
myView : (null) 
viewDidLoad ... 
myLabel: UILabel 
myLabel: UIImageView 

내가이 일을해야하는지 알고 관심을 가질만한 보이는 워드 프로세서에서 그것을해야하지만, 나는 보통 내가 할 수없는 아주 일을 설정하는 방법을 제공 같은 이 경우 왜 그렇지 않은지 이해하십시오.

답변

27

한 가지 더 답변 :-) 컨트롤러가 느리게보기를로드하기 때문에이 동작이 나타나는 것 같습니다. 뷰가 즉시로드되지 않고 누군가가 view 접근 자라고 처음 호출하면로드됩니다. 따라서 awakeFromNib을 수신 할 때 NIB로드 프로세스가 완료되지만의 오브젝트에 대해서는 이 아닙니다.

#1: 0 
#2: 0 
#3: 1 

하지만이 경우 뷰 강제로드 :

@property(retain) IBOutlet UILabel *foo; 
@synthesize foo; 

- (void) awakeFromNib 
{ 
    NSLog(@"#1: %i", !!foo); 
    [super awakeFromNib]; 
    NSLog(@"#2: %i", !!foo); 
} 

- (void) viewDidLoad 
{ 
    NSLog(@"#3: %i", !!foo); 
} 

이 기록이에

- (void) awakeFromNib 
{ 
    [super awakeFromNib]; 
    [self view]; // forces view load 
    NSLog(@"#1: %i", !!foo); 
} 

로그 변경 :

#3: 1 
#1: 1 
+0

Zoul, 고맙습니다. 매우 흥미 롭습니다. viewDidLoad를 사용하여 처음부터 호출을로드하도록 강제하는 것이 더 좋을 것 같습니다.나는 awakeFromNib을 사용하는 것이 아이폰에 좋은 아이디어가 아닐지도 모른다는 것을 읽었지만, 그것에 대한 의견이 혼합되어있는 것으로 보인다. 다시 감사드립니다 ... – fuzzygoat

+0

보기에 대한 액세스 권한이 없으면 awakeFromNib에서 performSelector : withObject : delay 호출을 수행하십시오. 해킹이지만 효과적입니다. – phatmann

+0

처음에는이 질문과 답변을 발견하기가 어려웠습니다. 이전에 발견하면 문제가 많아졌습니다. 2013 년에도 문제가 계속 발생하며 그 행위가 문서와 모순된다고 생각합니다. http://stackoverflow.com/questions/17400547/awakefromnib-outlets-and-storyboards-is-the-documentation-wrong –

-1

개체가 nil이 아닌가요? NSAssert 또는 NSParameterAssert은 당신의 친구 :

-(void) awakeFromNib { 
    NSParameterAssert(imageView); 
    NSParameterAssert(testLabel); 
    NSLog(@"awakeFromNib ..."); 
    [imageView setBackgroundColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:1.0]]; 
    [testLabel setText:@"Pants ..."]; 
    [super awakeFromNib]; 
} 

객체가 정말 초기화하는 경우, 자신의 주소를 기록하고 awakeFromNibviewDidLoad에 표시되는 인스턴스와 동일한 지 확인하려고 :

- (void) awakeFromNib { 
    NSLog(@"test label #1: %@", testLabel); 
} 

- (void) viewDidLoad { 
    NSLog(@"test label #2: %@", testLabel); 
} 

숫자가 같은 경우 범주를 만들어 setBackgroundColor에 중단 점을 설정하고 스택 추적을 들여다 보면 무슨 일이 일어나는지 볼 수 있습니다.

@implementation UIImageView (Patch) 
- (void) setBackgroundColor: (UIColor*) whatever { 
    NSLog(@"Set a breakpoint here."); 
} 
@end 

당신은 사용자 정의 서브 클래스를 사용하여 같은 트릭을 수행 할 수 있습니다

@interface PeekingView : UIImageView {} 
@end 

@implementation PeekingView 
- (void) setBackgroundColor: (UIColor*) whatever { 
    NSLog(@"Set a breakpoint here."); 
    [super setBackgroundColor:whatever]; 
} 
@end 

지금 당신은 당신의 UIViewObject이 인터페이스 빌더에서 클래스 PeekingView의로 설정거야, 그리고 누군가가 배경을 설정하려고 할 때 당신은 알 수 있습니다. 누군가 awakeFromNib보기를 초기화 한 후 배경 변경 내용을 덮어 쓰는 경우 catch합니다.

그러나 나는이 문제가 훨씬 더 간단 할 것이라고 추정한다. imageView은 아마도 nil 일 것입니다.

+0

안녕 Zoul는, 많은 감사, 내가 아침에 제일 먼저 당신의 제안을 통해 이동하게됩니다 너 내가 어떻게 지내는지 알지. 아마 당신이 그걸 간단하게 생각하면 좋을 것 같아. – fuzzygoat

+0

안녕 Zoul, 컨트롤은 참으로 무효입니다 (위의 Edit_002 참조) – fuzzygoat

1

awakeFromNib 메서드에서 super 호출이 첫 번째 줄이어야한다고 생각합니다. 그렇지 않으면 요소가 아직 설정되지 않습니다.

-(void)awakeFromNib { 
    [super awakeFromNib]; 
    [imageView setBackgroundColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:1.0]]; 
    [testLabel setText:@"Pants ..."]; 
} 
+2

이것은 좋은 추측이며 '슈퍼'가 실제로 먼저 호출되어야하지만,이 경우에는 도움이되지 않습니다. – zoul

0

를이 코드를 참조하십시오 나도 알아,이 게시물은 조금 나이가 있지만 최근에 비슷한 문제가 있으며 해결책을 귀하와 공유하고 싶습니다.

NSTextView의 서브 클래 싱을 사용하여 행 색상을 교대로 표시하고 싶습니다.

@interface XNSStripedTableView : NSTableView { 

    NSColor *pColor; // primary color 
    NSColor *sColor; // secondary color 
} 

@property (nonatomic, assign) NSColor *pColor; 
@property (nonatomic, assign) NSColor *sColor; 

@end 

덮어 쓰기 highlightSelectionInClipRect : 외부에서 색상을 변경 할 수 있으려면, 내가 XNSStripedTableView, 두 개의 인스턴스가 내 서브 클래스에 바르 추가 트릭은 각각의 clipRect에 대한 올바른 색상을 설정할 수 없습니다.

- (void)highlightSelectionInClipRect:(NSRect)clipRect 

{

float rowHeight = [self rowHeight] + [self intercellSpacing].height; 
NSRect visibleRect = [self visibleRect]; 
NSRect highlightRect; 

highlightRect.origin = NSMakePoint(NSMinX(visibleRect), (int)(NSMinY(clipRect)/rowHeight)*rowHeight); 
highlightRect.size = NSMakeSize(NSWidth(visibleRect), rowHeight - [self intercellSpacing].height); 

while (NSMinY(highlightRect) < NSMaxY(clipRect)) { 

    NSRect clippedHighlightRect = NSIntersectionRect(highlightRect, clipRect); 
    int row = (int) ((NSMinY(highlightRect)+rowHeight/2.0)/rowHeight); 
    NSColor *rowColor = (0 == row % 2) ? sColor : pColor; 
    [rowColor set]; 
    NSRectFill(clippedHighlightRect); 
    highlightRect.origin.y += rowHeight; 
} 

[super highlightSelectionInClipRect: clipRect]; 
}

지금

유일한 문제는, 어디 pColor 및 sColor의 초기 값을 설정하는 방법? awakeFromNib : 시도했지만 디버거가 오류가 발생합니다. 그래서 NSLog의 문제를 파헤 쳤습니다 : 간단하지만 실행 가능한 솔루션을 찾았습니다 : viewWillDraw :에 초기 값을 설정하십시오. 처음 메서드를 호출하는 객체가 만들어지지 않았기 때문에 nil을 확인해야했습니다.

- (void)viewWillDraw { 

if (pColor == nil) 
    pColor = [[NSColor colorWithSRGBRed:0.33 green:0.33 blue:0 alpha:1] retain]; 

if (sColor == nil) 
    sColor = [[NSColor colorWithSRGBRed:0.66 green:0.66 blue:0 alpha:1] retain]; 

}

나는이 솔루션은 더 "사람이 읽을 수"로 조절 될 수있는 하나 pColor 및 sColor의 이름을 다시 선택할 수 있지만 아주 좋은 :-)입니다 생각 하는가. 경우

-1

당신이 대신 UIViewController 하위의 UIView 하위를 사용하고, 당신은 loadView 메소드를 오버라이드 (override) 할 수 있습니다

- (void)loadView 
{ 
    [super loadView]; 
    //IBOutlets are not nil here. 
} 
관련 문제