//這是一個簡單又好用的機制
//對你要觀察的物件calendar加入觀察者self,再把你想要觀察的屬性calendar.selectedDate,就會在屬性值改變時呼叫下面的方法
- (void)viewDidLoad{
//對calendar做KVO
[self.calendar addObserver:self forKeyPath:@"selectedDate" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];
}
//加入一個下列的方法,一旦上面的觀察值有所改變,就會執行下面的方法
-(void) observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
NSLog(@"observeValueForKeyPath is run");
if([keyPath isEqual:@"selectedDate"]){
//改變值存在change這個dictionary中,要用key= old或new去取值
NSLog(@"old price is %@",[change objectForKey:@"old"]);
NSLog(@"new price is %@",[change objectForKey:@"new"]);
}
}
2013年3月26日 星期二
判斷是否為iPhone 5
判斷是否為iPhone 5的代碼
#define iPhone5 ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 1136), [[UIScreen mainScreen] currentMode].size) : NO)
所以當使用時,僅需照以下寫法使用即可囉
if (iPhone5)
//do something for iPhone 5
else
//do something for iPhone 4s 4 3GS etc..
2013年3月21日 星期四
新增檔案時,選項的區別
轉貼自http://blog.csdn.net/mygamezone/article/details/8513327
1.Create groups for any added folders:
把選擇的文件添加到工程的group下。
應該它生成的文件夾是黃色的。
2.Create folder references for any added folders:
這種方法是建立一個文件夾的索引,同時文件夾中的所有文件也會添加到整個工程。
應該他生成的文件夾是藍色的。
黃色和藍色有什麼區別呢?
http://img.my.csdn.net/uploads/201301/17/1358404441_9553.png
我們做一個測試
self.image.image=[UIImage imageNamed:@"111.jpg"];
// 不會顯示圖片
self.image.image=[UIImage imageNamed:@"myimages/111.jpg"];
// 顯示圖片
self.image.image=[UIImage imageNamed:@"222.jpg"];
// 顯示圖片
self.image.image=[UIImage imageNamed:@"images/222.jpg"];
// 不會顯示圖片
也就是說
我們在做ios開發的時候經常是黃色的,在做cocos的時候經常是藍色的,
如果文件夾是黃色的,你不需要加上路徑
如果文件夾是藍色的,你需要加上路徑
其實我們可以這樣理解
看到黃色文件夾,說明它很色,它已經把衣服脫了,你可以直接使用它裡面的東西
看到藍色文件夾,說明它很矜持,如果你想怎麼的,你需要給它脫一脫
2013年3月19日 星期二
Facebook SDK 3.2
如果你是用github下載FacebookSDK
你將先build the framework
打開command line進入FacebookSDK的路徑
輸入
scripts/build_framework.sh
Then, FacebookSDK.framework will appear in FacebookSDK/build
在Delegate中一定要實做下面這兩個方法,不然授權完回到我們的App時不會觸發login等相關的動作。
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
return [self.facebook handleOpenURL:url];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [self.facebook handleOpenURL:url];
}
這裡有詳細教學
http://www.erawppa.com/整合-ios-facebook-sdk/
http://bani.org/blog/?tag=objective-c
你將先build the framework
打開command line進入FacebookSDK的路徑
輸入
scripts/build_framework.sh
Then, FacebookSDK.framework will appear in FacebookSDK/build
在Delegate中一定要實做下面這兩個方法,不然授權完回到我們的App時不會觸發login等相關的動作。
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
return [self.facebook handleOpenURL:url];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [self.facebook handleOpenURL:url];
}
這裡有詳細教學
http://www.erawppa.com/整合-ios-facebook-sdk/
http://bani.org/blog/?tag=objective-c
2013年3月18日 星期一
常遇到的錯誤訊息與解決方式
- 錯誤訊息:Undefined symbols for architecture i386 error
- 錯誤訊息:Apple Mach-O Linker Error
- 錯誤訊息:linker command failed with exit code 1
- 錯誤訊息:Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to create description in descriptionForLayoutAttribute_layoutItem_coefficient. Something is nil'
- 錯誤訊息:*** Assertion failure in -[UITableViewCell _setHostsLayoutEngine:], /SourceCache/UIKit/UIKit-3318.16.14/NSLayoutConstraint_UIKitAdditions.m:2760
- 錯誤訊息:file '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.0/include/limits.h' has been modified since the precompiled header '/Users/YourName/Library/Developer/Xcode/DerivedData/YourProject-bafemyyfpibvkfbxdrsjfkyzjmxb/Build/Intermediates/PrecompiledHeaders/YourProject-Prefix-hkhsfrjbjnwlltfbputhdimgctvv/YourProject-Prefix.pch.pch' was built
cd ~/Library/Developer/Xcode/DerivedData/ModuleCache,然後用rm -f -r ./*把這裡的cache都清掉。
- 錯誤訊息:process launch failed: NotFound
解決方式:如果xcode一直跳出這訊息,無法實機測試,把手機重新開機就可以了。
- 錯誤訊息:*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIViewController _loadViewFromNibNamed:bundle:] loaded the "SignupViewController" nib but the view outlet was not set.'
解決方式:跳這個訊息代表你在Xib的File's Owner的view沒有連上UI上的view。
- 錯誤訊息:
Thread : Crashed: com.apple.main-thread
0 libobjc.A.dylib 0x0000000195757bdc objc_msgSend + 28
解決方式:到Project -> Build Settings -> ENABLE_STRICT_OBJC_MSGSEND 將它設為NO。
- 錯誤訊息:Error Domain=NSURLErrorDomain Code=-1022 "The resource could not be loaded because the App Transport Security policy requires the use of a secure connection."
解決方式:Apple在iOS 9的更新訊息中提到預設為強制使用https當作api的網址。

但如果你必須要用http可以去Info.plist修改預設值。
1. 新增App Transport Security Settings欄位
2. 把欄位下的Allow Arbitrary Loads設為YES
或是把欄位下的Exception Domains加入你的網址
Event Kit Framework 匯入iOS行事曆
[轉自http://iosdevelopersnote.blogspot.tw/2010/09/ios-event-kit-framework.html]
iOS 4.0 可以充許開發者去存取存iPhone裡的行事曆,
和通訊錄相同的行事曆的整個是用Core Foundation架構起來的是C 而不是Objective-C
Core Foundation是C, Foundation是Objective-C
但是兩者之間有很方便的轉換方法,其實就是直接cast,這個又叫做Toll-Free bridge
比如CFStringRef和NSString *要轉換就直接寫
CFStringRef cfString = xxxxxx;
NSString * objString = (NSString *) cfString;
這樣就可以直接用objString來當成cfString的替身了
先介紹一下幾個重要的c structure在event kit 會用到的
CFGregorianDate : 標準的日曆表示法,含有年,月,日,時,分,秒。至於為什麼叫Gregorian 請參考
CFGregorianUnits : 表示一段時間,和CFGregorianDate有相同的結構,但沒有限制值的範圍。比如說在CFGregorianDate"時"的值不能超過24小時,但在CFGregorianUnits"時"的值就可以超過24小時,因為它代表的是一段時間
我們來直接來看一個按下去按鈕就新增自訂event的例子
-(IBAction) createEvent:(id)sender{
NSLog(@"launched");
EKEventStore * myEventStore = [[EKEventStore alloc] init];
EKEvent * myEvent = [EKEvent eventWithEventStore:myEventStore];
myEvent.title = @"Knowledage Convergence Meeting";
CFGregorianDate gregorianStartDate, gregorianEndDate;
CFGregorianUnits startUnits = {0, 0, 0, 1, 3, 0};
CFGregorianUnits endUnits = {0, 0, 0, 1, 5, 0};
CFTimeZoneRef timeZone = CFTimeZoneCopySystem(); gregorianStartDate = CFAbsoluteTimeGetGregorianDate( CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTimeGetCurrent(), timeZone, startUnits), timeZone);
gregorianStartDate.hour = 17;
gregorianStartDate.minute = 55;
gregorianStartDate.second = 10;
gregorianEndDate = CFAbsoluteTimeGetGregorianDate( CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTimeGetCurrent(), timeZone, endUnits), timeZone);
gregorianEndDate.hour = 17;
gregorianEndDate.minute = 55;
gregorianEndDate.second = 25;
NSDate* startDate = [NSDate dateWithTimeIntervalSinceReferenceDate:CFGregorianDateGetAbsoluteTime(gregorianStartDate, timeZone)];
NSDate* endDate = [NSDate dateWithTimeIntervalSinceReferenceDate:CFGregorianDateGetAbsoluteTime(gregorianEndDate, timeZone)];
CFRelease(timeZone);
myEvent.startDate = startDate;
myEvent.endDate = endDate;
myEvent.calendar = [myEventStore defaultCalendarForNewEvents];
EKAlarm *myAlarm = [EKAlarm alarmWithAbsoluteDate:startDate];
myEvent.alarms = [NSArray arrayWithObject:myAlarm];
NSError *theError = nil;
[myEventStore saveEvent:myEvent span:EKSpanThisEvent error:&theError];
NSLog(@"error is %@", theError);
}
這個流程主要就是產生自己的EKEvent, 藍色的property都是必要的,除了alarms之外,EKEvent又必需要和 EKEventStore結合,因為event實體是EKEventStore給的,event裡的calendar也是EKEventStore給的,而EKEventStore實體的產生就只是用alloc, init方式。 其中最麻煩的就是startDate和endDate,輾轉要從 CFGregorianDate 或是 CFGregorianUnits而來 單看是要從 CFAbsoluteTimeGetGregorianDate產生還是要從 CFAbsoluteTimeAddGregorianUnits產生,不過記得一點,產生 CFGregorianDate 的實體之後可以從他的field,year, month, day, hour, minute, second 來設定絕對的時間就如墨綠色部分所示。 EKAlarm 可有可無,它是先和NSDate結合,再一起被設定到EKEvent
EKEventStore * myEventStore = [[EKEventStore alloc] init];
EKEvent * myEvent = [EKEvent eventWithEventStore:myEventStore];
myEvent.title = @"Knowledage Convergence Meeting";
CFGregorianDate gregorianStartDate, gregorianEndDate;
CFGregorianUnits startUnits = {0, 0, 0, 1, 3, 0};
CFGregorianUnits endUnits = {0, 0, 0, 1, 5, 0};
CFTimeZoneRef timeZone = CFTimeZoneCopySystem(); gregorianStartDate = CFAbsoluteTimeGetGregorianDate( CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTimeGetCurrent(), timeZone, startUnits), timeZone);
gregorianStartDate.hour = 17;
gregorianStartDate.minute = 55;
gregorianStartDate.second = 10;
gregorianEndDate = CFAbsoluteTimeGetGregorianDate( CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTimeGetCurrent(), timeZone, endUnits), timeZone);
gregorianEndDate.hour = 17;
gregorianEndDate.minute = 55;
gregorianEndDate.second = 25;
NSDate* startDate = [NSDate dateWithTimeIntervalSinceReferenceDate:CFGregorianDateGetAbsoluteTime(gregorianStartDate, timeZone)];
NSDate* endDate = [NSDate dateWithTimeIntervalSinceReferenceDate:CFGregorianDateGetAbsoluteTime(gregorianEndDate, timeZone)];
CFRelease(timeZone);
myEvent.startDate = startDate;
myEvent.endDate = endDate;
myEvent.calendar = [myEventStore defaultCalendarForNewEvents];
EKAlarm *myAlarm = [EKAlarm alarmWithAbsoluteDate:startDate];
myEvent.alarms = [NSArray arrayWithObject:myAlarm];
NSError *theError = nil;
[myEventStore saveEvent:myEvent span:EKSpanThisEvent error:&theError];
NSLog(@"error is %@", theError);
}
這個流程主要就是產生自己的EKEvent, 藍色的property都是必要的,除了alarms之外,EKEvent又必需要和 EKEventStore結合,因為event實體是EKEventStore給的,event裡的calendar也是EKEventStore給的,而EKEventStore實體的產生就只是用alloc, init方式。 其中最麻煩的就是startDate和endDate,輾轉要從 CFGregorianDate 或是 CFGregorianUnits而來 單看是要從 CFAbsoluteTimeGetGregorianDate產生還是要從 CFAbsoluteTimeAddGregorianUnits產生,不過記得一點,產生 CFGregorianDate 的實體之後可以從他的field,year, month, day, hour, minute, second 來設定絕對的時間就如墨綠色部分所示。 EKAlarm 可有可無,它是先和NSDate結合,再一起被設定到EKEvent
訂閱:
文章 (Atom)
