これが最後じゃないからね

iOS開発 / Swiftなどの技術を中心に

UIScrollView、UIKit座標計算系に関しての復習

みなさんお元気ですか?
新卒として社会人になり、気がつくとGWになってしまっていました、、、
業務でUIScrollViewでつまってしまったので復習してみることにしました。
プラスαでみなさんご存知UIKit座標系に関しても。

UIScrollView

UITableViewやUICollectionViewもUIScrollViewのサブクラスです。 f:id:haptaro:20170503204939p:plain

UIScrollViewの主な目的

  • 表示したいコンテンツの領域をドラッグして表示できるようにするため
  • ピンチジェスチャでコンテンツの表示を拡大縮小できるようにするため

今回は前述のほうに関してです。
表示したいコンテンツの領域をドラッグして表示するためにはそのコンテンツはUIScrollViewより大きい

UIScrollViewに関するプロパティ f:id:haptaro:20170503213246p:plain

  • contentOffset: CGPoint・・・どのくらいスクロールしているのか。特定の位置を左上角とする位置
    初期値は{0, 0}
  • contentSize: CGSize・・・スクロールする中身のサイズ。スクロール可能な領域 f:id:haptaro:20170503204556p:plain

  • contentInset: UIEdgeInsets・・・余分にどれだけスクロールできるか。こちらは以下の図の余白部分が伸び縮みする感じ f:id:haptaro:20170503204748p:plain

contentOffsetへのスクロールは2通り

  • setContentOffsetメソッドで指定されたcontentOffsetへコンテンツをスクロールさせる
  • contentOffsetプロパティへ直接代入(動きはsetContentOffset:animated: false同じ即座にスクロール)

UIScrollViewを使用するときのポイント

f:id:haptaro:20170503221005p:plain

  • contentOffsetの座標を移動させることでスクロール動作ができることを把握する
  • contentSize(スクロールする中身のサイズ。スクロール可能な領域)を決める
    ※StoryboardでAutoLayout制約をつける人も、コードでレイアウトをする人も結局意識することは同じです

Debug View Hierarchy

Viewをレイヤのように階層化して3D表示してくれる。
Xcode6から追加された機能。

f:id:haptaro:20170503160804p:plain

UI系の不具合やUIScrollViewでのスクロールなどにもってこい。
実際にUIScrollViewのスクロール計算部分で値が合わず、Debug View HierarchyでNavigationBar(44pt)やStatusBar(20pt)の高さを見て解決しました。

UIScrollViewでたまに出てくる処理

scrollView.contentOffsetをxより小さかったらxに、yより大きかったらyにというような処理
ex)
0より小さかったら0に
100より大きかったら100に

var x = scrollView.contentOffset.y
if x < 0 {
    x = 0
} else if x > 100 {
    x = 100
}

省略系

let y = min(max(0, scrollView.contentOffset.y), 100)

以下の座標や計算系

CGFloat・・・CG(Core Graphics)などのふ浮動小数点系。
UIViewの座標系を扱う際はDoubleやFloatではなく、CGFloatを使う必要がある

CGPoint

(x, y)座標

struct CGPoint {
    var x: CGFloat
    var y: CGFloat
}

CGSize

(width, height)の大きさ

struct CGSize {
    var width: CGFloat
    var height: CGFloat
}

CGRect

(x, y, width, height)

struct CGRect {
    var origin: CGPoint
    var size: CGSize
}

※Rect(Rectangles)

※frameはCGRect型

iOSの座標系

f:id:haptaro:20170503211422j:plain

frameとbounds , frame.origin(bounds.origin)とframe.size(bounds.size) の違い

f:id:haptaro:20170503215744p:plain

  • frame・・・親Viewからの座標 (x, y, width, height)
  • bounds・・・自分から見たViewの座標 (0, 0, width, height)
    ※boundsの(x, y)は常に(0, 0) f:id:haptaro:20170503215637p:plain

  • frame.origin(bounds.origin)・・・左上角の座標

  • frame.size(bounds.size)・・・Viewの大きさ

※origin: CGPoint, size: CGSize

まとめ

結局UIKit周りの知識がしっかりないとって感じなんですよね。。。
ただUIScrollViewもRxのものがあったりするので、リアルタイムに動きを監視して何か処理する部分は今後はRxSwiftでバリバリ書いていきたいですねー。
さてまた気分がのったらブログ更新します。

Apple公式ドキュメント

https://developer.apple.com/jp/documentation/UIScrollView_pg.pdf

developer.apple.com

参考URL

blogios.stack3.net www.itwendao.com サイズ指定(CGRect CGPoint CGSize) - iPhoneアプリ開発の虎の巻 gabrielghe.github.io

※中国語は読めません。w