iOS7から、UIScrollView
を継承したViewをViewControllerのviewの最初のviewに設定しているとviewのinsetsを操作して自動的に位置を補正するようになりました。
これは、iOS7からナビゲーションバーの下も表示領域として確保され、実質フルスクリーンが表示領域となるための措置です。
ただこの補正が自動的に行われるため、実装内容によっては意図した挙動にならず混乱することがあります。
scrollView.contentOffsetを使わない
今回色々実装していて、UIScrollView
のcontentOffset
を使って、スクロール位置に応じてごにょごにょ実装していたのですが、これだとバックグラウンドから復帰した際などに自動的に補正されて意図した値が取れないことがありました。
最初はNSNotificationCenter
のUIApplicationWillEnterForeGroundNotification
やUIApplicationDidEnterBackgroundNotification
を使って対処しようとしたんですが、色々変化して難しかったのでやめました。
結論としては scrollView.contentOffset
を使わず bounds.origin.y + contentInset.top
を使う、です。
ログを出力してみて気づいたのが、UIScrollView
が画面上端にある場合はbounds.origin.y
が-64
、contentInset.top
が64
に設定されていていました。
contentOffset.y
は通常時は-64
ですが、contentOffset.y
が少しでもずれているときにバックグラウンド→フォアグラウンドと遷移すると、自動的に位置が補正されるようです。
おそらく、自動的にinsetsを補正する機能が動いているためと思われます。
一方で、bounds.origin.y + contentInset.top
の値は、UIScrollView
が画面上部にある場合は常に0
となります。
なので、この値をスクロール位置として利用することでどんな状態でも適切に値を参照することができるようになりました。
console出力
実際に出力したconsoleのログを参考のため載せておきます。
通常時
po self.tableView
<TableView: 0x14887c00; baseClass = UITableView; frame = (0 0; 320 519); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x14513740>; layer = <CALayer: 0x145d1b00>; contentOffset: {0, -64}>
---------------------
po self.tableView.contentInset
(top = 64, left = 0, bottom = 0, right = 0)
-----------------------------
po (CGRect)[self.tableView bounds]
origin=(x=0, y=-64) size=(width=320, height=519)
{
(x=0, y=-64)
{
0
-64
}
(width=320, height=519)
{
320
519
}
}
ずれた状態
po self.tableView
<TableView: 0x14887c00; baseClass = UITableView; frame = (0 0; 320 519); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x14513740>; layer = <CALayer: 0x145d1b00>; contentOffset: {0, 0}>
------------------------------------------------------------------
po self.tableView.contentInset
(top = 0, left = 0, bottom = 0, right = 0)
------------------------------------------------------------------
po (CGRect)[self.tableView bounds]
origin=(x=0, y=0) size=(width=320, height=519)
{
(x=0, y=0)
{
0
0
}
(width=320, height=519)
{
320
519
}
}