2012年2月19日 星期日

viewDidLoad的致命陷阱,一點也不幽默的黑色隙縫


大權在握的view controller控制著畫面的呈現,
然而什麼該定義於viewDidLoad,
什麼又該定義於viewWillAppear:呢?
大部分的情況,viewDidLoad就好像一片歌手,
只會被呼叫一次,
在controller將畫面載入後被呼叫。
(有一種例外的情況發生於記憶體不足時,
 此時controller的viewDidUnload將被呼叫,
 釋放UI元件佔據的記憶體,
 因此之後當controller的畫面要顯示時,
 它的viewDidLoad將再度被呼叫。)
而viewWillAppear:則像劉德華一樣永遠那麼紅,
每當controller掌控的畫面欲顯示於螢幕上時,
它就會被呼叫。

今天下午,
微笑女孩蘇森力幫彼得潘畫了一個很可愛的背景圖片,
有著星星,月亮以及可愛的女孩。





由於背景圖片不會變化,
於viewDidLoad將它加入看起來滿合理的,
想不到顯示的結果卻令人失望。

- (void)viewDidLoad
{
    [super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
    [self configureView];
    
    NSLog(@"viewDidLoad view %@", self.view);
    
    self.view.backgroundColor = [UIColor blackColor];
    
    UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.view.frame];
    
    imageView.image = [UIImage imageNamed:@"star.jpg"];
    
    imageView.contentMode = UIViewContentModeScaleAspectFill;
    
    [self.view addSubview:imageView];
}

執行結果:


背景圖片並沒有佔滿畫面,
圖片和上方的bar間有一塊如同黑色幽默般的空隙。

這是因為在viewDidLoad和viewWillAppear:被呼叫時,self.view.frame其實是不同的。

012-02-19 23:34:29.814 Test[5142:f803] viewDidLoad view <UIView: 0x6a703a0; frame = (0 20; 768 1004); autoresize = W+H; layer = <CALayer: 0x6a7c0d0>>
2012-02-19 23:34:30.126 Test[5142:f803] viewWillAppear view <UIView: 0x6a703a0; frame = (0 0; 768 960); autoresize = W+H; layer = <CALayer: 0x6a7c0d0>>


我們可以發現,當viewWillAppear:被呼叫時,view才被調整至正確的位置和大小。 (960 = 1024 -20 - 44, 20是status bar的高度,44是navigation bar的高度) 所以當初我們將imageView的frame設為和self.view一樣時,其實有2個問題。

1. y軸offset偏移20 pixel,成為黑色空隙的原凶。
2. 圖片的高度比較大,1004比960整整大了44 pixel

解決第一個問題很簡單,


UIImageView *imageView = [[UIImageView alloc]   initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];


只要傳入0,即可讓Y軸不再偏移20 pixel。

至於高度的問題,
則需啟動UI元件自動縮放的天性

imageView.autoresizingMask = UIViewAutoresizingFlexibleHeight;

UIViewAutoresizingFlexibleHeight將讓subview的高度隨著superview的高度變化。這就好似當父親縮水時,兒子為了不讓父親發現這殘酷事實,也跟著縮水。可謂最高明的孝順之道呀!


執行結果:





終於,微笑女孩蘇森力的畫作完美地成為App的背景,相信圖畫中的女孩也該會心的一笑吧。


















沒有留言:

張貼留言