顯示具有 iOS 標籤的文章。 顯示所有文章
顯示具有 iOS 標籤的文章。 顯示所有文章

2015-01-07

OS X 與 iOS 的「接續互通」之「Handoff」

OS X Yosemite 與 iOS 8 有個 [Continuity](接續互通) 的特點,你可以參考官方網址

其中的 [Handoff] 可以讓你將工作從電腦與行動裝置之間無痛接續,WWDC 2014 也有指導你如何加入這樣的機制。

基本上需要這兩項:

  1. BTLE
  2. NSUserActivity

你可以參考 Handoff Programming Guide
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/Handoff/HandoffFundamentals/HandoffFundamentals.html

也可以參考 WWDC 2014
https://developer.apple.com/videos/wwdc/2014/?id=219

著名的 Raywenderlich 也有教學 iOS 8 Handoff Tutorial
http://www.raywenderlich.com/84174/ios-8-handoff-tutorial


其他參考資源:

Tutorial: A Step-By-Step Guide To Programming The Handoff Feature In iOS 8
https://maniacdev.com/2014/12/tutorial-a-step-by-step-guide-to-programming-the-handoff-feature-in-ios-8

Working with Handoff in iOS 8
http://www.appcoda.com/handoff/

Working with iOS 8 Handoff Part 2: Using Continuation Streams
http://www.appcoda.com/handoff-continuation-streams/

.

2014-11-14

Xcode 6 在模擬器 iPhone 5 + iOS 7 的版面上下黑邊

如果您在 Xcode 6 發現了模擬器以 iPhone 5 執行 iOS 7 時,是以 320x480 的版面而非 320x568 時,應該如何排解?
Xcode 6 執行選擇 iPhone 5/5s + iOS 7.1

iPhone 5 + iOS 7 不應該上下有黑邊
照理說,iPhone 5 應該是 4 吋 Retina 的解析度 320x568 不應該成為 320x480 而讓畫面留下上下的黑邊。

原因是這樣:

原來是在 4 吋 Retina 的設備,少了 Default-568h@2x.png 的啟始畫面。

註:在 iOS 7.1 以前需要的啟始畫面檔案
  • Default.png - 320 x 480 pixels (standard resolution iPhone)
  • Default@2x.png - 640 x 960 pixels (high resolution iPhone 4)
  • Default-568h@2x.png - 640 x 1136 pixels (iPhone 5)



所以,如果您的 App 專案有這樣的設定時:

解決的方式,除了可以加入一個 640 x 1136 的 Default-568h@2x.png 檔案之外,可以在 Project 的 TARGETS 設定內,從 General 頁面內的 App Icons and Launch Images 將 Launch Images Source,按下「Use Asset Catalog」


您再執行看看,結果就不會在 iPhone 5/5s + iOS 7.1 的畫面上下出現黑邊了。

.

2013-09-11

簡碼到用時方恨少

需要時可以查閱。


在這裡,看到了吧!


編輯器輸入點移到關鍵字後面,按下 ESC 按鍵,就可以看到。

.



2013-06-05

UIColor 存放到 NSDictionary/NSMutableDictionary 內

之前有篇提到「UIImage 存放到 NSArray/NSMutableArray 內」讀過之後,是不是了解到 imageNamed:imagePath 並不是直接將 imagePath 路徑內的圖片載入 Array 內了?

這次來看看 UIColor。

如果你這樣用:

NSDictionary *dict0 = [[NSDictionary allocinitWithObjectsAndKeys:
                           @"紅色"@"CColor",
                           [UIColor redColor], @"EColor",
                           @"YES"@"Fill",
                           nil];

Xcode 會跟你這樣說:
-[UICachedDeviceRGBColor bytes]: unrecognized selector sent to instance 0xa9671e0
ColorInDictionary[7955:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UICachedDeviceRGBColor bytes]: unrecognized selector sent to instance 0xa9671e0'
原因是 NSDictionary 內容不允許你直接存入 [UIColor redColor] 的關係。


於是你要將 [UIColor redColor] 包裝起來,改用 [NSKeyedArchiver archivedDataWithRootObject:[UIColor redColor]]

像這樣:

NSDictionary *dict0 = [[NSDictionary allocinitWithObjectsAndKeys:
                           @"紅色"@"CColor",
                           [NSKeyedArchiver archivedDataWithRootObject:[UIColor redColor]], @"EColor",
                           @"YES"@"Fill",
                           nil];

取用時再拆開,還原成 UIColor 即可

UIColor *colorNow = [NSKeyedUnarchiver unarchiveObjectWithData:[dict0 objectForKey:@"EColor"]];


.

2013-04-19

UIImage 存放到 NSArray/NSMutableArray 內

最近學員遇到一個問題,要將 UIImage 放到 NSMutableArray 內,但是很不幸地會發生這樣的錯誤訊息:
ImageArray[5343:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'

不管是從 NSBundle 或是從 NSFileManager 取得 Documents 的都一樣。

載入如下:

NSArray *directoryContent = [[NSBundle mainBundle] pathsForResourcesOfType:@"png" inDirectory:nil];
NSMutableArray *items = [[NSMutableArray alloc] initWithCapacity:0];

for (NSString *imagePath in directoryContent) {
    UIImage *img = [UIImage imageNamed:imagePath];
    [items addObject:img];
}
NSLog(@"imagesArray:%@", items);

可是執行之後,就會得到上述的錯誤訊息。

錯誤的原因就在這句:
UIImage *img=[UIImage imageNamed: imagePath];

只要改成
UIImage *img = [UIImage imageWithContentsOfFile:imagePath];

錯誤就可以修正


最後正確的程式碼如下:

NSArray *directoryContent = [[NSBundle mainBundlepathsForResourcesOfType:@"png" inDirectory:nil];
NSMutableArray *items = [[NSMutableArray allocinitWithCapacity:0];

for (NSString *imagePath in directoryContent) {
    UIImage *img = [UIImage imageWithContentsOfFile:imagePath];
    [items addObject:img];
}
NSLog(@"imagesArray:%@", items);


善用你在 Xcode 的 Option+Click,你就可以找到答案了:

+ (UIImage *)imageWithContentsOfFile:(NSString *)path
Creates and returns an image object by loading the image data from the file at the specified path.
This method does not cache the image object.

+ (UIImage *)imageNamed:(NSString *)name
Returns the image object associated with the specified filename.
This method looks in the system caches for an image object with the specified name and returns that object if it exists


下載範例檔案
.

2013-04-01

Storyboard 有兩個 Segue 的問題

剛好有學員問到這樣的問題,我就拿該程式畫面在這裡做個圖文解說。
這個畫面連結了兩個 Segue
一般 Segue 都是要在  - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 內安排,如果有 Object 或 Value 要往下個 ViewController 傳遞的話,也是在這裡處理。


另外,如果只有一個 Segue 是從 UIButton 發生,可以這樣做:
- (IBAction)btnSyp:(id)sender {
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    Game01VC *vc = [storyboard instantiateViewControllerWithIdentifier:@"CustomerAdd"];
    vc.Flag = 1;
}

但是,第二個 UIButton 就無法如預期發生。
- (IBAction)btnKiller:(id)sender {
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    Game01VC *vc = [storyboard instantiateViewControllerWithIdentifier:@"CustomerAdd"];

    vc.Flag = 2;
}

所以,還是要回來以 prepareForSegue 處理。


先在 Storyboard 內設定好 Segue 的 Identifier 為 @"btnSyp" 與 @"btnKiller"


在第一個 UIButton 連結的 Segue 設定 Identifier 為 @"btnSyp"
另一個 UIButton 連結的 Segue 設定 Identifier 為 @"btnKiller"

在 prepareForSegue 內的程式如下:

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    Game01VC *vc = segue.destinationViewController;

// 原本在 -(IBAction)btnSyp:(id)sender 內的,移到這裡來,以這種方式做
    if ([segue.identifier isEqualToString:@"btnSyp"]) {
        vc.Flag = 1;
    }
    
// 原本在 -(IBAction)btnKiller:(id)sender 內的,移到這裡來,以這種方式做
    if ([segue.identifier isEqualToString:@"btnKiller"]) {
        vc.Flag = 2;
    }
}

如此,就可以讓下個 ViewController 收到 Object 或 Value 了。


.

2013-03-30

iOS Dev Club 聚會 2013-03-30 活動影片

張景隆分享 Passbook 的實作,向隅的朋友可以觀看影片。


很久沒有來的家銘,這段時間都在開發這個平台,InWedding



iOS Dev Club : iPhone/iPad/iPod touch 軟體應用開發
https://www.facebook.com/groups/iostw/

姻為妳 inWedding 粉絲頁
https://www.facebook.com/OurInWedding




2012-11-14

新版本 Xcode 的專案如何在舊版本 Xcode 開啟

我在寫這個文章的時間點,剛好 Mac OS X 普遍有 10.6,10.7,10.8 三個版本。
同時,Xcode 可以開發 iOS 5 以上,又有 StoryBoard 的,至少是 4.2(4C199)。
4.2(4C199) for Mac OS X 10.6.x

另外,Xcode 目前最新的版本是 4.5.2 (4G2008a),新版的 Xcode 除了開發 iOS 6 需要之外,在設計時的效率可以幫助不少,所以可以更新的建議就直接更新。
4.5.2 (4G2008a) for Mac OS X 10.8.x
但是,如果你的 Mac 是 OS X 10.6.x,你的 Xcode 頂多只可以升級到的盡頭是 Xcode 4.2(4C199) 這個版本,也就是只有開發 iOS 5 的 App。

這兩年的 Xcode 變化很大,尤其是加入了 StoryBoard,剛好我以前的教材範例多用 XIB,為了轉換到 StoryBoard,已經改過一次了。

又遇到了客戶的專案以前用 4.2 寫的,雖然我的 iMac 上面還留著 Mac OS X 10.6,Xcode 還有兩個版本:Xcode 3.2.6 for iOS 4.3、Xcode 4.2(4C199) for iOS 5。
身邊的 MacBook Air 是 Mac OS X 10.8 & Xcode 4.5.2 (4G2008a)。

我剛好遇到過這個困擾:常常在 MacBook Air 做完,拿回到 iMac 上打不開。

其實,只要在新版 Xcode 選 MainStoryBoard,在 Interface Builder Document 屬性設定三個地方就可以解決這個困擾:
  1. Deployment 佈署設為 iOS 5.0
  2. Development 開發環境設為 Xcode 4.2
  3. Autolayout 取消勾選。
然後再將整個 Project 拿到舊版環境就可以開啟了。

在新版 Xcode 設定三個地方
只是你要知道,佈署與開發環境退回去舊版,相對的是不相容 iOS 6 的設備了。

以上希望對您有所幫助。

.

2012-09-20

iOS 6 beta 升級正式版本的韌體

很多朋友在 iOS 6 beta 就安裝了,但是當正式版本發佈時,iTunes 都一直說是最新版。

其實您可以直接下載韌體更新,位置如下:

iOS 6 Downloads

iPad Wi-Fi (3rd generation)
http://appldnld.apple.com/iOS6/Restore/041-3515.20120919.OYzOG/iPad3,1_6.0_10A403_Restore.ipsw

iPad Wi-Fi + Cellular (model for ATT)
http://appldnld.apple.com/iOS6/Restore/041-7163.20120919.19UEI/iPad3,3_6.0_10A403_Restore.ipsw

iPad Wi-Fi + Cellular (model for Verizon)
http://appldnld.apple.com/iOS6/Restore/041-7161.20120919.5CyjO/iPad3,2_6.0_10A403_Restore.ipsw

iPad 2 Wi-Fi (Rev A)
http://appldnld.apple.com/iOS6/Restore/041-2187.20120919.vmGkW/iPad2,4_6.0_10A403_Restore.ipsw

iPad 2 Wi-Fi
http://appldnld.apple.com/iOS6/Restore/041-0804.20120919.9SgHU/iPad2,1_6.0_10A403_Restore.ipsw

iPad 2 Wi-Fi + 3G (GSM)
http://appldnld.apple.com/iOS6/Restore/041-7165.20120919.eZTyh/iPad2,2_6.0_10A403_Restore.ipsw

iPad 2 Wi-Fi + 3G (CDMA)
http://appldnld.apple.com/iOS6/Restore/041-7167.20120919.y2ard/iPad2,3_6.0_10A403_Restore.ipsw

iPhone 4S
http://appldnld.apple.com/iOS6/Restore/041-7181.20120919.lEuOK/iPhone4,1_6.0_10A403_Restore.ipsw

iPhone 4 (GSM)
http://appldnld.apple.com/iOS6/Restore/041-7175.20120919.wvv7Y/iPhone3,1_6.0_10A403_Restore.ipsw

iPhone 4 (CDMA)
http://appldnld.apple.com/iOS6/Restore/041-7179.20120919.bDw4g/iPhone3,3_6.0_10A403_Restore.ipsw

iPhone 3GS
http://appldnld.apple.com/iOS6/Restore/041-7173.20120919.sDDMh/iPhone2,1_6.0_10A403_Restore.ipsw

iPod touch (4th generation)
http://appldnld.apple.com/iOS6/Restore/041-0807.20120919.soT6X/iPod4,1_6.0_10A403_Restore.ipsw


參考 https://developer.apple.com/ios/,非 GM 版