iOS之旅--UIScrollView疑難處理
阿新 • • 發佈:2019-01-05
引子:前兩天做了一個小活動,不是太趕週期,所以就不想採用xib和storyboard的方式開發,就使用Masonry控制約束,純程式碼進行了開發。本次開發主要是使用UIScrollView。
當然,很快就把程式碼碼完了,開始進入除錯,突然發現scrollView不能滾動了,這裡我已經設定過scrollView.contentSize了,但是還是不能滾動,然後就想到了可能是生命週期的問題,這裡簡單說一下生命週期的呼叫順序
1、initWithNibName:bundle:
初始化UIViewController,執行關鍵資料初始化操作,注意這裡不要做view相關操作,view在loadView方法中才初始化,這時loadView還未呼叫。如果使用StoryBoard進行檢視管理,程式不會直接初始化一個UIViewController ,StoryBoard會自動初始化或在segue被觸發時自動初始化,因此方法initWithNibName:bundle:不會被呼叫。
如果在程式碼裡面使用instantiateViewControllerWithIdentifier:方法顯示初始化一個UIViewController,則initWithCoder方法會被呼叫。
如果是通過呼叫initWithNibName:bundle指定nib檔名初始化的話,ViewController會根據此nib來建立View。如果name引數為nil,則ViewController會通過以下兩個步驟找到與其關聯的nib:
1)如果ViewController的類名以“Controller”結尾,例如ViewController的類名是MyViewController,則查詢是否存在MyView.nib ;
2)找跟ViewController類名一樣的檔案,例如MyViewController,則查詢是否存在MyViewController.nib
2、loadView
當訪問UIViewController的view屬性時,view如果此時是nil,那麼VC會自動呼叫loadView方法來初始化一個UIView並賦值給view屬性。此方法用在初始化關鍵view,需要注意的是,在view初始化之前,不能先呼叫view的getter方法,否則將導致死迴圈(除非先呼叫了[supper loadView];)
如果沒有過載loadView方法,則UIViewController會從nib或StoryBoard中查詢預設的loadView,預設的loadView會返回一個空白的UIView 物件。
3、viewDidLoad
當VC的view物件載入記憶體後呼叫,用於對view進行額外的初始化操作
4、viewWillAppear
在view即將新增到檢視層級中(顯示給使用者)且任意顯示動畫切換之前呼叫(這個時候supperView還是nil)。這個方法中完成任何與檢視顯示相關的任務,例如改變檢視方向、狀態列方向、檢視顯示樣式等
5、viewDidAppear
在view被新增到檢視層級中,顯示動畫切換之後呼叫(這時view已經新增到supperView中)。在這個方法中執行檢視顯示相關附件任務,如果過載了這個方法,必須在方法中呼叫[supper viewDidAppear];
6、viewWillLayoutSubviews
view即將佈局其Subviews。比如view的bounds改變了(例如狀態列從不顯示到顯示,檢視方向變化),要調整Subviews的位置,在調整之前要做的一些工作就可以在該方法中實現。
7、viewDidLayoutSubviews
view已經佈局其Subviews。比如view的bounds改變了(例如狀態列從不顯示到顯示,檢視方向變化),已經調整Subviews的位置,在調整完成之後要做的一些工作就可以在該方法中實現。
8、viewWillDisappear
view即將從superView中移除且移除動畫切換之前,此時還沒有呼叫removeFromSuperview。
9、viewDidDisappear
view從superView中移除,移除動畫切換之後呼叫,此時已呼叫removeFromSuperview。
之前的程式碼全部在viewDidLoad裡面,我把scrollView.contentSize 的設定放在viewDidLayoutSubviews(檢視調整完的最後),這樣就可以順利的滑動了。
注:由於我這邊的scrollView是動態的,需要計算高度,而我又不想儲存過多的變數,所以不太想在viewDidLayoutSubviews裡面設定scrollView的contentSize,所以就在檢視新增完成之後做了如下操作:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self.scrollView setContentSize:CGSizeMake(SCREEN_WIDTH, scrollHeight)];
});
通過這種辦法也可以實現scrollView的正常滑動,不過沒有特殊情況建議還是在viewDidLayoutSubviews裡面去處理。
另外本次做的刮刮樂效果,使用到了UIScrollView的delaysContentTouches這個屬性,很是有用。
如果你有遇到棘手的問題,歡迎留言。