給自己一個任務: 看能否寫出一個簡單的計算機程式. 在App store上面找幾個範例, 決定參考底下這個程式的layout:
所以我想,就先來implement上面的結果區吧!
用PhoneView把程式的bundle打開,看到一個background image file,長得像底下這樣子:
影像的長寬是 615 x 205,與上方顯示區的大小不一樣 !
所以我想,應該是想辦法放一個UILabel,然後設定他的background image是這張圖,iOS應該會自動調整影像的大小,可是我還要注意不要讓iOS把影像的邊緣給弄糊掉了,iOS內應該有類似Android Nine-Patch的觀念才對。
所以去網路上找了一些code,寫成了這個樣子:
// Stretch the image with 1x1 caps on each side
//
UIImage* imageBackground =
[[UIImage imageNamed:@"Rez/iPhone/bg-display.png"]
stretchableImageWithLeftCapWidth:1 topCapHeight:1];
_resultLabel.backgroundColor =
[UIColor colorWithPatternImage:imageBackground];
可是這個並不work!當圖片大小與Label不一致時,colorWithPatternImage並不會自動調整圖片大小,而是會做pattern fill,所以無法達成我要的效果。
到StackOverflow上面查了一下,有人suggest改用UITextField。由於UITextField可以指定backgroundImage,所以可以自動scale圖片。唯一要注意的只要把UITextField設定成是readonly就行了。
所以我做了第二次嘗試:
UIImage* imageBackground = ..
_resultText.borderStyle = UITextBorderStyleNone;
_resultText.background = imageBackground;
這樣子看到的效果是像這個樣子:
背景影像的scale以及邊緣的處理都是正確的,可是文字太靠右邊了,我需要一些padding!
再次查詢,這時候發現問題越來越大了,有的作法是subclass TextField,然後自定他文字的bounding box,有的作法是在TextField的右緣再放入一個空的view,我則是先試看看這樣子的作法:
- 在TextField的下方放一個UIView,設定UIView的背景為底圖,
- 把TextField改成是透明的,然後position TextField來產生padding的效果
這時候又發現,UIView也是沒有backgroundImage property,只有backgroundColor(跟UILabel一樣),所以圖片還是只能用pattern fill的方式擺放!看來還是必須想辦法自己寫code來scale background image。以下是相關的程式碼:
UIImage* imageBackground = ..
// resize image to fit _resultTextBackground
//
CGRect rect = _resultTextBackground.bounds;
UIImage* imageScaled =
[self imageWithImage:imageBackground scaledToSize:rect.size];
_resultTextBackground.backgroundColor =
[UIColor colorWithPatternImage:imageScaled];
_resultText.borderStyle = UITextBorderStyleNone;
[_resultText setBackgroundColor:[UIColor clearColor]];
const int cxPadding = 4;
const int cyPadding = 4;
_resultText.bounds = CGRectMake(cxPadding, cyPadding,
rect.size.width - cxPadding * 2, rect.size.height - cyPadding * 2);
另外
- (UIImage*)imageWithImage:(UIImage*)image
scaledToSize:(CGSize)newSize;
{
UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
這樣子的效果就對了
只是我開始想到其他的問題:
- imageWithImage這個是個common function,從xcode的角度該用什麼方式來建構library呢?or 這個API可以用category的方式加到UIImage class內 ?
- 如果我必須自己scale image的話,那也許直接用UILabel也可以做的出來?
- 這code看起來已經有點亂了,也許要試著把這組control寫成一個獨立的元件來用?
問題1跟3是很基礎的架構性的問題,希望下次可以找到好的方法!!