[iOS][Scroll view] 異常處理

異常描述

為了Scroll view在device旋轉時,contentOffset還能一致,所以做了一點運算去同步它,但是該運算在scroll view的contentOffset於最尾端時出現問題。
從portrait的300px寬度轉換到landscape的261px寬度,捲動到最尾端的部分時開始做旋轉測試。當你從portrait轉landscape(此時位置正確),再轉回portrait,卻無法對準尾端,會往回39px。
百思不得其解為何就是39px。

判斷

後來發現39px剛好是直橫向的frame寬度差(請看前面的描述),換句話說,我在運算時抓到的contentOffset,不知道為何先受到frame從261變成300所以被影響造成位移了39px。往前一看,是layoutSubviews的呼叫造成的。

解決辦法

由於我是在包含該scroll view的view (為一custom view) 的layoutSubviews裡面去處理旋轉後的contentOffset的相對位置同步的,這是因為旋轉時會呼叫layoutSubviews。經判斷後應該是scroll view的frame被改成直向的大小(但contentSize還沒變),所以交換一下程式碼的位置就好。
比方說:
- (void)layoutSubviews
{
    [super layoutSubviews];
    [self adjustScrollViewOffsetWhileDeviceRotate];
}
改成
- (void)layoutSubviews
{
    [self adjustScrollViewOffsetWhileDeviceRotate];
    [super layoutSubviews];
}
這是因為scroll view的frame會在[super layoutSubviews]呼叫之後被立刻改動(261px->300px),所以將調整用的method呼叫改到[super layoutSubviews]之前執行就可以了。這也反應了iOS元件的尺寸變化的機制,layout update的通知是從super view一層一層往subview告知,而frame的計算是由subview往super view一層一層回來。

不過這邊也是跟你 adjustScrollViewOffsetWhileDeviceRotate 方法內的操作有關,只是說當你在做一些跟superview的frame有關的frame/bounds操作遇到問題時,要注意到這機制。

留言