2013年3月26日 星期二

Key-Value Observing機制

//這是一個簡單又好用的機制
//對你要觀察的物件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"]);
       
    }
 }

判斷是否為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

2013年3月18日 星期一

frame跟bound的差別

常遇到的錯誤訊息與解決方式


  • 錯誤訊息:Undefined symbols for architecture i386 error
遇到這個錯誤碼代表你Code中有使用到你尚未載入的framework,把該加入的framework加一加就可以compile過了

  • 錯誤訊息:Apple Mach-O Linker Error 
解決方式:Project ->Build Settings -> Build Active Architecture Only -> 設成YES


  • 錯誤訊息:linker command failed with exit code 1 
解決方式: 把 Valid Architectures 的值改為 armv7 : PROJECT --> Build Settings --> Architectures --> Valid Architectures 他的值本來是 armv7 armv7s (ios6.0下) 把armv7s 去掉即可 同樣的操作 TARGETS --> Build Settings --> Architectures --> Valid Architectures 做同樣的修改 後來發現發生這些錯誤是因為引用了EVENTKIT但沒有先匯入它


  • 錯誤訊息: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
解決方式:在你的storyboard中有些TableView的content屬性為Dynamic Prototypes,你卻拉了客製化的cell進去TableView中。或者是你把cell直接拉到UIView當中。看樣子iOS7以後對cell的階層定義的很嚴格。

  • 錯誤訊息: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
解決方式:在你重新安裝xcode之後,舊的專案的暫存檔會跟新的衝突,所以要先把暫存檔資料夾清空,打開你的終端機輸入
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

時間格式

在開發iOS程序時,有時候需要將時間格式調整成自己希望的格式,這個時候我們可以用NSDateFormatter類來處理。 例如:
//實例化一個NSDateFormatter對像
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
//設定時間格式,這裡可以設置成自己需要的格式
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
//用[NSDate date]可以獲取系統當前時間 NSString *currentDateStr = [dateFormatter stringFromDate:[NSDate date]];
//輸出格式為:2010-10-27 10:22:13 NSLog(@”%@”,currentDateStr);
 //alloc後對不使用的對像別忘了release [dateFormatter release];
//另一個blog NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
 [formatter setDateFormat:@"yyyy-MM-dd hh:mm:ss"];
 NSString *locationString=[formatter stringFromDate: [NSDate date]];
 //獲取當前時間作為productId NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"hhmmss"];
NSString *locationString=[formatter stringFromDate: [NSDate date]]; downloadInfo.productId = locationString; [formatter release];
/****************************************************************************** 函數名稱 : getDate 函數描述 : 獲取當前日期時間 輸入參數 : N/A 輸出參數 : N/A 返回值 : NSString 當前時間 備注 : ******************************************************************************/
-(NSString *)getDate {
 NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
 [formatter setDateFormat:@"yyyy-MM-dd EEEE HH:mm:ss a"];
NSString *locationString=[formatter stringFromDate: [NSDate date]];
 [formatter release]; return locationString;
}
 //大寫的H日期格式將默認為24小時制,小寫的h日期格式將默認為12小時
//不需要特別設置,只需要在dataFormat裡設置類似"yyyy-MMM-dd"這樣的格式就可以了
//日期格式如下:
//y 年 Year 1996; 96
//M 年中的月份 Month July; Jul; 07
//w 年中的周數 Number 27
//W 月份中的周數 Number 2
//D 年中的天數 Number 189
//d 月份中的天數 Number 10
//F 月份中的星期 Number 2
//E 星期中的天數 Text Tuesday; Tue
//a Am/pm 標記 Text PM //H 一天中的小時數(0-23) Number 0
//k 一天中的小時數(1-24) Number 24
//K am/pm 中的小時數(0-11) Number 0
//h am/pm 中的小時數(1-12) Number 12
//m 小時中的分鐘數 Number 30
//s 分鐘中的秒數 Number 55
//S 毫秒數 Number 978
//z 時區 General time zone Pacific Standard Time; PST; GMT-08:00
//Z 時區 RFC 822 time zone -0800 http://furnacedigital.blogspot.tw/2011/02/nsdateformatter.html 想要得知有關日期的參數就必須使用 NSDate,由於從 NSDate 得到的資料實在是太多太雜,因此就避免不了使用 NSDateFormatter 來格式化(正規化)這些資訊,接下來我們就來探討,到底有哪些格式化的參數是我們可以用的。 首先,先介紹一下如何從 NSDate 中取得日期的相關料,並進行所謂的格式化,第一步當然是宣告一個 NSDate 型態的變數,並取得當下的日期資料。 NSDate *date = [NSDate date]; 接下來就是宣告一個 NSDateFormatter 型態的變數,並做格式化的設定。 NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"輸入正規化參數 ex:YYYY-MM-d"];
最後,就是將我們所得到的日期資料進行格式化。
NSString *correctDate = [formatter stringFromDate:date];
完成上述步驟之後,字串 correctDate 就存放的格式化好的日期資料,下面我們將列出所有可能的格式化參數以供參考。 與時間相關 參數 代表意義 a AM/PM (上午/下午) K 0~11 有0時的12小時制 h 1~12 12小時制 H 0~23 有0時的24小时制 k 1~24 24小時制 m 0~59 分鐘 s 0~59 秒數 s 秒數的個位數 A 0~86399999 一天當中的第幾微秒 v~vvv 一般的GMT時區縮寫 vvvv 一般的GMT時區名稱 z~zzz 具體的GMT時區縮寫 zzzz 具體的GMT時區名稱 與日期相關 參數 代表意義 d 1~31 日期 D 1~366 一年的第幾天 e 1~7 一週的第幾天 c/cc 1~7 一週的第幾天,星期日為第一天 ccc 星期幾縮寫 E~EEE 星期幾縮寫 cccc 星期幾全名 EEEE 星期幾全名 F 1~5 每月第幾周,一周的第一天為周一 w 1~5 每月第幾周,一周的第一天為周日 w 1~53 一年的第幾周,從去年的最後一個周日算起,一周的第一天為周日 L/LL 1~12 第幾個月 M/MM 1~12 第幾個月 LLL 月份縮寫 MMM 月份縮寫 LLLL 月份全名 MMMM 月份全名 q/qq 1~4 第幾季 Q/QQ 1~4 第幾季 qqq 季度縮寫 QQQ 季度縮寫 qqqq 季度全名 QQQQ 季度全名 u 完整年份 y/yyyy 完整年份 Y/YYYY 完整年份,從星期天開始的第一周算起 yy/yyy 兩位數的年份 YY/YYY 兩位數的年份,從星期天開始的第一周算起 特殊用途 參數 代表意義 g Julian Day Number,從4713 BC一月一日算起 G~GGG BC/AD 西元前後縮寫 GGGG 西元前後全名 這裡只有列出幾個常用常用參數,還有一些小技巧並沒有詳述,例如今天是 15 號,輸入參數 d 或是 dd 皆可以得到數值 15,可是輸入 ddd 卻會得到數值 015,而輸入 dddd 又會得到 0015,其他的參數也可以此類推,有興趣的讀者們可以自行實驗。

2013年3月15日 星期五

暫存 EKEVENT

http://iosdevelopersnote.blogspot.tw/2010/09/ios-event-kit-framework.html

在自己的App中打開iOS中其他App的方式

//直接跳到iOS Settings (iOS 8以上限定)
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];

//How to check whether the app is installed in iOS device or not?
BOOL isAppInstalled=[[UIApplication sharedApplication] canOpenURL: [NSURL URLWithString:@"APP-URL-Scheme"]];
if(isAppInstalled) {
// app launching code
}else {
// app download prompting code
}

//Sending a Mail from iOS App
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: @mailto:krish@krish.codeworth.com]];

//Making a Phone Call from iOS app
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: @"tel:1-408-555-5555"]];

//Sending an SMS from the iOS App
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms:"]];
or
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: @"sms:1-408-555-1212"]];


//開apple maps
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: @"http://maps.apple.com/maps?q=taiwan"]];

//開google maps
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: @"http://maps.google.com/maps?q=taiwan"]];

//開maps加導航
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: @"http://maps.google.com/maps?daddr=San+Francisco,+CA&saddr=cupertino"]];


//Opening YouTube App
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: @"http://www.youtube.com/watch?v=VIDEO_IDENTIFIER"]];
or
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: @"http://www.youtube.com/v/VIDEO_IDENTIFIER"]];

//Opening iTunes App
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: @"http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewAlbum?i=156093464&id=156093462&s=143441"]];

//Opening App Store App
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"Copied iTunes Store URL"]];

//Opening iBooks App
NSString *stringURL = @”itms-books:”; NSURL *url = [NSURL URLWithString:stringURL]; [[UIApplication sharedApplication] openURL:url];

不知道Key卻想列出所有Dictionary內容的方式

for (id key in dictionary) {
NSLog(@"key: %@, value: %@", key, [dictionary objectForKey:key];
 }

2013年3月14日 星期四

建立navigationBar風格的button

//101是往回的箭頭 100跟102都是baritem的按鈕
UIButton *infoButton = [UIButton buttonWithType:101];
[infoButton setFrame:CGRectMake(10,10,infoButton.frame.size.width, infoButton.frame.size.height)];
[infoButton addTarget:self action:@selector(infoButtonTapped) forControlEvents:UIControlEventTouchUpInside];

一些心得好站

http://www.yifeiyang.net/category/embedded/iphone-embedded/know/
蠻多特殊技巧的

在TableViewCell的前後加入按鈕

//加在- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath裡

//加入按鈕在右邊的cell.accessoryView
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self action:@selector(tipAction:) forControlEvents:UIControlEventTouchDown];
button.tag=indexPath.row+1;
[button setTitle:@"Show View" forState:UIControlStateNormal];
button.frame = CGRectMake(20.0, 20.0, 60.0, 40.0);
cell.accessoryView = button;

//加入按鈕在左邊的cell.imageView
UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeInfoLight];
[infoButton setFrame:CGRectMake(10,10,infoButton.frame.size.width, infoButton.frame.size.height)];
[infoButton addTarget:self action:@selector(infoButtonTapped) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:infoButton];
[cell.imageView setImage:[UIImage imageNamed:@"info-button.png"]]; [cell.imageView setUserInteractionEnabled:YES];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(infoImageTapped:)];
[tap setNumberOfTapsRequired:1];
[cell.imageView setGestureRecognizers:[NSArray arrayWithObject:tap]];
[tap release];


//根據不同行的按鈕,利用tag做出不同反應
-(void)tipAction:(id)sender {
NSInteger tag= ((UIControl*)sender).tag; //為了讓compiler認出tag,先對sender參數轉型為UIControl
NSLog(@"%d",tag);
}

讓button變成自己的圖片形狀

UIButton *button = [[UIButton buttonWithType:UIButtonTypeCustom]];
UIImage *image = [UIImage imageNamed:@"xxx.png"];
[button setBackgroundImage:image forState:UIControlStateNormal];
圖片選張圓形的就可以了 如果在xib中拖出來的按鈕,就把Type設為custom,然後在BackImgae裡選張圓形圖片即可

XML格式的網路英文字典(可用來測試NSXMLParser)

http://fy.webxml.com.cn/webservices/EnglishChinese.asmx/Translator?wordkey=word

其中最後的word就是你想要查詢的單字


Code如下,還需要用Delegate
NSLog(@"beginto request webservice!!!!");
NSURL*url=[NSURLURLWithString:[NSStringstringWithFormat: @"http://fy.webxml.com.cn/webservices/EnglishChinese.asmx/Translator?wordkey=%@",ipAddress.text]];
// xmlElements=[[NSMutableArray alloc]init];
NSXMLParser*xml=[[NSXMLParseralloc] initWithContentsOfURL:url];
[xml setShouldProcessNamespaces:NO];
[xml setShouldReportNamespacePrefixes:NO];
[xml setShouldResolveExternalEntities:NO];
[xml setDelegate:self];
[xml parse];


另一種包成方法的方式
//1, 構建解析方法
-(void)parseXMLFile:(NSURL *)XMLURL //XMLURL为第一個文件的URL
{
NSXMLParser *eventParser = [[NSXMLParser alloc] initWithContentsOfURL:XMLURL];
[eventParser setDelegate:self]; //設置代理为本地
[eventParser parse]; //開始解析
NSLog(@"end Of parseXMLFile");
}


//2, 解析開始後,所有XML的內容由NSXMLParserDelegate處理
// 所以一定要注意在本地添加到文件頭
//在NSXMLParser在NSXMLParser讀到<p>的時候重寫一個標簽,原來的是XML中的,無法直接使用

//第一個代理方法:開始處理xml數據,它會把整個xml遍曆一遍,識別元素節點名稱
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqualToString:@"p"])
{
[htmlDataString appendFormat:@"<p>"];
needOrNot = YES; //我們需要<p>和</p>中間的內容,其餘的在end中設置NO
return;
}
}

//第二個代理方法:也就是得到文本節點裏存儲的信息數據
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if(needOrNot) { [htmlDataString appendString:string]; //如上,將需要的字段添加到得到的html結構String中
}
}

第三個代理方法:存儲從第二個代理方法中獲取到的信息
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{  
if ([elementName isEqualToString:@"p"])
{
[htmlDataString appendFormat:@""]; needOrNot = NO; //不需要的內容不允許上面的delegate去讀取到htmlDataString中
return;
}
}

- (void)parserDidEndDocument:(NSXMLParser *)parser
{
NSLog(htmlDataString); //在結束後輸出得到的html數據結構.
}

//另外:
//解析開始執行的方法
- (void)parserDidStartDocument:(NSXMLParser *)parser{
//todo something
}
//解析結束執行的方法
- (void)parserDidEndDocument:(NSXMLParser *)parser{
//todo something
}
//當出現解析錯誤的時候,會執行這個方法
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{
//todo something
}

2013年3月13日 星期三

Sqlite Sample(記得加入檔案要勾選Target)

把data.sqlite時,選Target
[NSBundle mainBundle]

//NSString* path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject ]; //用lastObjest
NSArray* path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *file=[path[0] stringByAppendingPathComponent:@"data.sqlite"];
if ([[NSFileManager defaultManager]fileExistsAtPath:file]==FALSE){
NSString* fromFile = [[NSBundle mainBundle]pathForResource:@"data" ofType:@"sqlite"];
[[NSFileManager defaultManager] copyItemAtPath:fromFile toPath:file error:nil];
}else{
NSLog(@"db exist");
}
if (sqlite3_open([file UTF8String], &database)!=SQLITE_OK) {
NSAssert1(0, @"Failed to open database with message '%s'.", sqlite3_errmsg(database));
}else{
NSLog(@"DB Opened");
}
NSString* Sql=@"SELECT * FROM Info";
const char *selectSql=[Sql UTF8String];
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, selectSql, -1, &statement, nil)==SQLITE_OK) { NSLog(@"select ok.");
while (sqlite3_step(statement)==SQLITE_ROW) {
int _id=sqlite3_column_int(statement, 0);
char *name=(char *)sqlite3_column_text(statement, 1);
NSLog(@"row>>id %i, name %s",_id,name);
}
}else{
NSLog(@"dont match");
}
sqlite3_finalize(statement);
sqlite3_close(database);

iOS 全域變數

我的做法是宣告一個Singleton做為Library
將常用的UserDefault做成getter跟setter:例如lounchCount放App被開啟幾次

在你的App中再開一個Class來繼承它使用,來寫這個程式需要的變數,如果要在App關掉還存在,就寫在userdefault,如果不是就直接宣告。例如,字串常數

2013年3月12日 星期二

使用本地通知

UILocalNotification *notification=[[UILocalNotification alloc] init];
if (notification!=nil) {
NSLog(@">> support local notification");
NSDate *now=[NSDate new];
notification.fireDate=[now addTimeInterval:10];
notification.timeZone=[NSTimeZone defaultTimeZone];
notification.alertBody=@"该去吃晚饭了!";
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}

至於顯示方式為banner或alert要視iOS的設定而定,無法在App中控制。

隱藏狀態列

[[UIApplication sharedApplication] setStatusBarHidden:YES animated:NO];

[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent];

2013年3月7日 星期四

如何修改tableview的group name

在tableview的datasource區段加入下面方法

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { NSString *sectionName;
switch (section) {
case 0: sectionName = NSLocalizedString(@"mySectionName", @"mySectionName");
break;
case 1: sectionName = NSLocalizedString(@"myOtherSectionName", @"myOtherSectionName"); break;
// ... default: sectionName = @"";
break; }
return sectionName;
}

另一種可以插入Label
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
//UIImage *myImage = [UIImage imageNamed:@"BUTTON.png"];
NSString *sectionName = nil;
switch (section) {
case 0: sectionName = [NSString stringWithFormat:@"Header Text 1"];
break;
case 1: sectionName = [NSString stringWithFormat:@"Header Text 2"];
break;
case 2: sectionName = [NSString stringWithFormat:@"Header Text 3"];
break;
}
UILabel *sectionHeader = [[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 40)] autorelease];
sectionHeader.backgroundColor = [UIColor clearColor];
sectionHeader.font = [UIFont boldSystemFontOfSize:18];
sectionHeader.textColor = [UIColor whiteColor];
sectionHeader.text = sectionName;
return sectionHeader;
}

如果上第二種方法,那要加入下面方法來控制section header的高度
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
if (section ==0) return 80.0f;
else
return 30.0f;
}
That's because the UITableView automatically sets the frame of the header view you provide to (0, y, table view width, header view height) y is the computed position of the view and header view height is the value returned by tableView:heightForHeaderInSection:

將TableViewCell的accessoryView換成Switch Button

在這- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

加入
if (indexPath.section == 1 && indexPath.row == 1) {
cell.textLabel.text = @"I Have A Switch";
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UISwitch *switchView = [[UISwitch alloc] initWithFrame:CGRectZero];
cell.accessoryView = switchView;
[switchView setOn:NO animated:NO];
[switchView addTarget:self action:@selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
[switchView release];
}

2013年3月6日 星期三

How to interact with UITableView in UIViewController?

Implement UITableViewDataSource and UITableViewDelegate protocols in your view controller .h file.

@interface ThirdViewController : UIViewController

Have an outlet for the UITableView.

@property (retain, nonatomic) IBOutlet UITableView *SMSTableView;

In viewDidLoad, set the tableView's datasource and delegate to self since the viewcontroller implements the protocol.

tableView.delegate = self;
tableView.dataSource = self;

Then, write the cellForRowAtIndexPath method.
It will be getting called.

#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { #warning Potentially incomplete method implementation.
// Return the number of sections.
return 3; }
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
#warning Incomplete method implementation.
// Return the number of rows in the section.
return 10; }
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
return cell; }

2013年3月5日 星期二

在viewController中使用delegate中宣告的變數的方法

在需要的類別內記得#import 'AppDelegate.h'
並在此類別.m加入
AppDelegate* delegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
使用上的話,就可以用 delegate.tmp_int 做存取

加入登入畫面的方法

In your AppDelegate, at the end of the application didFinishLaunchingWithOptions method you'll see this:
[window addSubview:tabcontroller.view];
[window makeKeyAndVisible];
return YES;

Simply initialize your login view controller and add it after the tabcontroller, like this: initialScreenViewController = [[InitialScreenViewController alloc] init];
self.window.rootViewController = self.tabBarController;
//[self.window addSubview:self.tabBarController.view];
//[self.window addSubview:viewController1.view];
[self.window makeKeyAndVisible];
[self.tabBarController presentViewController:viewController1 animated:NO completion:^{ ; }];
return YES;

In you login viewcontroller, after authenticating the user you can hide it like this:

AppDelegate* delegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
[delegate.tabBarController dismissViewControllerAnimated:YES completion:^{ ; }];

which allows you to show it again if you have a logout feature.

內嵌Kal Calender

一,下載Kal存在固定路徑ex: /Users/HouKang/Desktop/Kal/src

二,將src中的Kal.xcodeproj拖進xcode中自已的專案裡

三,若跳出複製的對話框,不要勾選 Copy items into destination group's folder
選擇Create folder references for any added folders按下add

四,在專案的Target中的Build Setting
1、把Search Paths的Header Search Paths加入剛剛存好的固定路徑ex: /Users/HouKang/Desktop/Kal/src
2、把Linking的Other Lingker Flags加上"-all_load"

五,在專案的Target中的Summary下的Linked Frameworks and Libraries加入libKal.a

六,在專案的Target中的Build Phases下的Target Dependencies加入Kal

七,把Kal.bundle拖出來到自已的專案中,
若跳出複製的對話框,不要勾選 Copy items into destination group's folder
選擇Create folder references for any added folders按下add


八,在VIEW DID LOAD中填入下列二行即可插入
KalViewController *calendar = [[KalViewController alloc] init]; [self.navigationController pushViewController:calendar animated:YES];


修改KAL畫面
一,在Classes下的KalGridView.m中的const CGSize kTileSize = { 46.f, 24.f };
可以設定基本儲存格大小。

二,在Classes下的KalTileView.m中的CGFloat fontSize = 24.f;
可以調整行事曆數字字體大小

使用SAMPLE
一,用之前要去Kal Project中的TARGETS中的Build Phases下的Link Binary With Libraries把libKal.a給移除

調整event marker的位置
一,在Class下的KalTileView.m中的
if (flags.marked) [markerImage drawInRect:CGRectMake(21.f, 5.f, 4.f, 5.f)];
可以調整marker在Tile中的位置

2013年3月4日 星期一

頁面折疊

做的很有 clear 的感覺:http://www.realmacsoftware.com/clear/
Paul Wu 也貼了兩個類clear的 iOS project :
https://github.com/mpospese/MPFoldTransition
https://github.com/mystcolor/jtgesturebasedtableviewdemo

好用的外插元件

KissXml——xml解析庫 相關教程:http://www.iteye.com/topic/625849 http://sencho.blog.163.com/blog/static/83056228201151743110540/ 很方便的一個xml解析器,支持Xpath查詢。 skpsmtpmessage——Quick SMTP郵件發送 svn checkout http://skpsmtpmessage.googlecode.com/svn/trunk/ skpsmtpmessage-read-only github: git clone https://github.com/kailoa/iphone-smtp.git 相關教程:http://disanji.net/2011/01/28/skpsmtpmessage-open-source-framework/ skpsmtpmessage 是由Skorpiostech, Inc.为我們帶來的一個SMTP協議的開源實現,使用Objective-c 實現,iOS系統的項目可以直接調用。 jsonframework——JSON支持 相關教程:http://blog.csdn.net/xiaoguan2008/article/details/6732683 它是一個開源框架,基於BSD協議發布。由於json-framework是開放源代碼的,當你需要使用它時你只需將json的源代碼加入到你的工程中。 ASIHttpRequest——HTTP Network庫 ASIHttpRequest庫極大的簡化了網络通 信,提供更先進的工具,例如文件上傳工具,重定向處理工具、驗證工具、等等。 MBProgressHUD——進展指示符庫 蘋果的應用程序一般都會用一種優雅的,半透明的進度顯示效果,不過這個API是不公開的,因此你要是用了,很可能被清除出AppStore。而 MBProgressHUD提供了一個替代方案,而且在用戶角度上,實現的效果根本看不出和官方程序有什麼差別。同時還提供了其他附加功能,比如虛擬進展 指示符,以及完成提示信息。整合到項目裏也很容易,這裏不細談了。 zxing——二維碼掃描庫 支持條形碼/二維碼掃描的圖形處理庫,這是一個java庫,在android上的功能比較完整。同時該庫也支持ios,但只能支持二位條形碼的掃描。 kal——iPhone日曆控件 一個類似於ios系統默認日曆開源日曆庫,支持添加事件,自定義日曆样式等功能。 Facebook iOS SDK——Facebook API類庫 大體來講就是iPhone上的Facebook login,完全支持Facebook Graph API和the older REST api。 shareKit——分享庫 相關demo:http://www.cocoachina.com/bbs/read.php?tid-71760.html 分享到開心,豆瓣,騰訊,新浪微博的api所用到的強大的分享庫。 SDWebImage——簡化網络圖片處理 用SDWebImage調用網站上的圖片,跟本地調用內置在應用包裏的圖片一样簡單。操作也很簡單。 GData client——iPhone上所有Google相關服務的類庫 名字就說明一切了。跟Google相關的,值得一提的是,這個項目很開放。有很多示例程序供下載。 CorePlot——2D圖形繪圖儀 CorePlot有很多解决方案將你的數據可視。同時也會提供各種迷人的圖形效果,比如棒狀圖、餅狀圖、線狀圖等等,在他們網站上也提供了大量的範例圖形,很多股票價格應用,遊戲分數,個人财務管理都在用。 Three20——類似於Facebook的優秀的UI庫 Three20類庫是Facebook自己做的,大而全是他最大的特色。把他整合到已有的項目中可能得費點周折,不過如果一開始你就用上了Three20,尤其是牽扯到很多web相關的項目的時候,你就能深刻體會到神馬叫给力了。 FMDatabase——SQLite的Objective-C封裝 是SQLite的C API對初學者來說實在太麻煩太瑣碎,難度太高。FMDB說穿了其實只是把C API包裝成簡單易用的Objective-C類。對於SQLite初學者來說,大大減低了上手的難度。有了FMDB,寫程式時只要專心在SQLite的語法上,而不用去理那堆有看沒有懂的C API,實在是件快樂的事情。