提示:因爲水平有限,如發現有疑問或錯誤的地方請絕不客氣的提出、討論,我會在第一時間回覆,感謝在先
html
0.注意APi可以使用範圍ios
重要的事情說三遍 注意API 可以使用範圍api
重要的事情說三遍 注意API 可以使用範圍app
1.塊的反向使用less
已知 :aVC,aVC.searchBar ; bVC,bVC.block
aVC addChildVC:bVC
searchBar代理方法:ide
searchBarBeginSearch{ bVC.block(); };函數
2.AVAudioPlayeroop
播放界面和player控制邏輯分開.佈局
初始化方法中路徑轉換成百分比的形式測試
parse 和stop都是中止播放.可是有區別的
(void)pause; / pauses playback, but remains ready to play. /
(void)stop; / stops playback. no longer ready to play. /
NSString* songPath = [[NSBundle mainBundle]pathForResource:self.songs.firstObject ofType:@"mp3"]; //C函數把songPath進行URL轉換.(資源含有中文會報錯) songPath = StePercentEscapedStringFromString(songPath); NSURL* songUrl = [NSURL URLWithString:songPath]; NSError* error; self.player = [[AVAudioPlayer alloc]initWithContentsOfURL:songUrl error:&error]; if (error) { NSLog(@"error:%@",error.localizedDescription); return; } if (self.player) { //初始化後,prepareToPlay前,若是若是須要調整播放速率,須要打開enableRate開關 //To enable adjustable playback rate for an audio player, set this property to YES after you initialize the player and before you call the prepareToPlay instance method for the player. self.player.enableRate = YES; self.player.numberOfLoops = 0; [self.player prepareToPlay]; }
3.ViewController.h文件中的屬性沒法賦值.
從XIB中拉出的組件,若是在建立的時候用這種方式:VC.label.text = @"XX";有可能賦值失敗;緣由:執行 VC.label.text = @"XXX"時候,label尚未從Xib中建立好; 能夠調用此方法強制加載控件:
-(void)loadViewIfNeeded NS_AVAILABLE_IOS(9_0); // Loads the view controller's view if it has not already been set.
也能夠給VC添加另外的屬性,做爲中間間使用,在ViewDidLoad中給IBOut組件賦值.
因爲初始化時書寫順序有問題,形成VC屬性沒法賦值
UIViewController *vc = [[UIViewController alloc] init]; //在這裏配置View可能過早致使ViewDidLoad方法執行;然而在ViewDidLoad 中使用userModel時爲空;(把View的配置寫在最後就能夠了) vc.view.frame = self.view.bounds; UserModel* model = [UserModel new]; model.account = @"account"; vc.model = model; [self addChildViewController:vc]; [self.view addSubview:vc.view];
4.判斷系統版本
4.1宏定義
#define SystemVersion [[[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"."][0] intValue] //只是提取主版本號
4.2使用NSFoundationVersionNumber來判斷
if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_9_x_Max){ NSLog(@"systemVersion >=10.0.0"); }
4.3使用UIProcessInfo
//對NSOperatingSystemVersion進行封裝,使用的時候寫在頭文件便可 NSOperatingSystemVersion SteOperationMake(NSInteger majorVersion,NSInteger minorVersion,NSInteger patchVersion){ NSOperatingSystemVersion systemVersion ={majorVersion,minorVersion,patchVersion}; return systemVersion; }
//使用NSProcessInfo類能夠獲取關於當前進程的信息.這裏主要獲取關於系統版本的信息。 NSProcessInfo* info = [NSProcessInfo processInfo]; /* typedef struct { NSInteger majorVersion;(主版本) NSInteger minorVersion;(次版本) NSInteger patchVersion;(修訂版本) } NSOperatingSystemVersion; NSOperatingSystemVersion 是結構體類型. */ NSLog(@"%ld %ld %ld", info.operatingSystemVersion.majorVersion,info.operatingSystemVersion.minorVersion,info.operatingSystemVersion.patchVersion); //10 2 0 基於當前手機的測試數據 NSLog(@"%@", info.operatingSystemVersionString); //Version 10.2 (Build 14C92) 基於當前手機的測試數據 NSOperatingSystemVersion systemVersion; systemVersion.majorVersion = {9,0,0}; //這裏也可使用上面封裝的SteOperationMake(9, 0, 0); //Returns a Boolean value indicating whether the version of the operating system on which the process is executing is the same or later than the given version. NSLog(@"%d",[info isOperatingSystemAtLeastVersion:systemVersion]); //當前版本是否大於等於9.0
4.4 也可使用 someClass.class 或者 respondsToSelector 進行判斷
//使用respondsToSelector有必定風險:好比有一個方法在低版本中是私有方法. //在高的系統版本中這個方法又被公開了,這中狀況下是有被拒的危險的 //@property (readonly, copy) NSString *localizedUppercaseString NS_AVAILABLE(10_11, 9_0); if ([@"" respondsToSelector:@selector(localizedUppercaseString)]){ NSLog(@"判斷是否響應某個方法!"); } //UIStackView: NS_CLASS_AVAILABLE_IOS(9_0) if ([UIStackView class]) { NSLog(@"能夠建立StackView"); } //建議使用這種方法 if (NSClassFromString(@"UIStackView")) { NSLog(@"能夠建立StackView"); } //對於與硬件相關類可使用類提供的詢問方法進行測試 好比:UIImagePickerController + (BOOL)isSourceTypeAvailable:(UIImagePickerControllerSourceType)sourceType; //枚舉值 typedef NS_ENUM(NSInteger, UIImagePickerControllerSourceType) { UIImagePickerControllerSourceTypePhotoLibrary, UIImagePickerControllerSourceTypeCamera, UIImagePickerControllerSourceTypeSavedPhotosAlbum }
5.SCrollView相關概念
5.1 contentOffset:The point at which the origin of the content view is offset from the origin of the scroll view
5.2 contentSize:The size of the content view(可視內容)
5.3 contentInsert:The distance that the content view is inset from the enclosing scroll view
e.g.: scrollView frame = (0 20; 320 548) contentSize: {320, 600} //設置contentInset會觸發scrollViewDidScroll方法執行 偏移量爲(0,-70) self.scrollView.contentInset = UIEdgeInsetsMake(70, 0, 70, 0); //手指在0-70範圍內移動時候,scrollView是能夠移動的 //scrollView中止滑動時候偏移量:-70,600-548+70 //當即contentOffSet 與 contentInset 區別
5.4 -canCancelContentTouches(method): A Boolean value that controls whether touches in the content view always lead to tracking(一個用來控制ContentView的觸摸事件,是否老是被追蹤的布爾值)
Discuss: If the value of this property is YES and a view in the content has begun tracking a finger touching it, and if the user drags the finger enough to initiate a scroll, the view receives a touchesCancelled:withEvent: message and the scroll view handles the touch as a scroll. If the value of this property is NO, the scroll view does not scroll regardless of finger movement once the content view starts tracking.(翻譯:若是布爾值爲YES,而且ContentView手指的觸摸事件已經被追蹤,用戶拖動ContentView足夠長觸發ScrollView開始滑動,ContentView會收到touchesCancelled:withEvent: 消息,與此同時scrollView把觸摸視爲滑動;若是屬性值爲NO,scrollView是不會滑動的,當content開始追蹤就忽略手指的移動,簡而言之:若是屬性爲NO,scrollVie不會滾動)
5.5 delaysContentTouches: If the value of this property is YES, the scroll view delays handling the touch-down gesture until it can determine if scrolling is the intent. If the value is NO , the scroll view immediately calls touchesShouldBegin:withEvent:inContentView:. The default value is YES.
5.6工做原理:
Because a scroll view has no scroll bars, it must know whether a touch signals an intent to scroll versus an intent to track a subview in the content. To make this determination, it temporarily intercepts a touch-down event by starting a timer and, before the timer fires, seeing if the touching finger makes any movement. If the timer fires without a significant change in position, the scroll view sends tracking events to the touched subview of the content view. If the user then drags their finger far enough before the timer elapses, the scroll view cancels any tracking in the subview and performs the scrolling itself. Subclasses can override the touchesShouldBegin:withEvent:inContentView:, pagingEnabled, and touchesShouldCancelInContentView: methods (which are called by the scroll view) to affect how the scroll view handles scrolling gestures.
參考內容連接:http://www.cnblogs.com/wayne2... 以及官方文檔5.7 scrollView在快速拖拽的時候會contentOffSet數值會發生跳變:scrollView採用定時器採樣scrollView偏移量.
6 定時器
6.1 定時器會中止計數,當scrollView滑動的時候,解決方法加入把定時器 添加到runLoop 的commandModel.
6.2 定時器形成循環引用,這個在高效52個方放中有講.不過多解釋
6.3 ( 特定場景 )eg:訂單列表中若是是支付中的訂單;有一個倒計時5分鐘然後取消訂單的需求;與此同時後臺也有一個5分鐘倒計時取消的操做;針對這種狀況最好在5分鐘倒計時結束的時候去重新拉取數據(後臺在倒計時結束會自動取消訂單)從而避免移動端操做的麻煩.(最好不要去在移動端定時器結束後去調取消訂單的操做:支付完成後若是沒有返回app這時候的定時器還在運行就會取消訂單)
7.edgesForExtendedLayout
設置重疊部分該如何顯示.
Prior to(在iOS7以前) iOS 7, the UIViewController.View did not visually underlap(重疊) parent elements such as the status bar, navigation bar, or toolbar. In iOS 7, it typically should.
The UIViewController.EdgesForExtendedLayout specifies to the UIViewController.ParentViewController how the edges of this UIViewController should be extended for underlap. The default value of UIRectEdge.All specifies that all edges should be extended to underlap(子控制器視圖的邊界到延伸到與父控制器視圖重疊的部分), while UIRectEdge.None specifies an extent similar to that in iOS 6 or earlier.
UIRectEdge.All :重疊部分延伸; UIRectEdge.None:重疊部分不延伸
摘選:https://developer.xamarin.com...7.2 automaticallyAdjustsScrollViewInsets:
The default value of this property is YES, which lets container view controllers know that they should adjust the scroll view insets of this view controller’s view to account for screen areas consumed by a status bar, search bar, navigation bar, toolbar, or tab bar. Set this property to NO if your view controller implementation manages its own scroll view inset adjustments.(主要解決當scrollView被狀態欄、導航欄遮擋的狀況下自動調整contentInsert)
7.3 extendedLayoutIncludesOpaqueBars:佈局是否包括透明的Bars
8.應用受權範例
ALAuthorizationStatus alStatus = [ALAssetsLibrary authorizationStatus] ; if (alStatus == ALAuthorizationStatusDenied ||alStatus == ALAuthorizationStatusRestricted) { UIAlertAction* confirmAction = [UIAlertAction actionWithTitle:@"肯定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { //跳轉到設置界面進行受權. //NSURL* settingUrl = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; //iOS10 iOS8 也是能夠正常運行. NSURL* settingUrl = [NSURL URLWithString:@"App-prefs:root=Privacy&path=Photos"]; //UIApplicationOpenSettingsURLString NS_AVAILABLE_IOS(8_0);(使用這個 選項進行設置也是能夠的,建議使用而後彈出一個HowToDo界面) if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_9_x_Max) { if ([[UIApplication sharedApplication] canOpenURL:settingUrl]) { [[UIApplication sharedApplication] openURL: settingUrl options:@{} completionHandler:^(BOOL success) { NSLog(@"跳轉成功!"); }]; } }else{ if ([[UIApplication sharedApplication] canOpenURL:settingUrl]) { [[UIApplication sharedApplication] openURL:settingUrl]; } } }]; UIAlertAction* cancleAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]; UIAlertController* alterVC = [UIAlertController alertControllerWithTitle:@"想訪問您的相冊" message:nil preferredStyle:UIAlertControllerStyleAlert]; [alterVC addAction:confirmAction]; [alterVC addAction:cancleAction]; [self presentViewController:alterVC animated:YES completion:nil]; }else{ ///已經受權 [self continueAccessAlbum]; }
9.UIPickerView 大小
UIPickerView大小在ios9.以前是很難改變的,以後就能夠了
UIPickerView and UIDatePicker are now resizable and adaptive—previously, these views would enforce a default size even if you attempted to resize them. These views also now default to a width of 320 points on all devices, instead of to the device width on iPhone.
Interfaces that rely on the old enforcement of the default size will likely look wrong when compiled for iOS 9. Any problems encountered can be resolved by fully constraining or sizing picker views to the desired size instead of relying on implicit behavior.
參考連接:https://developer.apple.com/l...
10.UICollectionView.collectionViewLayout 內容.
collectionViewLayout property of UICollectionView is of type UICollectionViewLayout. You can assign any custom subclass of type UICollectionViewLayout to collectionView instance Similarly apple has created a subclass called UICollectionViewFlowLayout which inherits from UICollectionViewLayout Because its a subclass of UICollectionViewLayout you can set UICollectionViewFlowLayout instance to collectionView.collectionViewLayout property and UICollectionViewFlowLayout class has a property named minimumLineSpacing and obviously its parent class which is UICollectionViewLayout does not have it ) In your case u created a instance of parent class (UICollectionViewLayout) and tried accessing the property defined in child class (UICollectionViewFlowLayout). Obviously compiler could not find that property hence crashed(有一點須要注意collectionView實例默認的collectionViewLayout類型是UIcollectionViewFlowlayout)