2013年12月15日 星期日

iOS 開發筆記 - UITableViewController Editing Mode 隱藏 Delete 按鈕(Move Only)

UITableViewControllerEditMode

開始把玩 UITableViewController Editing mode,由於不想讓使用者刪資料,所以就需要把 Delete 相關的操作介面給關掉。

簡言之:

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //if (self.editing)
    //    return UITableViewCellEditingStyleDelete;
 
    return UITableViewCellEditingStyleNone;
}


如此一來即可:

UITableViewControllerEditModeWithoutDeletition

2013年12月14日 星期六

免費導航王 - 台灣版小米機可免費使用勤崴導航王 android app 一整年

導航王小米版

半年前幫家人添購一台小米2S,最近我自己也用了一台,然後莫名又有一台紅米。當我徜徉於紅米的高 CP 時,看到台灣小米機又可以免費用「導航王」!有更賺到的感覺!(台灣版小米2S或紅米都可以使用)

紅米機的性能的確已經非常夠用,特別適用那些常用來打電話,但偶爾又想透過手持裝置獲得瀏覽網頁資訊的人。有了免費的導航王後,紅米又可以變身為導航車機啦!

詳情請參閱:歡慶【導航王】成為小米台灣獨家導航軟體合作夥伴!

用法:

  1. 從 勤崴官網 下載專屬於台版小米機的 導航王 app (NaviKing_Android_XiaoMi_WXGA_2.134.0.116.apk)
  2. 透過 USB 傳輸線,把下載好的 NaviKing_Android_XiaoMi_WXGA_2.134.0.116.apk 擺在小米機上,如 Download 資料夾
  3. 使用小米機內建檔案管理,開啓 NaviKing_Android_XiaoMi_WXGA_2.134.0.116.apk 即可進行安裝
  4. 安裝完導航王後,啟動後再下載圖資
  5. 一切安裝完後,重新啟動導航王即可

此外,試用了導航王後,發現他已經把一些常用的旅遊、生活類功能都做進去了!不見得要把它當行車導航的 app :

導航王小米版1

導航王小米版2

導航王小米版3

導航王小米版4

導航王小米版5

2013年12月11日 星期三

紅米機開箱文

紅米開箱

不知不覺手邊就多了這隻,預計要拿來送給長輩使用的 XD 其次是當開發機。

用紅米玩一下 Candy Crush 時,發現寶石落下時會 lag ?! 有擔心一下,但是改玩 Angry Birds 倒還好,其他拍照的顏色也還滿鮮豔的。整體上品質還挺不錯的,螢幕尺寸大也挺顧眼睛的,紅米顯而易見的缺點是內建儲存容量僅4GB,可以用的可能只有2GB,還好可以加microSD來使用。

剛好手邊有小米2S就順便比一下吧!(左邊小米2S,右邊紅米)


紅米與小米2s大小差異2

紅米與小米2s大小差異

小米2s和紅米

紅米與小米2s大小差異3

試用完紅米後,我還是喜歡小米2S的尺寸 XDD 但如果是愛帶包包的人,或許就沒差別了。

iOS 開發筆記 - 使用 Core Graphics 進行文字繪圖輸出並設定 NSString Attributes (Font、Alignment) 等

draw string

整理一年多前的程式碼,發現用的函數已經在 iOS 7 宣告為 deprecated 啦,恰好重看 CS193P 時,得知 NSAttributedString 這東西,以為是最新出來的,沒想到這在 iOS 3.2 就存在啦。

順便把一些筆記都記下吧:

+ (UIImage *)buildImageAndDrawText:(NSString *)text size:(CGSize)size ios7:(BOOL)iOS7SDK
{
    UIGraphicsBeginImageContext(size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetRGBFillColor(context, 1, 1, 1, 1);
    CGContextFillRect(context, CGRectMake(0, 0, size.width, size.height));

    UIFont *font = [UIFont italicSystemFontOfSize:15];
    UIColor *fontColor = [UIColor blueColor];

    if (iOS7SDK) {
        NSMutableParagraphStyle *paragrapStyle = [[NSMutableParagraphStyle alloc] init];
        [paragrapStyle setLineBreakMode:NSLineBreakByWordWrapping];
        [paragrapStyle setAlignment:NSTextAlignmentCenter];
     
        [text drawInRect:CGRectIntegral(CGRectMake(0, size.height/2, size.width, size.height))
          withAttributes:@{
                           NSParagraphStyleAttributeName: paragrapStyle,
                           NSFontAttributeName: font,
                           NSForegroundColorAttributeName: fontColor}
         ];
    } else {
        [fontColor set];
        [text drawInRect:CGRectIntegral(CGRectMake(0, size.height/2, size.width, size.height)) withFont:font lineBreakMode:NSLineBreakByWordWrapping alignment:NSTextAlignmentCenter];
    }
 
    UIImage *outImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return outImage;
}


用法:

self.imageView = [YourClass buildImageAndDrawText:@"iOS app development @ blog.changyy.org" size:CGSizeMake(300, 300) ios7:YES];

細節可參考 Core Graphics Framework Reference


2013年12月10日 星期二

iOS 開發筆記 - 透過 semaphore 讓 function 特性從 nonblocking 回到 blocking 模式

相信從事 Window Programming 的大多都知道 Main thread(UI thread) 的特性,例如 Main Thread 用來處理事件,須儘量避免做太久的工作,此外,所謂的 nonblocking 的原理就只是在建立一支 thread 去執行任務,任務完成後在依照設計返回到 Main thread 去更動 UI 狀況。
因此,採用一些手機視窗程式等第三方 SDK 時,更是容易碰到 nonblocking functions。這會使得規劃的 function flow 有點亂掉。

在 iOS app development 環境中,以 block 為例,可以透過 semaphore 來達成 blocking 效果,如:

dispatch_semaphore_t waitJobDone = dispatch_semaphore_create(0);
[self callBlock:^{
// do something
dispatch_semaphore_signal(waitJobDone);
}];
dispatch_semaphore_wait(waitJobDone, DISPATCH_TIME_FOREVER);


順便筆記一下其他東西,隨意使用 nonblocking 用法:

dispatch_async( dispatch_queue_create(“job_running”, NULL), ^{


});


在非 UI thread 中,又想動 UI 方式:

dispatch_async( dispatch_queue_create("job_running", NULL), ^{
// do something ...
     
dispatch_async(dispatch_get_main_queue(), ^{
// update ui
});
});


最後一提,如果用到的 SDK 跟網路相關的(NSURLConnection),那大多不能用 semaphore 來使之改成 blocking 模式(或是改法很繁雜要深入or破壞SDK架構),這跟 NSURLConnection Delegate Callback 設計有關(NSRunLoop)。