2012年10月29日 星期一

清除不識抬舉的多餘表格分隔線 - 彼得潘的OAOA

iOS SDK有著優異的表格cell管理機制,只載入畫面上顯示行數的資料,而不是一次載入全部的資料。因此即便我們擁有大量的資料,也不用太過擔心表格無法負荷。然而當我們準備的材料不足,塞不滿整個畫面時,將出現一個尷尬的情況。如下圖所示,彼得潘改編五月天激勵人心的動人作品"OAOA",將改編版歌詞顯示於表格的cell裡。改編版的歌詞有8行,但iPhone 5是如此地修長,它可以顯示12行都沒問題。於是我們看到當超過第8行時,分隔線還是持續出現,超不識抬舉的呀,這些分隔線難道不知道已經沒內容了,它們不該再出現了嗎?




對付這些不長眼的分隔線,只好施展殺無赦。將它們清除。只要設定表格的tableFooterView,即可消除這些多出來的分隔線。

    self.myTableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];


執行App:




最後,讓我們好好聽聽正宗五月天的OAOA吧




2012年10月28日 星期日

利用Storyboard ID設定View Controller的識別ID

在App程式設計入門的13-17頁,介紹了如何利用instantiateViewControllerWithIdentifier:建立controller。


MasterDetailTestDetailViewController *viewController =
        [self.storyboard instantiateViewControllerWithIdentifier:@"Poem"];


其中的關鍵在於在storyboard裡替View Controller取個好名字,也就是它的Identifier,如此到時候才能在程式裡指定建立的View Controller為何。

原本設定Id的方式如下。先切換到Detail View Controller的Attributes Inspector分頁,然後將Identifier欄位設為Poem。



不過在最新的Xcode 4.5裡,如同梁朝偉的一天一點愛戀,滄海已成桑田,設定的地方已經改變。現在我們要切換至Identity Inspector頁面(第三個Icon),設定Storyboard ID ( 如下圖所示)




執行App:

只要設定了Storyboard ID,原來的程式碼將順利地執行,我們又可以再一次提升文藝氣息,欣賞大詩人李商隱的錦瑟了。




2012年10月24日 星期三

幫天然呆寶寶發呆,隱藏顯示煩人時間的status bar

iOS App在執行時,最上方往往有一條顯示時間,電量的status bar。大部分的情況下,這是個貼心的設計,讓我們可以時時刻刻看到時間,不會因為沉迷於App忘了重要的約會。然而有些App,比方遊戲,往往心懷不軌地想要我們沉迷於遊戲裡,因此偷偷地把status bar藏了起來。在最新的Xcode 4.5,將App的status bar設為隱藏更容易了。接下來彼得潘將以插畫家Hana Mini繪製的可愛角色,天然呆寶寶為例,為大家說明隱藏status bar的小小技巧。

                                                    愛上了夏天螢火蟲的天然呆


可愛的天然呆寶寶常常放空、發呆,反應慢,喜歡簡單的生活。不過最近他常常無法安心發呆,因為要隨時注意時間,晚上6點準時接送女朋友。為了讓他能自在地發呆,讓我們幫他把顯示煩人時間的status bar移除掉吧,偶爾也該讓女朋友學習自己坐計程車回家。



假設專案名稱是Test,讓我們切換到Target Test的Summary頁面,找到Status Bar區塊。看到了嗎? 就是那道光,"Hide during application launch"前方有個框框,將其勾選即可隱藏status bar。




執行App:

天然呆終於不再被status bar煩人的時間干擾,可以忘記晚上6點要接送女朋友,放心地放空發呆了 !

2012年10月22日 星期一

弘光科技大學演講



101年10月22日 13:45 ~ 16:25

主題: 
Part 1:  彼得潘的App逐夢之旅
Part 2   App學習和工作之道


2012年10月19日 星期五

2012年10月18日 星期四

V.K克的SoundCloud雲端琴聲 (MacToday 2012.10)


SoundCloud是目前十分火紅的雲端音樂平台,如果說Youtube是諸葛亮,那麼SoundCloud就是周瑜了。Youtube的強項在影片,SoundCloud則在音樂。這些雲端平台讓許多像彼得潘這樣的平凡人實現唱歌,演電影的夢想,而對已經成名的明星來講,這些雲端平台不只有著更快,更國際化的宣傳效果,還能省下大筆的行銷預算。接下來彼得潘將以好朋友,亞洲鋼琴天王V.K克存放於SoundCloud的作品為例,介紹如何結合SoundCloud API,播放V.K克遠在天邊的琴聲陪伴我們度過漫漫長夜。

一. 雲端音樂霸主SoundCloud

SoundCloud大方地提供我們不小的雲端音樂儲存空間,方便我們和朋友分享自己石破天驚的創作或一聽上癮的歌聲。畢竟像張學友這樣的歌神,周杰倫這樣的創作奇才, 一百年才出現一個,120分鐘的音樂總合時間,對於像彼得潘這樣的素人來說已經足夠。





彼得潘的好朋友,鋼琴天王V.K克,早已將專輯裡的音樂放到SoundCloud上,讓網友們免費試聽。如圖所示,我們可以看到SoundCloud十分強大,不只提供播放音樂的功能,還結合了Facebook的Like,iTunes的購買連結,讓更多的人可以認識,分享V.K的音樂。



二. 獵取V.K克的雲端使用者ID

想要在App裡播放V.K克的音樂,首先我們得先顯示音樂清單,也就是要取得V.K克的作品清單。SoundCloud提供以下API供我們取得某人的音樂清單。


USER_ID和CLIENT_ID是我們要另外指定的。現在彼得潘首先介紹如何獵取V.K克的雲端使用者ID,也就是USER_ID。

1. 連到SoundCloud的V.K克頁面。



2. 點選Share按鈕,從彈出的視窗裡複製Embed Code。


3. 解密Embed Code。

<iframe width="100%" height="450" scrolling="no" frameborder="no" src="http://w.soundcloud.com/player/?url=http%3A%2F%2Fapi.soundcloud.com%2Fusers%2F8546094&show_artwork=true"></iframe>

重點在於users%2F8546094,%2F後的8546094即是神秘的V.K克USER_ID。真是踏破鐵鞋無覓處,得來全不費功夫,太容易了!



三.  取得神秘的CLIENT_ID

為了防止閒雜人等隨意存取,利用CLIENT_ID之類的字串來識別來者為何方神聖,只有握有合法認證CLIENT_ID的App才能存取雲端上的珍貴資料,已成為大多數網站採用的API存取機制。因此SoundCloud也不例外,接下來就請各位讀者跟著彼得潘一步步操作,建立握有合法CLIENT_ID,存取V.K克雲端音樂的App。。

1. 連到SoundCloud網站首頁。




2. 點選Sign in with Facebook,以Facebook帳號登入。

3. 建立新App。

連到以下頁面,http://soundcloud.com/you/apps,點選Register a new application按鈕。


4. 設定App名稱V.K克。


5. 設定App採用走在時代尖端的認證機制OAuth2。

什麼都不用改,只要點選右下角的Save app即可。

我們尚缺的那臨門一腳,Client ID,原來就在此頁面。請將它好好記牢,等會彼得潘將結合User ID和Client ID,登上雲端聆聽V.K克的琴聲。

四.  結合SoundCloud SDK。

1. 建立Single View Application專案ListenVK。

2. 安裝SoundCloud SDK。

切換到專案ListenVK資料夾下。

git submodule add git://github.com/soundcloud/CocoaSoundCloudAPI.git
git submodule add git://github.com/nxtbgthng/OAuth2Client.git
git submodule add git://github.com/nxtbgthng/JSONKit.git
git submodule add git://github.com/nxtbgthng/OHAttributedLabel.git
git submodule add git://github.com/soundcloud/CocoaSoundCloudUI.git

將CocoaSoundCloudUI.xcodeproj, JSONKit.xcodeproj, OAuth2Client.xcodeproj, OHAttributedLabel.xcodeproj, CocoaSoundCloudAPI.xcodeproj加入專案。


3. 設定header。

切換到Target的Build Settings頁面,於Header Search Paths欄位輸入代表專案目錄的$PROJECT_DIR,並記得勾選前面的框框。如此到時尋找header時將recursive地尋找專案目錄下的所有檔案。


4. 設定依靠的library(Target Dependencies) 。

切換到Target的Build Phases頁面,於 Target Dependencies區塊加入libSoundCloudUI.a, OAuth2Client.a, libJSONKit.a, OHAttributedLabel.a以及SoundCloudAPI.a。


5. 設定連結的library

於Link Binary With Libraries區塊加入libJSONKit.a, libOAuth2Client.a, libOHAttributedLabel.a, libSoundCloudAPI.a, libSoundCloudUI.a,  AddressBook.framework, AddressBookUI.framework, CoreLocation.framework, CoreText.framework,QuartzCore.framework, Security.framework。


6. 設定linker flag。

切換到Target的Build Settings頁面,於Other Linker Flags欄位輸入-all_load -ObjC。


7. 將原本在SoundCloudUI.xcodeproj -> Resources的SoundCloud.bundle複製到ListenVK下。



五.  取得SoundCloud上的V.K克音樂清單。

NSString *resourceURL = @"https://api.soundcloud.com/users/8546094/tracks.json?client_id=9fcae9e1437a8ca39cd9d60d6c8cc321";
    
NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:resourceURL]];
    
[NSURLConnection sendAsynchronousRequest:req queue:[NSOperationQueue currentQueue] completionHandler:^(
         NSURLResponse  *response, NSData *data,                                                                 
                                NSError *error) {
         if(error == nil)
         {
             NSError *jsonError = nil;
             NSJSONSerialization *jsonResponse = 
               [NSJSONSerialization JSONObjectWithData:data
                          options:0 error:&jsonError];
             if (!jsonError && [jsonResponse isKindOfClass:[NSArray 
               class]]) {
                 NSArray *trackArray = (NSArray *)jsonResponse;
             }
         }
     }];

說明:
(1) NSString *resourceURL = @"https://api.soundcloud.com/users/8546094/tracks.json?client_id=9fcae9e1437a8ca39cd9d60d6c8cc321";

有了V.K克的USER_ID和V.K克App的CLIENT_ID,即可由tracks.json取得音樂清單。

(2) NSJSONSerialization *jsonResponse = [NSJSONSerialization
                                                  JSONObjectWithData:data
                                                  options:0
                                                  error:&jsonError];
      if (!jsonError && [jsonResponse isKindOfClass:[NSArray class]]) {
                NSArray *trackArray = (NSArray *)jsonResponse;

Server回傳的音樂清單,其實是JSON格式,Array包裝成的清單,因為我們將其轉化為NSArray。Array裡的每個元素都是內容豐富的Dictionary,除了常見的title(曲目名稱),artwork_url(圖片)外,連購買連結(purchase_url)都貼心幫我們準備好。


執行App:

顯示SoundCloud上取得的V.K克音樂清單。


六.  播放V.K克的琴聲。

NSDictionary *track = [trackArray objectAtIndex:indexPath.row];
NSString *streamURL = [NSString stringWithFormat:@"%@?client_id=9fcae9e1437a8ca39cd9d60d6c8cc321", [track 
    objectForKey:@"stream_url"]];
self.player = [AVPlayer playerWithURL:[NSURL  
                 URLWithString:streamURL]];
[self.player play];

說明:
(1) NSString *streamURL = [NSString stringWithFormat:@"%@?client_id=9fcae9e1437a8ca39cd9d60d6c8cc321", [track 
    objectForKey:@"stream_url"]];

包含豐富音樂資訊的Dictionary裡, stream_url正包含音樂檔案連結的URL。

(2)  self.player = [AVPlayer playerWithURL:[NSURL  URLWithString:streamURL]];

利用 AVPlayer的playerWithURL: method,幫我們連線天邊,串流雲端的V.K克音樂。



2012年10月17日 星期三

不用開刀也能偏心的FB興趣清單

FB上的朋友和粉絲團數量實在驚人,即使是像彼得潘這樣的FB重度使用者,現在也無法保證沒有遺漏這些好朋友們,好粉絲團每天發表的珍貴文章了。 當然並不是每個朋友,粉絲團都一樣重要,我們想要的是能夠偏心,讓某些暗戀的對象,珍愛的粉絲團貼文保證被我們看到。

想要偏心其實很簡單,不用花錢傷身地開刀,只要善用FB的興趣清單即可。接下來,彼得潘將以自己的粉絲團為例,介紹如何利用興趣清單來偏愛某某某吧! 

1. 點選粉絲團頁面右邊的齒輪按鈕。
   
別害怕,這個齒輪完全不會割人啦。 點選後再選擇"Add to Interest Lists",將粉絲團加到興趣清單。




2. 如果之前完全沒有建立過興趣清單,或是想要建立新的興趣清單,請選擇New List。



若是之前建立過興趣清單,比方曾建立過彼得潘,在此清單下將看到彼得潘親切的跟你打招呼呢!




3.  顯示將加到此清單上的幸運朋友,暗戀對象,或是崇拜的粉絲團。



在這個頁面我們還可以做調整,選擇將其它的朋友或粉絲團加入。



4. 設定興趣清單的名稱和哪些人看得到。




完成後看到彼得潘的App開發技術分享或是即興的心情小語機會將大大提高唷 !


2012年10月15日 星期一

六大天王海報牆 - 神乎奇技的圖片重覆排列

圖片可不是只有單純的放大縮小那麼簡單,利用神乎奇技的圖片重覆排列技巧,我們可以設計更有創意,更天馬行空的App畫面。接下來,就讓彼得潘小時候的六大偶像,林隆璇,張智霖,劉德華,梁朝偉,戴佩妮,蔡淳佳,為大家好好表演海報牆的效果吧 !



測試圖片: idol.png  ( 180 pixel * 120 pixel),每個天王各佔 60 * 60 的空間。




UIImage *image = [UIImage imageNamed:@"idol.png"];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 548)];
imageView.image = image;
[self.view addSubview:imageView];

執行App:

尚未施展圖片重覆排列技巧前,圖片呆呆地整個放大到320* 548,每個天王的身材比例都跑掉了 !



圖片重覆排列技巧:

利用UIImage的resizableImageWithCapInsets: method,我們可以控制圖片的縮放,限制圖片的某個區塊維持固定大小,其它未被限定的區塊則以重覆堆疊的方式填滿欲顯示的範圍,例如UIImageView所佔的空間。

resizableImageWithCapInsets:的定義如下:
- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets

利用UIEdgeInsets型別的capInsets,我們可以控制圖片中維持固定大小的區塊。接下來讓我們經由實際例子,了解UIEdgeInsets的威力吧。

UIImage *image = [[UIImage imageNamed:@"idol.png"]     
                  resizableImageWithCapInsets:UIEdgeInsetsMake(0, 60, 0, 0)];

利用UIEdgeInsetsMake(0, 60, 0, 0)建立capInsets。其定義如下:
UIEdgeInsetsMake(CGFloat top, CGFloat left, CGFloat bottom, CGFloat right)

剛剛的例子裡,表示我們希望圖片裡距離左邊界60 points的區塊維持固定大小。讓我們先偷看結果,再來說明。

執行App:

從下圖我們看到林隆璇和梁朝偉固定在第一個column休息,但其它4個偶像卻要辛苦地重覆排列將畫面填滿。這是因為林隆璇和梁朝偉所佔據的空間正是距離左邊界60 points的區塊,所以他們享有特權,可以維持原狀,不用分擔填滿畫面的重擔。



讓我們試試同時設定左邊和右邊各60 points,看看有何變化。

UIImage *image = [[UIImage imageNamed:@"idol.png"] 
                resizableImageWithCapInsets:UIEdgeInsetsMake(0, 60, 0, 60)];


執行App:

這一次佔據距離左邊界60 points的林隆璇和梁朝偉,以及佔距離右邊界60 points的劉德華和蔡淳佳都可以維持原狀休息,只有居中的張智霖和戴佩妮要獨自負責填滿畫面的重責大任,真是辛苦他們了。



一直顧左右也不是辦法,讓我們換個方向,試試設定距離上邊界60 points吧。

UIImage *image = [[UIImage imageNamed:@"idol.png"] 
               resizableImageWithCapInsets:UIEdgeInsetsMake(60, 0, 0, 0)];

執行App:

輪到距離上邊界60 points的林隆璇,張智霖和劉德華可以休息了,剩下其它三個人繼續辛勞地填滿畫面。



為了公平起見,再換個方向,設定距離下邊界60 points吧。

UIImage *image = [[UIImage imageNamed:@"idol.png"] 
                resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 60, 0)];



執行App:

風水輪流轉,梁朝偉,戴佩妮,蔡淳佳終於可以休息了,換剛剛在一旁閒很久的三個人來重覆排列填滿畫面了。




2012年10月14日 星期日

播放天生愛情狂"張智霖"的Youtube MV

iOS SDK內建的MPMoviePlayerController十分強大,輕輕鬆鬆就能播放手機上或雲端上的網路影片,然而如果直接指定Youtube影片的URL,MPMoviePlayerController卻變成啞巴吃黃蓮,有苦說不出,完全無能為力,無法順利播放。幸運地,第三方套件LBYouTubeView已經幫我們解決了這個問題,成功地利用MPMoviePlayerController播放Youtube影片。接下來彼得潘將為各位示範如何運用LBYouTubeView,播放偶像張智霖即將上映的愛情電影"天生愛情狂"。

1. 下載利用MPMoviePlayerController播放Youtube影片的LBYouTubeView

git clone https://github.com/larcus94/LBYouTubeView.git

2. 建立新專案PlayYoutube

3. 將剛剛下載的LBYouTubeView資料夾加入專案


4. 加入MediaPlayer.framework


5. 移除使用JSONKit的程式碼

iPhone使用者升級到新版iOS的比例很高,現在絕大多數的使用者都已升到iOS 5以上,因此我們可以大膽採用iOS 5內建的JSON API,不需要再透過第三方library JSONKit。

(1) 移除#import "JSONKit.h"  (LBYouTubeExtractor.m)

(2)  在_extractYouTubeURLFromFile:error: method裡 (LBYouTubeExtractor.m)
       移除
       else {
            JSONCode = [JSON objectFromJSONStringWithParseOptions:JKParseOptionNone  
                    error:&decodingError];
        }

6.  利用LBYouTubePlayerViewController播放Youtube影片  

PlayYoutubeViewController.h.m:

#import "LBYouTubePlayerViewController.h"


@interface PlayYoutubeViewController ()
{
    LBYouTubePlayerViewController* controller;
}
@end

@implementation PlayYoutubeViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
    
    
    NSURL *url = [NSURL URLWithString:@"http://www.youtube.com/watch?v=kLKaZ6Mi3H0"];
    controller = [[LBYouTubePlayerViewController alloc] initWithYouTubeURL:url quality:LBYouTubeVideoQualityLarge];
    controller.view.frame = CGRectMake(0.0f, 0.0f, 200.0f, 200.0f);
    controller.view.center = self.view.center;
    [self.view addSubview:controller.view];
    
}
說明:
(1) NSURL *url = [NSURL URLWithString:@"http://www.youtube.com/watch?v=kLKaZ6Mi3H0"];

設定張智霖浪漫愛情電影"天生愛情狂"MV的Youtube URL。

(2) controller.view.frame = CGRectMake(0.0f, 0.0f, 200.0f, 200.0f);
     controller.view.center = self.view.center;

設定影片顯示的位置和大小。

執行App:

影片會貼心地自動播放,不用勞駕使用者動指按下播放鍵。


點選右下角的放大button後,即可以放大播放。



如果還不滿足,還可以再次點選右上角的放大button,使影片佔滿整個畫面,但由於一般影片都是寬螢幕的比例,所以在直立畫面時將有部分畫面被切除。


最好的影片觀賞角度當然是水平模式呀,讓我們將iPhone轉向,以水平角度好好欣賞張智霖微笑的帥氣表情。



很多時候,我們想在App裡呈現的影片不只一個。因此我們希望能夠顯示影片的縮圖清單,然後再讓使用者自行選出一見鍾情的影片觀看,抓取Youtube影片的縮圖其實很簡單,縮圖的網址規則如下:

http://img.youtube.com/vi/VIDEO_ID/#.jpg

以"天生愛情狂"為例,其影片URL為http://www.youtube.com/watch?v=kLKaZ6Mi3H0,因此它的VIDEO_ID為kLKaZ6Mi3H0。 而#我們可以用 0 ~ 3代入,對應到Youtube幫我們產生的影片縮圖。 1 ~ 3都是120*90的小圖,2則是預設的縮圖。 0的圖案同2,只不過大小為480*360的大圖。

ex:











2012年10月13日 星期六

努力化身不怕雨淋的永恆寶石,App泡沫化又怎樣


最近有朋友問彼得潘,App那麼多,會不會快要泡沫化了?現在投入還值得嗎?

其實多少根本不是問題,當競爭少時物以稀為貴,一個70分的App就可以取得不錯成績,但這樣子的成就是短暫的。只有自己才是我們最大的敵人,並不是別人。以自己為目標,努力朝著做出100分的App夢想前進。當我們擁有做出100分App的實力時,早已經化身為不怕雨淋的永恆寶石,無論多大的泡沫,都掩蓋不了持續閃爍著的寶石的 !



                          

2012年10月11日 星期四

如女人心般難捉摸的圖片ContentMode

一張圖勝過千言萬語。多了美麗圖片加持的App,就是跟別人不一樣。在App裡想要展示這些美美的圖片,要嘛透過UIImageView,要嘛經由UIButton。然而圖片的比例往往跟我們想要顯示的大小有段落差,這時候就得依賴contentMode決定圖片的縮放方式了。接下來,彼得潘將介紹當UIButton遇上contentMode時,會產生哪些意想不到的惱人問題。(感謝彼得潘的朋友查爾斯提供可愛的狐狸圖片作為以下範例的主角。)





1. 在畫面上加入顯示狐狸圖片的UIButton

UIButton *imageButton = [[UIButton alloc] initWithFrame:CGRectMake(60, 80, 200, 200)];
 [imageButton setImage:[UIImage imageNamed:@"fox.png"] forState:UIControlStateNormal];
 [self.view addSubview:imageButton];

2. 在圖片上加上同樣200*200的半透明View,方便我們等會分析圖片的縮放。
 
UIView *whiteView = [[UIView alloc] initWithFrame:CGRectMake(60, 80, 200, 200)];
whiteView.backgroundColor = [UIColor colorWithWhite:1 alpha:0.3];
[self.view addSubview:whiteView];

執行App:

如圖所示,當利用setImage:forState:設定圖片時,預設的contentMode為UIViewContentModeScaleToFill,所以令人心疼地,可愛的小狐狸變形了。



讓我們將contentMode設為UIViewContentModeScaleAspectFit,救救小狐狸,讓牠維持比例縮放吧。

imageButton.imageView.contentMode = UIViewContentModeScaleAspectFit;


執行App:


如圖所示,圖片乖乖地待在我們限定的200*200範圍內維持比例縮放,不敢越雷池一步。(可從半透明的View辨別200*200所在範圍)



能不能貪心地希望小狐狸更清楚點,給小狐狸特寫呢?當然可以,只要將contentMode設為UIViewContentModeScaleAspectFill,即可讓小狐狸維持比例縮放,但又能勇敢地部分超出範圍,實現完全佔滿200*200範圍的目標。

imageButton.imageView.contentMode = UIViewContentModeScaleAspectFill;



執行App:



imageButton的imageView.clipsToBounds預設為YES,所以超出的部分看不到。相反的,如果是UIImageView物件,其clipsToBounds預設為NO,所以當contentMode設為UIViewContentModeScaleAspectFill時,我們將完整看到超出的部分。  




sometimes when we touch

除了clipsToBounds的差異外,UIButton和UIImageView最大的差別在於它可以觸碰,它是有感情,觸碰會有感應的,不像冰冷冷的UIImageView。如下圖所示,當sometimes when we touch發生時,仿彿有氣氛的夜晚來臨,圖片明顯變暗讓我們明確感覺正在觸碰中。




但在iOS 5時,當我們調整了UIButton的imageView.contentMode後,觸碰時卻會產生不正常的現象。如下圖所示,觸碰時圖片又回復為原來的UIViewContentModeScaleToFill。因此,在iOS 5時,為了解決這個問題,有個折衷的做法,那就是將UIButton的adjustsImageWhenHighlighted設為NO,如此雖然Touch時不會變暗,但至少圖片不會變形。




圖片尺寸問題

如果圖片的size較我們設定的UIButton尺寸小,當利用setImage:forState:設定圖片時,此時無論我們將UIButton的imageView設為哪一種contentMode,圖片都將頑固地維持原狀,不會放大。若是UIImageView物件,則不會有此問題。




特別感謝:

查爾斯的blog視說新語:

http://whereyou.pixnet.net/blog

查爾斯的FB視說新語:
https://www.facebook.com/EyeNews