轉載於: http://blog.csdn.net/hengshujiyi/article/details/20943045php
文中有些方法可能已過期並不適用於如今的開發環境。
html
一、Search Bar 怎樣去掉背景的顏色(storyboard裏只能設置background顏色,但是發現clear Color沒法使用)。
其實在代碼裏仍是能夠設置的,那就是刪除背景view
[[self.searchBar.subviews objectAtIndex:0] removeFromSuperview]; java
二、NSDate 詳解:
1 字母 日期或時間元素 表示 示例 2 G Era 標誌符 Text AD 3 y 年 Year 1996 96 4 M 年中的月份 Month July; Jul; 07 5 w 年中的週數 Number 27 6 W 月份中的週數 Number 2 7 D 年中的天數 Number 189 8 d 月份中的天數 Number 10 9 F 月份中的星期 Number 2 10 E 星期中的天數 Text Tuesday; Tue 11 a Am/pm 標記 Text PM 12 H 一天中的小時數(0-23) Number 0 13 k 一天中的小時數(1-24) Number 24 14 K am/pm 中的小時數(0-11) Number 0 15 h am/pm 中的小時數(1-12) Number 12 16 m 小時中的分鐘數 Number 30 17 s 分鐘中的秒數 Number 55 18 S 毫秒數 Number 978 19 z 時區 General time zone Pacific Standard Time; PST; GMT-08:00 20 Z 時區 RFC 822 time zone -0800
[注意]在開發中,若是使用年月日,用NSDateFormatter setFormat :@"yyyy-MM-dd",若是是使用小時和分鐘,設置爲:"HH:mm",切記不要設置「HH-mm」,這樣會出錯的。
舉例:ios
1 //建立一個時間對象 2 NSData * date = [NSDate date]; 3 //打印時間 4 NSLog(@"today is %@",date); 5 6 //再獲取的時間date減去24小時的時間(昨天的這個時候) 7 NSDate *yesterday = [NSDate dateWithTimeIntervalSinceNow:-(24*60*60)]; 8 NSLog(@"yesterday is %@",yesterday);//打印昨天的時間 9 10 /*字符串換成時間*/ 11 //設置一個字符串的時間 12 NSString *datestring = [NSString stringWithFormat:@"1999-09-03"]; 13 //想要設置本身想要的格式,能夠用nsdateformatter這個類,這裏是初始化 14 NSDateFormatter * dm = [[NSDateFormatter alloc]init]; 15 //指定輸出的格式 這裏格式必須是和上面定義字符串的格式相同,不然輸出空 16 [dm setDateFormat:@"yyyy-MM-dd"]; 17 //把字符串的時間轉換成Date對象,用dateFromString方法 18 NSDate * newdate = [dm dateFromString:datestring]; 19 //輸出 20 NSLog(@"newdate is %@",newdate); 21 22 23 /*把時間轉換成字符串*/ 24 //把Date對象轉換成String對象 用stringFromDate方法 25 NSString * datestring2 = [dm stringFromDate:newdate]; 26 //打印 27 NSLog(@"datestring2 is %@",datestring2);
三、 若是使用 UTTabviewCell,設置其accessory樣式爲:Detail Disclosure ,就是在每個cell右邊設置一個detail button。若是這樣的操做是使用storyboard,進行的,它會要求你給每個你cell設置indentifier,而後你會在如下方法內設置 重用indentfier,別忘記加上一句話,不然編譯運行時可能會彈出: cell未實例化
四、在 開發項目中,有時有這樣的需求:運行程序,登錄界面是一個自由的ViewController,只是擺放幾個TextField和button,點擊後跳 轉到孩子選擇或其它選擇界面,點擊選項後進入咱們的主界面:這個時候,在登錄界面做跳轉時,會有好多的方法,若是使用storyboard,就比較方便 了,設置一個segue,跳轉代碼中:
[self PerformSegueWithIdentifier:@"targetViewController",self]; 就能夠了,但是我想實例化想要跳轉的控制器,而後設置某一屬性的值,這樣跳轉後控制器獲取那個屬性,就會獲得值了,但是這樣作會有一個問題:
主 界面控制器若是使用了navigatorViewController,而且是其RootViewController,等到在主界面設置功能,點擊某一 功能,想push到一個新頁面時,問題就來了,你會發現毫無反應,沒有報錯,只是segue沒法跳轉。後來終於找到緣由:就是我在登錄控制器跳轉時沒有使 用segue的方法,而是用代碼self.storyboard,加載一個新類,具體原理目前尚未搞明白,先把出問題的代碼記錄下來,回頭補之:
代碼這樣作,會致使其後沒法使用navigatorViewController作push跳轉 c++
五、 (1010更新)開發過程當中,咱們經過http請求,後臺返回json數據,而有時數據裏某一字段的值爲null~,而後咱們把此值賦值給 NSArray,NSdictionary,或是NSString,而後咱們會判斷此值爲null時,所作的處理,而一般慣性思惟判斷時咱們都會 寫:if(dict == nil)或是if(dict == Nil)或是if(dict == NULL)再或是if(dict isEqual nil),咱們發現,都很差用,根本沒有起到判斷的做用~後來我才發現,原來不能這樣來判斷。
簡單點說,就是當字典,數組爲null時,後臺打印的輸出結果是這樣:
而後,咱們須要在代碼判斷時利用[NSNull null]來判斷,具體如:
isEqual:[NSNull null] 就搞定了,nsarray也是一樣的道理。
控制檯打印:str=(null) 表明着 字符串或數組或字典是一個空指針,(而非空字符串)判斷的時候,直接用:
if(str == nil)就能夠了。以下圖所示:
而控制檯打印:str = <null>,表明着這是一個空字符串,賦值爲空,指針是存在的,只是內容爲空,這種判斷須要使用:
if(str is equal [NSNull null ]) ,由於在ios上,內容爲空不能簡單的判斷str==null(null 在ios上得用[NSNull null])
通常這種狀況是,服務器那邊是null,直接返回@"null"的字符串,這樣在ios這邊很差判斷,最好跟後臺溝通,若是遇到null值,返回@"",好作判斷 git
六、給uiview設置圓角樣式
只需在加載時,添加這樣的話就能夠了: 正則表達式
testView.layer.cornerRadius = 6;
testView.layer.masksToBounds = YES;
注意,須要 import <QuartzCore/QuartzCore.h> 導入,不然,不能識別cornerRadius和masksToBounds。
uiview設置背景圖片:算法
[theMainView setBackgroundColor: [UIColor colorWithPatternImage: [UIImage imageNamed: @"bg.png"]]];
imageName 緩存,下面方法不緩存編程
1 NSString *thePath = [[NSBundle mainBundle] pathForResource:@"default" ofType:@"jpeg"]; 2 UIImage *prodImg = [[UIImage alloc] initWithContentsOfFile:thePath"]; 3 controller.productImg.image = prodImg; 4 [prodImg release];
七、隱藏鍵盤的兩種方法
1-1Did End On Exit 調用下面事件當點擊鍵盤return得時候就會隱藏鍵盤json
1 - (IBAction)textFieldShouldReturn:(UITextField *)textField { 2 //[sender resignFirstResponder]; 3 if (textField == chi) { 4 [chi resignFirstResponder]; 5 double m=[chi.textdoubleValue]/3.003; 6 double f=m *3.2808; 7 meter.text=[[NSStringalloc] initWithFormat:@"%.4f",m]; 8 feet.text=[[NSStringalloc] initWithFormat:@"%.4f",f]; 9 } 10 if (textField == meter) { 11 [meter resignFirstResponder]; 13 } 14 if (textField == feet) { 15 [feet resignFirstResponder]; 16 } 17 }
1-2 點擊屏幕得時候隱藏鍵盤
1 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ 2 UITouch *touch=[[event allTouches] anyObject]; 3 if (touch.tapCount >=1) { 4 [chi resignFirstResponder]; 5 [meter resignFirstResponder]; 6 [feet resignFirstResponder]; 7 } 8 }
1-2 的方法至關於屏幕任何位置的點擊事件(除了各組件的點擊處)能夠在這個方法裏執行要隱藏或remove的view。
1-3 隱藏鍵盤 方法二
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ [self.view endEditing:YES]; }
八、UITextField密文顯示輸入內容:
只須要在TextField屬性中的Secure(安全的)勾選上或者設置 passWordTextField.secureTextEntry=YES; 就能夠了。顯示apple默認的密文顯示方式。
九、經過系統自帶的NSPredicate使用正則表達式。(在TextField中)
1 NSString *regex =[NSString stringWithFormat:@"^1(3[4-9]|5[012789]|8[2378]|47)\\d{8}$"]; 2 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex]; 3 BOOL isMatch = [predicate evaluateWithObject:editPhoneField.text];
十、項目設置應用程序顯示名稱:
1,在項目的Supporting Files下尋找infoPlist.strings文件,打開後會看到一片空白(英文默認是跟隨項目名稱顯示)。此時,能夠就地添加一句代 碼:CFBundleDisplayName="愛貝通";這樣的話,不管手機設置英文語言仍是中文語言,應用程序都會顯示設置的名稱。
2,爲了國際化而言,咱們最好建立一個chinese專有的infoPlist.strings文件。
如上圖所示,添加一箇中文的plist
而後打開添加代碼:
這個時候,大功告成。部署在模擬器或真機中吧,你的手機設置(中/英)文語言,它就會調用相應的配置文件。
十一、更改Xcode的缺省公司名
1 // testAppDelegate.m 2 // test 3 // 4 // Created by gaohf on 11-5-24. 5 // Copyright 2011 __MyCompanyName__. All rights reserved.
在終端中執行如下命令:
defaults write com.apple.Xcode PBXCustomTemplateMacroDefinitions '{"ORGANIZATIONNAME" = "COMPANY";}'
執行後效果
1 // testAppDelegate.m 2 // test 3 // 4 // Created by gaohf on 11-5-24. 5 // Copyright 2011 COMPANY. All rights reserved.
十二、在有uinavigation,uitoolbar的狀況下,如何添加一個全屏的 uiview (通常是做爲顯示一個進度框,任何區域沒法觸摸而使用)
只須要在要添加view時侯這樣寫:
[[UIApplication sharedApplication].keyWindow addSubview:waitingview];
這樣,直接把waitingview添加到了uiWindow上,而不是self.view上。再次運行,會發現屏幕所有區域都已經遮擋住了。
1三、 使用了storyboard,運行程序模擬器顯示黑屏,這是因爲,操做不當,獲取點擊了例如 navigationViewController屬性種的in init ViewController選項,而後重置了當前進入程序後的首界面,解決辦法就是選擇入口界面,屬性種從新勾選此選項。
StoryboardApp[8593:207] Failed to instantiate the default view controller for UIMainStoryboardFile 'MainStoryboard' - perhaps the designated entry point is not set?
StoryBoard中沒有一個view controller設置了Initial Scene。您須要選擇一個view conroller做爲story board的第一個界面:
1四、如何給uiNavigationBar 設置背景顏色或是自定義圖片?
在項目中添加以下代碼:
//設置背景顏色:
1 UIColor *itemcolor = [UIColor colorWithRed:100.0f/255.0f green:176.0f/255.0f blue:0.0f/255.0f alpha:0.3f]; 2 self.navigationController.navigationBar.tintColor = itemcolor;
//設置自定義的圖片:
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"navbg.png"] forBarMetrics:UIBarMetricsDefault];
5.0以上,api有了上面setBackgroundImage的方法,能夠直接設置,若是項目須要適配5.0如下版本的設備,最好加一個判讀,是否有此函數,有則設置,沒有就經過drawRect方法設置。
另外:設置背景圖片沒法匹配backButton或rightButtonItem,因此返回按鈕或右邊自定義的Bar button Item須要自行處理。
1五、如何給uiview設置背景圖片?
在storyboard或xib中,添加一個uiview,屬性設置欄通常都有設置背景顏色,樣式,透明度alpha,可是沒有提供設置image,只有在imageview中才有,因此,要想設置背景圖片,只能在代碼中設置,以下:
[leftNaviView setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"pabb_leftnaviview_bg.png"]]];
這樣,背景就能夠變成想要的圖片了。另外,設置大小:
[leftNaviView setFrame:CGRectMake(9, 60, 120, 250)];
效果圖:
1六、如何在項目用代碼打開AppStore軟件(也就是訪問appstore)
1 //如下是經過id打開此軟件的評價 2 //int m_appleID = 576337094; 3 //NSString *str = [NSString stringWithFormat: 4 //@"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=%d", 5 //m_appleID ]; 6 7 //如下是經過appstore連接到本身應用在商店的位置 8 NSString *url = [NSString stringWithFormat:@"http://itunes.apple.com/cn/app/huo-xing-she-xin-dian/id549425594?l=en&mt=8"]; 9 [[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]];
把以上代碼直接拷貝到想要實現點擊跳轉的操做方法內就能夠了,經過appID,隨意能夠經過appstore打開應用,直接用url就能夠連接到了。很簡單,通常都用在檢查更新的時候。
1七、如何代碼實現點擊http://www.kaka.com或400-800-400或message實現跳轉safari,phone或message?
只須要在相應的代碼中寫入:
一、調用 電話phone
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://4008008288"]];
二、調用自帶 瀏覽器 safari
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://www.abt.com"]];
三、調用 自帶mail
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"mailto://admin@abt.com"]];
四、調用 SMS
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms://800888"]];
5,跳轉到系統設置相關界面
1 [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"prefs:root=WIFI"]];
其中,發短信,發Email的功能只能填寫要發送的地址或號碼,沒法初始化發送內容,若是想實現內容的話,還須要更復雜一些,實現其各自的委託方法。
若須要傳遞內容能夠作以下操做:
1 //加入:MessageUI.framework 2 #import <MessageUI/MFMessageComposeViewController.h> 3 4 //實現代理:MFMessageComposeViewControllerDelegate 5 6 //調用sendSMS函數 7 //內容,收件人列表 8 - (void)sendSMS:(NSString *)bodyOfMessage recipientList:(NSArray *)recipients 9 { 11 MFMessageComposeViewController *controller = [[[MFMessageComposeViewController alloc] init] autorelease]; 13 if([MFMessageComposeViewController canSendText]) 15 { 17 controller.body = bodyOfMessage; 19 controller.recipients = recipients; 21 controller.messageComposeDelegate = self; 23 [self presentModalViewController:controller animated:YES]; 25 } 27 } 28 29 // 處理髮送完的響應結果 30 - (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result 31 { 32 [self dismissModalViewControllerAnimated:YES]; 34 if (result == MessageComposeResultCancelled) 35 NSLog(@"Message cancelled") 36 else if (result == MessageComposeResultSent) 37 NSLog(@"Message sent") 38 else 39 NSLog(@"Message failed") 40 }
發送郵件的爲:
1 //導入MFMailComposeViewController 2 #import <MessageUI/MFMailComposeViewController.h> 3 //實現代理:MFMailComposeViewControllerDelegate 4 5 //發送郵件 6 -(void)sendMail:(NSString *)subject content:(NSString *)content{ 7 MFMailComposeViewController *controller = [[[MFMailComposeViewController alloc] init] autorelease]; 9 if([MFMailComposeViewController canSendMail]) 11 { 13 [controller setSubject:subject]; 15 [controller setMessageBody:content isHTML:NO]; 17 controller.mailComposeDelegate = self; 19 [self presentModalViewController:controller animated:YES]; 21 } 22 } 23 24 //郵件完成處理 25 -(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error{ 27 [self dismissModalViewControllerAnimated:YES]; 29 if (result == MessageComposeResultCancelled) 30 NSLog(@"Message cancelled"); 31 else if (result == MessageComposeResultSent) 32 NSLog(@"Message sent"); 33 else 34 NSLog(@"Message failed"); 35 36 } 37
默認發送短信的界面爲英文的,解決辦法爲:在.xib 中的Localization添加一組chinese
1八、註冊設置應用程序訪問用戶手機發送推送消息,(彈出Alertview)
1 [[UIApplication sharedApplication] registerForRemoteNotificationTypes: 2 (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
1九、輕鬆自定義複選框按鈕
1 -(void)checkboxClick:(UIButton *)btn 2 { 3 btn.selected = !btn.selected; 4 } 5 7 - (void)viewDidLoad { 8 UIButton *checkbox = [UIButton buttonWithType:UIButtonTypeCustom]; 10 CGRect checkboxRect = CGRectMake(135,150,36,36); 11 [checkbox setFrame:checkboxRect]; 12 13 [checkbox setImage:[UIImage imageNamed:@"checkbox_off.png"] forState:UIControlStateNormal]; 14 [checkbox setImage:[UIImage imageNamed:@"checkbox_on.png"] forState:UIControlStateSelected]; 15 16 [checkbox addTarget:self action:@selector(checkboxClick:) forControlEvents:UIControlEventTouchUpInside]; 17 [self.view addSubview:checkbox]; 18 }
20、程序中獲取軟件的版本號和app名稱
應用程序的名稱和版本號等信息都保存在mainBundle的infoDictionary字典中,用下面代碼能夠取出來。
1 NSDictionary* infoDict =[[NSBundle mainBundle] infoDictionary]; 2 NSString* versionNum =[infoDict objectForKey:@"CFBundleVersion"];//版本名稱 3 NSString*appName =[infoDict objectForKey:@"CFBundleDisplayName"];//app名稱
1 <p style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; font-family: Menlo;"> 2 <span style="color: #703daa">NSString</span> 3 * versionShortString = [infoDict <span style="color: rgb(61, 29, 129);">objectForKey</span>: 4 <span style="color: #d12f1b">@"CFBundleShortVersionString"</span>];//標識應用程序發佈版本號 5 </p> 6 NSString*text =[NSString stringWithFormat:@"%@ %@",appName,versionNum, 7 <span style="font-family: Menlo; font-size: 11px; white-space: pre; ">versionShortString</span>];
此version 爲工程info下的Bundle version字段值:value能夠隨意定義。
CFBundleVersion,標識(發佈或未發佈)的內部版本號。這是一個單調增長的字符串,包括一個或多個時期分隔的整數。
CFBundleShortVersionString 標識應用程序的發佈版本號。該版本的版本號是三個時期分隔的整數組成的字符串。第一個整數表明重大修改的版本,如實現新的功能或重大變化的修訂。第二個整 數表示的修訂,實現較突出的特色。第三個整數表明維護版本。該鍵的值不一樣於「CFBundleVersion」標識。
圖片裏的 Version 對應的就是CFBundleShortVersionString (發佈版本號 如當前上架版本爲1.1.0 以後你更新的時候能夠改成1.1.1)
Build 對應的是 CFBundleVersion(內部標示,用以記錄開發版本的,每次更新的時候都須要比上一次高 如:當前版本是11 下一次就要大於11 好比 12,13 ....10000)
2一、如何使屏幕一直保持喚醒狀態?(就是不自動黑屏)
好比,若是咱們作一個播放視頻的功能時,想在播放的時候,不會自動進入屏保(黑屏)
只要在代碼里加入這一行:
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
固然,在想要黑屏的時候還須要把它設置爲NO(好比視頻播放完畢時),否則屏幕會在此軟件運行下一直亮着。
2二、一直以來的疑問:在Xcode中,有時候在類名稱後邊帶有M或C等標示,不知道爲什麼意。以下圖所示:
表示在版本控制中,自上一次提交以來,文件作了修改。貌似只有在帶有版本控制的項目代碼中才會顯示。
2三、有關ios上屏幕旋轉,view設置Frame的相關問題(ios5)。
屏幕旋轉一共有4個相關屬性(旋轉方向):
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
UIInterfaceOrientationPortrait
UIInterfaceOrientationPortraitUpsideDown
前兩個是橫屏時的狀態,後兩個是正常狀態(Portrait)和上下顛倒(UpsideDown)時的狀態。
【注意:Left和Right兩個左右模擬器旋轉時移動的方向正好是相反的,但移動後Home的方向,就以下圖所示】
具體見下圖:
其中涉及到兩個方法,在ViewController中默認會實現這個方法:
1 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 2 { 3 //除了不容許旋轉屏幕後:上下顛倒,其他方向都運行旋轉 4 //若是想都運行,能夠直接返回YES,或都不容許NO 5 return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 6 7 }
這個方法是聲明此ViewController所運行屏幕旋轉的方向,一共4種類型,所有容許返回YES,上圖所示除了不容許上下顛倒,其他均可 以。【注意,項目設置Supported Device Orientations 所支持的屏幕旋轉類型並不影響此方法的設置,也就是說,哪怕Support只支持Portrait,方法裏設置UpsideDown,此 ViewController也會實現上下顛倒旋轉的】
第二個方法,是咱們比較經常使用的,也就是在設備即將以某個方向旋轉以前,咱們在其狀態(方向)設置組件或view的Frame,bound,等須要改變的屬性時所用到的方法。
1 -(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{ 2 //屏幕旋轉到橫屏時 4 if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) { 5 myMapview.frame = CGRectMake(0,0,480, 300); 6 } 7 //屏幕旋轉到豎屏時 8 else{//== else if(UIInterfaceOrientationIsPortrait(toInterfaceOrientation)) 9 myMapview.frame = CGRectMake(0, 0, 320,460); 10 } 11 12 }
全部旋轉屏幕後須要改變組件尺寸屬性的設置均可以在這個方法裏面實現。
【注意,以上兩個方法,在最新的ios6貌似已經不提倡使用了,除非要適應舊設備,新的旋轉屏幕的相關方法能夠網絡搜索一下】
http://blog.csdn.net/zzfsuiye/article/details/8251060 IOS6屏幕旋轉詳解(自動旋轉、手動旋轉、兼容IOS6以前系統)
http://blog.csdn.net/huifeidexin_1/article/details/7826159 ios旋轉屏幕總結 詳細教程
http://blog.csdn.net/xiaoyun8822/article/details/8213738 Ios5(三)屏幕的旋轉和大小設置;
以上爲參考教程
2四、Xcode編譯警告和錯誤解決方法:
1 Application windows are expected to have a root view controller at the end of application launch解決方法:在ios5以上版本,應用程序加載時,須要一個 root view controller ,因此須要編寫代碼_rootViewController = [[RootViewController alloc] init];self.window.rootViewController = _rootViewController;此問題大可能是在Xib或Storyboard下操做ViewController時不當心鏈接 RootViewController 的底層View所致使的,檢查刪除沒有做用的view鏈接線,或是Clean (Command+Shift+K),再運行。
2五、如何設置視圖(view)在最上層?或是view1和view2交換?
情景再現:
咱們在storyboard的一個視圖裏添加了一個view1用做快捷功能導航;而後在對應的viewController裏 實例化了一個Mapview的地圖view2,大小是整個屏幕,這樣一來,就把咱們在storyboard中添加的view1覆蓋了,這個時候,咱們想把 view1在地圖view2的上面,該怎麼作?
簡而言之就是window中subview的交換。
首先經過:NSLog(@"subviews:%@",self.view.subviews); 這個咱們能夠看到當前下全部的subview(NSArray類型)以下圖所示:
能夠看到一共有3個view:UILabel 地圖view2,添加的view1
咱們如今要作的就是把後二者對調一下,因此在self.view 中尋找一下看有沒有replace相關的方法
就是這個方法,第一個參數是要進行調換的地圖view2,第二個參數是調換後顯示的view1。
[self.viewexchangeSubviewAtIndex:1 withSubviewAtIndex:2];
由於經過log打印,咱們已經知道Mapview在第一個下標的位置,view1在第二個下標的位置。
大功告成。記住這個方法:self.view exchangeSubviewAtIndex:withSubviewAtIndex:];
2六、如何隱藏UINavigationBar
有的時候,咱們的視圖使用了Navigation Controller ,可是主界面(rootviewcontroller)或其它push進入的界面 想使用一個全屏的view,就是說,不顯示頂部的navigationBar,這個時候,就須要咱們來隱藏了。
1 //隱藏NavigationBar 2 -(void) viewWillAppear:(BOOL)animated{ 3 [self.navigationControllersetNavigationBarHidden:YES animated:YES]; //設置隱藏 4 5 [super viewWillAppear:animated]; 6 } 7 8 -(void) viewWillDisappear:(BOOL)animated{ 9 [self.navigationControllersetNavigationBarHidden:NO animated:YES]; 10 11 [super viewWillDisappear:animated]; 12 }
2七、如何限制UITextField輸入長度(監聽textField文本變化的事件)
一、實現UITextFieldDelegate協議;
二、實現textField:shouldChangeCharactersInRange:replacementString:方法;
1 -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{ 2 int kMaxLength = 11; 3 4 NSInteger strLength = textField.text.length - range.length + string.length; 5 //輸入內容的長度 - textfield區域字符長度(通常=輸入字符長度)+替換的字符長度(通常爲0) 6 return (strLength <= kMaxLength); 7 8 }
如上代碼,若是咱們簡單的這樣寫: if(range.location<=11) return 或是 if (textfield.text.length>=11) 這樣雖然也能限制位數爲11位,可是若是經過放大鏡把光標切換到以前的位數後,你照樣能夠輸入,而且還會致使輸入11位後,鍵盤上的退格(X鍵)沒法使用,緣由是:咱們在location到達11位後,返回了NO,鍵盤沒法相應:添加,修改,刪除。這是很嚴重的。因此照着我上面的。
方法解讀:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
功能:
把textField中位置爲range的字符串替換爲string字符串;此函數在textField內容被修改時調用;
返回值:
YES,表示修改生效;NO,表示不作修改,textField的內容不變。
參數說明:
textField:響應UITextFieldDelegate協議的UITextField控件。
range: UITextField控件中光標選中的字符串,即被替換的字符串;
range.length爲0時,表示在位置range.location插入string。
string: 替換字符串; string.length爲0時,表示刪除。
2八、使用ios5.0之後的一個方法自定義table View Cell
1 UINib *nib = [UINib nibWithNibName:@"TvWeiboCell" bundle:nil]; 2 [tableView registerNib:nib forCellReuseIdentifier:CellIdentifier];
2九、iOS和iPad各app圖標和啓動頁尺寸。
iphone APP圖標尺寸:57X57 高清:114X114 單位:pixel 命名:無特殊要求,最好是,app_icon 高清的要加@2x
iphone 啓動頁尺寸:大小最好是320X460或320X480(至關於整個屏幕尺寸) 單位:pixel 命名:Default.png
iPad APP圖標尺寸:72X72 高清:144X144 單位:pixel 命名:
ipad 啓動頁尺寸:大小最好是768X1004或768X1024 單位:pixel 命名:Default-Portrait~ipad.png 高清:Default-Portrait@2x~ipad.png
30、如何用NSLog輸出NSRange,CGRect等結構體。
NSString 中的方法:
NSStringFromCGPoint
NSStringFromCGSize
NSStringFromCGRect
NSStringFromCGAffineTransform
NSStringFromUIEdgeInsets
如:NSLog(@"rect1: %@", NSStringFromCGRect(rect1));
3一、如何在navigationviewcontroller中,pop到以前不一樣的viewcontroller(push過的viewcontroller)?
如上圖所示,回退到界面2,很簡單: [self.navigationControllerpopViewControllerAnimated:YES]; 直接就回退到界面2了,但是咱們既不想回到rootviewcontroller,
也不想回到界面2,只想回到界面1,該如何作?
笨方法:在界面1要跳轉到界面2時,把本身self,set到界面2(前提界面2要設置一個id類型的屬性,用來存放界面1self,以此類推,當在界面3想退到界面1時,
[self.navigationControllerpopToViewController:controlleranimated:YES];
其實如今剛明白,一個很簡單的方法:
1 NSArray *viewControllers=[self.navigationController viewControllers]; 2 UIViewController *controller=[viewControllers objectAtIndex:1];
想起來navigation的機制了吧,每當咱們push到一個viewcontroller時,就會把這個viewcontroller的實例保存到nsarray裏,經過array能夠獲取到任何一個viewcontroller,
這不就解決問題了麼?
[self.navigationController popToViewController:controller animated:YES];
【注意】千萬不要在這個地方實例化 界面1 而後popToViewController,這種方法是不對的。
3二、self.navigationItem.backBarButtonItem 的title設置
新寫的App中須要使用UINavigationController對各個頁面進行導航,但因爲第一級頁面的title較長,在進入第二級頁面後返回按鈕leftButtonItem的title就會變得很長,
對NavigationBar空間佔用很大,並且不美觀,因而使用代碼對leftButtonItem的title文本進行修改,不管是設置self.navigationItem.leftBarButtonItem.title = @"返回";仍是self.navigationItem.backBarButtonItem.title = @"返回";都沒有效果,title文本始終不會發生變化。到網上亂搜一通後,獲得瞭如下解決方法,相對來講比較簡單,特記錄以下:
在第一級頁面的viewDidLoad方法中加入如下代碼:
1 UIBarButtonItem *temporaryBarButtonItem = [[UIBarButtonItem alloc] init]; 2 temporaryBarButtonItem.title =@"返回"; 3 self.navigationItem.backBarButtonItem = temporaryBarButtonItem; 4 [temporaryBarButtonItem release]; 5 // 也就是用一個新的按鈕在進行導航前將原來的返回按鈕替換掉就能夠了。
因此,經過這個咱們能夠明白,self.navigationItem.backBarButtonItem是在一級頁面設置的(提早設置下一個頁面的返回按鈕),而self.navigationItem.leftBarButtonItem/rightBarButton是在二級頁面設置的,(隨意設置本頁面的左右按鈕,左按鈕將替代系統的返回按鈕)
---------------------------------------------------------------------------------------------------------
通常一個程序中有一個UIWindow,一個UINavigationController,一個根UIViewController,多個子UIViewController。
UIWindow是整個可視界面的容器,裏面放置咱們看到的UIView。
UIView負責處理屏幕上一個矩形區域的繪製,UIView中還可包含子UIView。
UIWindow是UIView類的擴展,能夠看做是整個屏幕的根UIView。
UIViewController負責管理UIView的層次結構。能夠有多個UIViewController。
一個UIViewController中有一個頂部的UINavigationBar、一個根UIView,多個子UIView。
UINavigationBar中有一個UINavigationItem,UINavigationItem。
UINavigationController是用於構建分層應用程序的主要工具,它維護了一個UIViewController棧。
這個棧中必須有一個根UIViewController,其餘的UIViewController都是子UIViewController。
UINavigationItem表示UINavigationBar中的控件,好比左按鈕、中間標題、右按鈕。
UINavigationController會自動在當前子UIViewController的UINavigationBar左邊添加一個返回按鈕。
按鈕名稱是上一個UIViewController的標題。
---------------------------------------------------------------------------------------------------------
3三、self.navigationItem和self.navigationController.navigationItem的區別?
/**********************************************/
self.navigationItem
self.navigationController.navigationItem
self.navigationController.navigationBar
/**********************************************/
1, 不要混淆 self.navigationItem 和 self.navigationController.navigationItem ,
UINavigationItem 自己是用來 定製 ViewController本身在被導航過程當中的 appearence, navigationItem是UIViewController類關於UINavigationControllerItem類別的擴展:
@interface UIViewController (UINavigationControllerItem)
@property(nonatomic,readonly,retain)UINavigationItem * navigationItem;
...
@end
因此後者 是調用 VC的所在的導航控制器導航控制器本身本身做爲VC的 navigationItem,是導航的疊加。
2. UINavigationBar 繼承於 UIView,隸屬於整個 UINavigationController ,用來定義整個導航過程當中的導航欄的顏色等其餘數值,(相似於 self.tabBarController.tabBar UINavigationBar ,只須要一個設置通用的基本屬性),只能經過self.navigationController.navigationBar來訪問。
所以,定製於導航堆棧裏某個VC 的時候,通常經過self.navigationItem, 好比經常使用的self.navigationItem.leftBarButtonItem,self.navigationItem.rightButtonItem, 同時若是本身來定製導航欄的外觀的話,就要用到self.navigationItem.titleView,這個能夠直接用一個 CustomView 賦值於self.navigationItem.titleView便可。
此時,若是須要,就得本身畫導航過程當中的返回按鈕了。
3四、圖片模糊化處理
1
2 +(UIImage *)scale:(UIImage *)image toSize:(CGSize)size 3 { 4 UIGraphicsBeginImageContext(size); 5 [image drawInRect:CGRectMake(0, 0, size.width, size.height)]; 6 UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext(); 7 UIGraphicsEndImageContext(); 8 return scaledImage; 9 }
3五、NSString轉換大小寫的用法
iOS 6中NSString對象有些新的使用方法,可讓字符串轉變成所有大寫,所有小寫,或者每一個單詞首字母大寫。
代碼以下所示:
1 NSString *str = @"mobile developer tips"; 2 // Convert string to uppercase 3 NSString *upperStr = [str uppercaseStringWithLocale:[NSLocale currentLocale]]; 4 NSLog(@"upperStr: %@", upperStr); 5 6 // Convert string to caps 7 NSString *capStr = [upperStr capitalizedStringWithLocale:[NSLocale currentLocale]]; 8 NSLog(@"capStr: %@", capStr); 9 10 // Convert string to lowercase 11 NSString *lowerStr = [capStr lowercaseStringWithLocale:[NSLocale currentLocale]]; 12 NSLog(@"lowerStr: %@", lowerStr);
運行結果:
3六、真機調試:could not change executable permissions錯誤?
雖然更改了新demo的bundle identifier和以前的identifier同樣,可是真機上還保留着以前調試時的demo,因此新的工程若是使用一樣的identifier真機調試,須要先把機器上原來的demo刪除,再使用新工程調試。
3七、判斷iphone5屏幕的宏定義
1 #define iPhone5 ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 1136),
[[UIScreen mainScreen] currentMode].size) : NO)
在須要判斷屏幕尺寸的地方:
mymapview = [[BMKMapView alloc] initWithFrame:CGRectMake(0,0,320,460+(iPhone5?88:0))];
iphone5的View爲568,減去Nav(44)+任務欄(20),爲504,相比iphone4s及之前版本的480,減去Nav+任務欄,爲416,高出88(差異).
http://www.cnblogs.com/maxfong/archive/2012/10/04/2711379.html
3八、invalid deployment target for -stdlib=libc++ (requires iOS 5.0 or later)錯誤
選中項目--target---build settings 找到C++Standard Library 改爲:Compiler Default,再編譯就不會有錯誤了.
3九、如何調用系統聲音?【iphone 調用系統鈴聲與震動功能】
首先要在工程里加入Audio Toolbox framework這個庫,而後在須要調用的文件裏
#import <AudioToolbox/AudioToolbox.h>
最後在須要播放提示音的地方編寫以下代碼:
AudioServicesPlaySystemSound(1000);//新郵件消息提示
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); //震動
注:括號中爲系統聲音的id,詳見請參考如下網址http://iphonedevwiki.net/index.php/AudioServices。
http://blog.csdn.net/tskyfree/article/details/8096500
http://www.cnblogs.com/martin1009/archive/2012/06/14/2549473.html
http://www.cnblogs.com/chen1987lei/archive/2012/02/07/2341535.html
40、重複調用2次loadView和viewDidLoad
最好不要在UIViewController的loadView方法中改變狀態欄的可視性(好比狀態欄由顯示變爲隱藏、或者由隱藏變爲顯示),由於會致使重複調用2次loadView和viewDidLoad方法。
//錯誤代碼 1 - (void)loadView { 2 NSLog(@"loadView"); 3 // 隱藏狀態欄 4 [UIApplication sharedApplication].statusBarHidden = YES; 5 6 // .... 建立UIView 7 self.view = [[[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds] autorelease]; 8 self.view.backgroundColor = [UIColor grayColor]; 9 } 10 11 - (void)viewDidLoad { 12 [super viewDidLoad]; 13 NSLog(@"viewDidLoad"); 14 }
打印信息:
1 2013-05-14 00:51:36.152 test[2251:c07] loadView
2 2013-05-14 00:51:36.153 test[2251:c07] loadView
3 2013-05-14 00:51:36.153 test[2251:c07] viewDidLoad
4 2013-05-14 00:51:36.154 test[2251:c07] viewDidLoad
雖然運行效果是對的,可是系統連續調用了2次loadView和viewDidLoad方法,致使建立了2次UIView,形成了沒必要要的開銷。
緣由分析:
狀態欄由顯示變爲隱藏,意味着屏幕的可用高度變長了,UIViewController的UIView的高度也要從新調整,所以系統會從新調用loadView方法建立UIView,
建立完畢後再次調用viewDidLoad方法。
4一、點擊UIButton 沒法產生觸摸事件
若是在UIImageView中添加了一個按鈕,你會發如今默認狀況下這個按鈕是沒法被點擊的,須要設置UIImageView的userInteractionEnabled爲YES:
imageView.userInteractionEnabled = YES;
設置爲YES後,UIImageView內部的按鈕就能夠被點擊了
4二、如何啓動app時全屏顯示Default.png(圖片)?
大部分app在啓動過程當中全屏顯示一張背景圖片,好比新浪微博會顯示這張:
要想在iOS中實現這種效果,毫無壓力,很是地簡單,把須要全屏顯示的圖片命名爲Default.png便可,在iOS app啓動時默認會去加載並全屏顯示Default.png。
也能夠用其餘名稱來命名圖片,在Info.plist配置一下便可:
配置事後,app啓動時就會去加載並全屏顯示lufy.png
在默認狀況下,app顯示Default.png時並不是真正的"全屏顯示",由於頂部的狀態欄並無被隱藏,好比下面的效果:
大部分狀況下,咱們都想隱藏狀態欄,讓Default.png真正全屏顯示。
說到這裏,可能有人立刻就想到了一種辦法:在AppDelegate的application:didFinishLaunchingWithOptions:方法中添加以下代碼:
[UIApplication sharedApplication].statusBarHidden = YES;
我只能說你的思路是對的,但實際上達不到想要的效果,你會發現顯示Default.png時狀態欄仍是存在的,等Default.png顯示完畢後,狀態欄才被隱藏。
我先解釋下爲何這種方法不可行,其實緣由很簡單:
1> Default.png是在app啓動過程當中加載的,並非在app啓動完畢後再加載的
2> AppDelegate的application:didFinishLaunchingWithOptions:方法是在app啓動完畢後才調用的
下面說一下解決方案,在Info.plist中增長一個配置便可:
這裏的YES表示在app初始化(啓動)的時候就隱藏狀態欄。
固然,在Default.png顯示完畢後狀態欄仍是隱藏的。若是想從新顯示狀態欄,補上下面代碼便可:
[UIApplication sharedApplication].statusBarHidden = NO;
4三、使用ASIHTTPRequest保存cookies
假如個人APP,第一次啓動請求了登陸接口並獲得了Cookie,而後我把APP關了,下次啓動APP,我不請求登陸接口了,那上次獲得的Cookie就不存在了。若是須要,那麼2種方法,下次啓動app,自動登入,這樣能獲得服務器分配給你的cookier(這一種是最好的,由於session也會過時),還有一種是你把上次登入的時候,拿到的cookier存起來,而後下次啓動app的時候,手動給請求(ASIHTTP)添加cookie。
因此當第一次登陸成功後,能夠把cookie保存到CoreData,SQLite,UserDefault等,等到下次網絡請求時,讀取:
1 ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:UserInfoURL]; 2 [request setRequestMethod:@"POST"]; 3 [request addRequestHeader:@"Cookie" value:[NSString stringWithFormat:@"cookie=%@",[[NSUserDefaults standardUserDefaults] objectForKey:@"cookie"]]]; 4 //把cookie的值放進Header裏,這個cookie的值是一串很長的字符串。
4四、設置UITextField只有當有字符輸入後,鍵盤右下角的搜索/返回/done/等等鍵纔可使用
TextField設置這個屬性爲YES就能夠了,默認爲NO
searchField.enablesReturnKeyAutomatically =YES;
4五、相似QQ等IM軟件,長度和高度不一的聊天氣泡的圖片是如何作的?拉伸?
實際上是一個小氣泡png,而後拉伸中間部分,四個角不拉動,就是局部拉伸。ios自帶方法,四個角能夠不拉伸的,以下:
4六、UITableView中有多個UITextField時,被擋住的TextField如何實現自動向上彈起?
首先要實現TextField的delegate,在方法:
1 - (void)textFieldDidBeginEditing:(UITextField *)textField { 2 [self.tableView setContentOffset:CGPointMake(0, 70) animated:YES]; 4 }
這說明當開始輸入時,tableview在原來的基礎上向上擡起70個距離。多個UITextFiled能夠經過判斷來使用CGPoint的調整高度,我這寫的是70.
tableview的scrollEnabled屬性必定要是YES;要否則滾動不了了。
記得在return時復原tableview的位置:
1 - (BOOL)textFieldShouldReturn:(UITextField *)sender { 2 [self.tableView setContentOffset:CGPointMake(0, 0) animated:YES]; 3 return YES; 4 }
4七、ios如何在調試時,輕鬆找到程序在哪裏崩潰?
咱們給本身的工程添加一個全局的斷點:
一步步按上面圖完成操做。
再運行程序
自動就斷點到這裏來了,
log信息是:
2013-05-20 11:14:19.635 GestureRecognizer[1491:c07] -[__NSCFNumber isEqualToString:]: unrecognized selector sent to instance 0x7a88df0 2013-05-20 11:15:21.148 GestureRecognizer[1491:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[__NSCFNumber isEqualToString:]: unrecognized selector sent to instance 0x7a88df0'
這樣很簡單就能發現程序崩潰是由於value沒有 isEqualToString方法。若是沒加上面這個通用的斷點,那程序會直接斷點到main函數去。
4八、UIImageView 如何實現windows 桌面相似的背景壁紙屏幕(很小的圖片會顯示N多個)?
從UImageView上找ContentMode或clipToBounds是都無論用的,正確的辦法是,不用UImageView,使用UIView,而後設置backgroundColor屬性爲咱們的圖片,這樣的話自動會以屏幕的方式顯示。
1 UIView *gridView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 195)]; 2 gridView.backgroundColor = [UIColor colorWithPatternImage:BUNDLE_IMAGE(@"blue_grid")]; 3 [self.view addSubview:gridView]; 4 [gridView release];
下圖所示:(原圖是一個6X6的方格)
4九、UITableViewCell 的backgroundColor不起做用的問題?
在開發時,想要在tableview中的某一個Cell設置選中狀態,而且Cell的背景顏色是一個自定義顏色。
1 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 2 3 <span style="white-space:pre"> </span>//省略.... 5 cell.textLabel.font = [UIFont systemFontOfSize:6.0]; 6 cell.textLabel.text = @"13832207020"; 7 8 if (indexPath.row==0) { 10 [cell setBackgroundColor:[UIColor colorWithRed:100.0f/255.0f green:176.0f/255.0f blue:0.0f/255.0f alpha:1.0f]]; 11 } 12 else{ 13 [cell setBackgroundColor:[UIColor whiteColor]]; 14 } 15 16 return cell; 17 }
這樣的話,第1行cell就應該是咱們設置好的顏色,不過請注意,此方法在UITableViewStylePlain的風格下有效,在 UITableViewStyleGrouped的樣式下是無效的!這個跟tableview的backgroundView和backgroundColor是沒有關係的,我的猜測應該是在Grouped風格下,cell選中的顏色有系統的view遮罩,致使咱們設置的沒法顯示出來。
【補充】若是想在reload或init時設置tableview的某一cell爲 selected狀態,千萬不要使用cell setSelected:YESanimated:YES,使用tableview的方法:
1 NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0]; 2 terminalTableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone];
50、UITableViewCell選中時contentView中各組件的高亮狀態
使用系統或簡單自定義的UITableViewCell時,當選中某一行Cell後,除了背景顏色改變外,Cell上全部的組件(數據)好比UILabel,UIbutton等都被自動顯示成了其
Highlighted(高亮)狀態下的效果,(若是想顯示出效果,你的那些自定義的組件必需要設置高亮狀態,好比highlightedTextColor,UIControlStateHighlighted等),因此這一點須要特別注意,若是不想要系統的這個自動特效,有兩個解決辦法:
1,組件不設置highlighted下的屬性
2,若是自定義的Cell:
1 - (void)setSelected:(BOOL)selected animated:(BOOL)animated 2 { 4 [super setSelected:selected animated:animated]; 6 if (selected) { 7 //強制系統在UITableViewCell選中時SettingButton組件的高亮狀態爲NO 8 [(UIButton *)[self.contentView.subviews objectAtIndex:1] setHighlighted:NO]; 9 [settingBtn setImage:BUNDLE_IMAGE(@"accessory_sel") forState:UIControlStateNormal]; 10 } 11 else{ 12 [settingBtn setImage:BUNDLE_IMAGE(@"accessory_nor") forState:UIControlStateNormal]; 13 } 16 }
5一、IOS atomic與nonatomic,assign,copy與retain的定義和區別
atomic和nonatomic用來決定編譯器生成的getter和setter是否爲原子操做。
atomic
設置成員變量的@property屬性時,默認爲atomic,提供多線程安全。
在多線程環境下,原子操做是必要的,不然有可能引發錯誤的結果。加了atomic,setter函數會變成下面這樣:
{lock}
if (property != newValue) {
[property release];
property = [newValue retain];
}
{unlock}
nonatomic
禁止多線程,變量保護,提升性能。
atomic是Objc使用的一種線程保護技術,基本上來說,是防止在寫未完成的時候被另一個線程讀取,形成數據錯誤。而這種機制是耗費系統資源的,因此在iPhone這種小型設備上,若是沒有使用多線程間的通信編程,那麼nonatomic是一個很是好的選擇。
指出訪問器不是原子操做,而默認地,訪問器是原子操做。這也就是說,在多線程環境下,解析的訪問器提供一個對屬性的安全訪問,從獲取器獲得的返回值或者經過設置器設置的值能夠一次完成,即使是別的線程也正在對其進行訪問。若是你不指定 nonatomic ,在本身管理內存的環境中,解析的訪問器保留並自動釋放返回的值,若是指定了 nonatomic ,那麼訪問器只是簡單地返回這個值。
assign
對基礎數據類型 (NSInteger,CGFloat)和C數據類型(int, float, double, char)等等。
此標記說明設置器直接進行賦值,這也是默認值。在使用垃圾收集的應用程序中,若是你要一個屬性使用assign,且這個類符合NSCopying協 議,你就要明確指出這個標記,而不是簡單地使用默認值,不然的話,你將獲得一個編譯警告。這再次向編譯器說明你確實須要賦值,即便它是 可拷貝的。
retain
對其餘NSObject和其子類對參數進行release舊值,再retain新值
指定retain會在賦值時喚醒傳入值的retain消息。此屬性只能用於Objective-C對象類型,而不能用於Core Foundation對象。(緣由很明顯,retain會增長對象的引用計數,而基本數據類型或者Core Foundation對象都沒有引用計數——譯者注)。
注意: 把對象添加到數組中時,引用計數將增長對象的引用次數+1。
copy
對NSString 它指出,在賦值時使用傳入值的一份拷貝。拷貝工做由copy方法執行,此屬性只對那些實行了NSCopying協議的對象類型有效。更深刻的討論,請參考「複製」部分。
copy與retain:
Copy實際上是創建了一個相同的對象,而retain不是:
1.好比一個NSString 對象,地址爲0×1111 ,內容爲@」STR」,Copy 到另一個NSString 以後,地址爲0×2222 ,內容相同。
2.新的對象retain爲1 ,舊有對象沒有變化retain 到另一個NSString 以後,地址相同(創建一個指針,指針拷貝),內容固然相同,這個對象的retain值+1。
總結:retain 是指針拷貝,copy 是內容拷貝。
assign與retain:
1. 接觸過C,那麼假設你用malloc分配了一塊內存,而且把它的地址賦值給了指針a,後來你但願指針b也共享這塊內存,因而你又把a賦值給(assign)了b。此時a和b指向同一塊內存,請問當a再也不須要這塊內存,可否直接釋放它?答案是否認的,由於a並不知道b是否還在使用這塊內存,若是a釋放了,那麼b在使用這塊內存的時候會引發程序crash掉。
2. 瞭解到1中assign的問題,那麼如何解決?最簡單的一個方法就是使用引用計數(reference counting),仍是上面的那個例子,咱們給那塊內存設一個引用計數,當內存被分配而且賦值給a時,引用計數是1。當把a賦值給b時引用計數增長到2。這時若是a再也不使用這塊內存,它只須要把引用計數減1,代表本身再也不擁有這塊內存。b再也不使用這塊內存時也把引用計數減1。當引用計數變爲0的時候,表明該內存再也不被任何指針所引用,系統能夠把它直接釋放掉。
總結:上面兩點其實就是assign和retain的區別,assign就是直接賦值,從而可能引發1中的問題,當數據爲int, float等原生類型時,可使用assign。retain就如2中所述,使用了引用計數,retain引發引用計數加1, release引發引用計數減1,當引用計數爲0時,dealloc函數被調用,內存被回收。
5二、#pragma mark -#pragma mark Initialization含義
它們告訴Xcode編譯器,要在編輯器窗格頂部的方法和函數彈出菜單中將代碼分隔開;注意 #pragma mark – 的「-」後面不能有空格。若是你的標誌沒有出如今彈出菜單中,好比沒有分隔線出現,請在Xcode菜單 「Preferences..」中的 「Code Sense」選項取消選中」Sort listalphabetically」便可。
5三、自定義delegate變量聲明時使用assign仍是retain?
咱們經過發送消息給對象出發特定動做;對象發送某些變化的時候經過回調函數(callback)通知咱們。對象在特定事件發生的時候,就會調用對應的回調函數,觸發業務邏輯。回調函數經過所謂的代理(Delegation)來實現.
delegate使用方法:
@property (assign) <id>xxxDelegate delegate;
正確的使用方法是使用assign屬性而不是retain。之因此對於delegate這類對象使用assign而不是用retain是爲了防止循環retain(retain loop)
5四、給成員變量(屬性)賦值時使不使用self?
使用@property和@synthesize聲明一個成員變量,給其賦值是時要在前面加上"self.",以便調用成員變量的setmember方法。直接調用成員變量而且給其賦值:member=[NSString stringWithFormat:@」」];將不執行setmember 方法。
使用self調用成員變量而且給其賦值:self.member=[NSString stringWithFormat:@」」];將執行setmember方法。
5五、如何給UIbutton 同時設置圖片(Image)和文字(Title)以及它們的各類狀態?
1 startRangeButton = [UIButton buttonWithType:UIButtonTypeCustom]; 2 startRangeButton.frame = CGRectMake(85,componentOriginY, regionImage.size.width, 16); 3 [startRangeButton setBackgroundImage:regionImage forState:UIControlStateNormal]; 4 //還能夠設置其高亮狀態startRangeButton setBackgroundImage:regionImage forState:UIControlStateHighlighted]; 5 startRangeButton.titleLabel.font = [UIFont systemFontOfSize:7.0]; 6 [startRangeButton setTitle:@"2013-08-01 07:00" forState:UIControlStateNormal]; 7 [startRangeButton setTitleColor:COLOR(101, 199, 240, 1) forState:UIControlStateNormal]; 8 [startRangeButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
代碼中我設置button背景圖片爲本身定義的一個regionImage,並設置了button的title = 「2013-08-01 07:00」【注意,設置了背景圖片後,title只能這樣添加,以button.titleLabel.text方式添加會沒法顯示的】,而且設置了tiitle正常和高亮下文字顏色。
因此看到這裏,應該明白button.setBackgroundImage 和 set Image 的區別了吧,前者是能夠同時設置文字,後者是一旦設置了image,沒法再顯示文字。
普通:高亮:
5六、如何將NSDate類型轉化爲距離1970/1/1的毫秒差?
[formatter setDateFormat:@"yyyy-MM-dd HH:mm"]; 這種格式獲得的數值是精確到秒的,也就是說少1000,
可是嘗試[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];或SS大寫,或[formattersetDateFormat:@"yyyy-MM-dd HH:mm.ss.SSS"];都不起做用,最後才發現,原來是這樣
NSTimeInterval自己是個秒級別的double類型數值,小數點後面即毫秒數,*1000.0f便可獲得毫秒級別的時間差
1 //爲了兼容java版本,事件是從1970/1/1開始 2 3 -(NSDate *)getDateTimeFromMilliSeconds:(long long) miliSeconds 5 { 7 NSTimeInterval tempMilli = miliSeconds; 8 9 NSTimeInterval seconds = tempMilli/1000.0; 10 11 NSLog(@"seconds=%f",seconds); 12 13 return [NSDate dateWithTimeIntervalSince1970:seconds]; 15 } 16 17 18 19 //將NSDate類型的時間轉換爲NSInteger類型,從1970/1/1開始 20 21 -(long long)getDateTimeTOMilliSeconds:(NSDate *)datetime 23 { 25 NSTimeInterval interval = [datetime timeIntervalSince1970]; 26 27 NSLog(@"interval=%f",interval); 28 29 long long totalMilliseconds = interval*1000 ; 30 31 NSLog(@"totalMilliseconds=%llu",totalMilliseconds); 32 33 return totalMilliseconds; 35 }
也就是說,計算結果再本身乘以1000就能夠了
1 NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 2 [formatter setDateFormat:@"yyyy-MM-dd HH:mm"]; 3 4 NSDate *sDate = [formatter dateFromString:startRangeButton.titleLabel.text]; 5 NSDate *eDate = [formatter dateFromString:endRangeButton.titleLabel.text]; 6 NSTimeInterval sinterval = [sDate timeIntervalSince1970]; 7 long long start = sinterval*1000; 8 NSTimeInterval einterval = [eDate timeIntervalSince1970]; 9 long long end = einterval*1000; 10 [mConnectionHelper doTrack:mobile startTime:start endTime:end];
5七、ios中的全局靜態變量
Objective-C 支持全局變量
主要有兩種實現方式:
(1)第一種和C/C++中的同樣, 使用"extern"關鍵詞;
(2)另一種就是使用單例實現。
(好比咱們常常會把一個變量放在AppDelegate裏面做爲全局變量來訪問, 其中AppDelegate就是一個單例類)
在Objective-C中如何實現像C++中那樣的靜態成員變量呢?
你須要作的是在一個類A的implementation(.m或者.mm)文件中定義一個static變量,而後爲A類定義靜態成員函數(class method,也就是類方法)來操做該變量。
1 //example.h 2 @interface Example : NSObject { 3 4 } 5 - (id)init; 6 +(int)instanceCount; 7 @end
1 //example.m 2 #import "example.h" 3 static int count; 4 @implementation Example 5 -(id)init{ 6 self = [super init]; 7 if(nil!=self){ 8 count+=1; 9 } 10 return self; 11 } 12 +(int)instanceCount{ 13 return count; 14 } 15 @end
上面的例子中你就能夠經過[Example instanceCount]對靜態變量count進行訪問,無須建立實例。
警告: static 寫在interface外面編譯是沒有錯誤的,可是編譯器會報警告,這麼說這樣的寫法是不被編輯器承認的。
錯誤:static 寫在interface裏面會直接報錯,顯然這樣的語法是不被承認的。
static關鍵字聲明的變量必須放在implementation外面,或者方法中,若是不爲它賦值默認爲0,
它只在程序開機初始化一次。
5八、如何使用 NSNotificationCenter 在viewcontroller之間進行傳值?
簡單點的來,兩個界面間傳值,直接上代碼了:
sendViewcontroller.m
1 //SettingViewController :接受值的viewcontroller 2 SettingViewController *setting = [[SettingViewController alloc] init]; 3 [[NSNotificationCenter defaultCenter] addObserver:setting selector:@selector(received:) name:@"msetting" object:nil]; 4 NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:@"user",@"type", nil]; 5 6 [[NSNotificationCenter defaultCenter] postNotificationName:@"msetting" object:dict]; 7 [self.navigationController pushViewController:setting animated:YES]; 8 9 [setting release]; 10 SettingViewController.m(接收值的viewcontroller)
1 -(void)received:(NSNotification *)notification{ 2 3 id data = [notification object]; 4 NSLog(@"received data: %@",data); 5 }
這樣就實現了基本的使用,跟delegate相似,注意 addObserver時,須要寫目標viewcontroller的實例,而不是self。
5九、Thread EXC_BAD_ACCESS : objc_retain, objc_getProperty 崩潰錯誤
如上圖所示,遇到這個錯誤,從字面的意思咱們大體能猜到,是有屬性已經被release掉了,可是咱們又使用它了,因此,一部一部排查把,必定有某個地方的屬性提早被release掉了,本身手動管理內存就會有這樣的困惱,代碼不少,不想去找,必定要有耐心,找的過程還能夠學到不少知識。
如上圖,這個就是我找到的緣由所在,unarchiver release掉了,而咱們在其它的類中想使用location的屬性。
60、MAC 終端(bash)svn命令不識別 command not found
在mac os 10.8中,svn Command line tools是沒有自動安裝的,這樣的話,svn 命令行就會失效,解決辦法:
1.打開xcode偏好設置(comand+,)-->"Download" -->Components:
2.點擊「Command line tools」下載,下載完成以後安裝。
3.安裝完成以後,打開終端,輸入「svn help」,若是出現以下所示,說明命令行工具安裝好了。
6一、ios MapKit 判斷座標是否在MapView顯示範圍內
1 CLLocationDegrees leftDegrees = mapView.region.center.longitude –(mapView.region.span.longitudeDelta / 2.0); 2 CLLocationDegrees rightDegrees = mapView.region.center.longitude +(mapView.region.span.longitudeDelta / 2.0); 3 CLLocationDegrees bottomDegrees = mapView.region.center.latitude –(mapView.region.span.latitudeDelta / 2.0); 4 CLLocationDegrees topDegrees = self.region.center.latitude +(mapView.region.span.latitudeDelta / 2.0); 5 if (leftDegrees > rightDegrees) { // Int'l Date Line in View 6 leftDegrees = -180.0 - leftDegrees; 7 if (coords.longitude > 0) // coords to West of Date Line 8 coords.longitude = -180.0 - coords.longitude; 9 } 10 If (leftDegrees <= coords.longitude && coords.longitude <= rightDegrees && bottomDegrees <= coords.latitude && coords.latitude <= topDegrees) { 11 // 座標在範圍內 12 }
6二、在App圖標上顯示數字徽標
IOS7 :
1 UIApplication *app = [UIApplication sharedApplication]; 2 3 // 應用程序右上角數字 4 app.applicationIconBadgeNumber = 99;
上面的代碼能夠搞定
IOS8:
iOS8中設置application badge value 會拋錯:Attempting to badge the application icon but haven't received permission from the user to badge the
緣由是由於在ios8中,設置應用的application badge value須要獲得用戶的許可。使用以下方法諮詢用戶是否許可應用設置application badge value
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
在這以前要判斷系統是否爲iOS8的系統,不然8以前的系統會報錯。
1 UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil]; 2 3 [[UIApplication sharedApplication] registerUserNotificationSettings:settings]; 4 5 UIApplication *app = [UIApplication sharedApplication]; 6 // 應用程序右上角數字 7 app.applicationIconBadgeNumber = 10;
注意:清除數字請將數字設置爲 0
1-2設置標籤欄按鈕顯示數字圖標
1 UIViewController *second=[SecondViewController new]; 2 UITabBarItem *item=[[UITabBarItem alloc]initWithTitle:@"支付" image:[UIImage imageNamed:@"008"] selectedImage:[UIImage imageNamed:@"002"]]; 3 second.tabBarItem=item; 4 item.badgeValue=@"20";
效果如圖
6三、如何獲取手機硬件信息?
經過使用UIDevice:
[[UIDevice currentDevice] systemName];
[[UIDevice currentDevice] systemVersion];//os version
[[UIDevice currentDevice] uniqueIdentifier];
[[UIDevice currentDevice] model];
[[UIDevice currentDevice] name];
真機上結果:
System Name: iPhone OS
System Version: 4.2.1
Unique ID: 9b5ded78d5fa0ac96250f8b4af0e46f40b96ea6d
Model: iPhone
Name: 「wwk」的 iPhone
模擬器上結果:
System Name: iPhone OS
System Version: 4.2
Unique ID: 21FFE0FF-429B-5D0B-96D2-EADCA3203260
Model: iPhone Simulator
Name: iPhone Simulator
uniqueIdentifier:iPhone經過,向幾個硬件標識符和設備序列號應用內部散列算法,而生成這一標識符。
http://blog.csdn.net/qiwancong/article/details/7914923 參考
6四、設置隱藏頭部狀態欄(電池圖標)
1-1 設置狀態 如圖
1-2添加代碼:
1 //隱藏狀態欄 2 [[UIApplication sharedApplication]setStatusBarHidden:YES];
實現效果 如圖
6五、根據App版本號來判斷App開啓時是否進入引導頁
#define __kFirstVersion @"kFirstVersion"
1 //根據App版本號來判斷App開啓時是否進入引導頁 2 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 3 4 //1.獲取一個狀態:是否已經進入過主界面 5 // BOOL b = [[[NSUserDefaults standardUserDefaults]valueForKey:__kFirst] boolValue]; 6 7 //獲取到當前的版本 8 NSString *key = (NSString *)kCFBundleVersionKey; 9 NSString *version = [NSBundle mainBundle].infoDictionary[key]; 10 11 //獲取到以前的版本 12 NSString *lastVersion = [[NSUserDefaults standardUserDefaults]valueForKey:__kFirstVersion]; 13 14 //2.若是沒有進入過主界面,則進入引導頁 15 //若是兩個版本號相同,則進入主界面,不然進入引導頁 16 if (![lastVersion isEqualToString:version]) { 18 ViewController *vc = [[ViewController alloc]init]; 20 [vc setCallback:^{ 21 [self startApp]; 22 [[NSUserDefaults standardUserDefaults]setValue:version forKey:__kFirstVersion]; 23 [[NSUserDefaults standardUserDefaults]synchronize]; 24 }]; 26 self.window.rootViewController = vc; 27 } 28 //3.若是已經進入過主界面,則直接進入主界面 29 else 30 { 31 [self startApp]; 32 } 33 return YES; 34 } 35 36 37 -(void)startApp 38 { 39 self.window.rootViewController = [[UINavigationController alloc]initWithRootViewController:[RootViewController new]]; 40 }
6六、根據字體和文字來計算 UILable 的長度和大小
1 NSString *theText = @"Texting"; 2 3 UIFont *font = [UIFont fontWithName:@"HelveticaNeue" size:18.0f]; 4 5 CGSize theStringSize = [theText sizeWithFont:font constrainedToSize:theLabel.frame.size 6 lineBreakMode:theLabel.lineBreakMode]; 7 8 theLable.frame= CGRectMake(theLable.frame.origin.x, 9 theLable.frame.origin.y,theStringSize.width,theStringSize.height); 10 11 theLable.text= theText;
6七、圖解 imagView 的 UIContentMode的顯示方式 以下圖
6八、解決view的縮放的時候,layer.border.width(圓角邊框)隨着view的放大時會出現鋸齒化的問題。
self.layer.allowsEdgeAntialiasing = YES;