UIRefreshControlちゃんと導入できていますか?
若干あおりっぽいですが...(笑)
先日こちらのブログ記事をみていて、そういえばそんなプロパティも追加されてたっけ...
とふと思い、何か違うのかなぁ?ってちょちょっと検証してたら違ったのだけれど、それより大事なことを知ってしまったので
UIRefreshControl
導入方法によって違う...ってか、え?これダメなの!?
です!(笑)
環境
- Xcode v9.2
- Swift v4.0
UIRefreshControl
とは?
iOSでapp作ってりゃ説明いらないとおもいますが...
リスト系のやつで引っ張って更新っていう操作がよくあるけども
アレを実現してくれるやつです。
導入方法
2つ(?)紹介します
addSubview()
で導入する(旧?バージョン)
むかーしから使われている方法ですね..。
let refreshControl = UIRefreshControl()
self.tableView.addSubview(refreshControl)
こういう感じ。
これで引っ張ることができるようになります。
refreshControl
プロパティで追加する(新バージョン)
新バージョンっていってもこのプロパティが追加されたのはけっこう前なはず...(笑)
let refreshControl = UIRefreshControl()
self.tableView.refreshControl = refreshControl
こういう感じ。
この旧と新で一見すると同じ挙動になるので、
僕は「導入できる方法が2つあるだけでも何も変わらんだろう〜」ぐらいに思っていました。
が、それが特定の条件下だと挙動に差異がでてきます。
NavigationBarのlargeTitleを有効にしている場合
先に紹介したブログのほうで話題になっていたのですぐ気づいたのですが...
UINavigationBar
がlargeTitleモードになっていると挙動が違ってきます。
くるくるが出て来るところが全然違う(笑)
旧バージョン
引っ張ってる最中はなんか見えない(多分広がったNavigationBarに隠れている)で、
引っ張っている状態から戻ってきた時にやっとくるくるがみえる感じ
新バージョン
もうTableViewの領域を超えてNavigationBarのほうにでちゃう!
多分こっちが本来あるべき挙動だと思われます
もどってくるアニメーションもなんかスムーズですし。旧バージョンのほうはちょっと変な感じがするのです。
スクロールによるBounceが効かない(要らない)場合
ちょっと説明が難しいのですが...
例えば...
self.tableView.alwaysBounceVertical = false
という感じでbounceを無効にして、かつスクロールが発生しない状態(件数が0件だったり少数で画面内におさまる場合)...そういうケースです
旧バージョン
引っ張って更新ができません。ひっぱれません。
新バージョン
引っ張れます。いつものように引っ張って更新できます。
旧バージョンの場合、addSubview()
なので、TableViewの状態に依存してしまいできないのでしょうか。。?
ただ、これは困った話で、仕様的にbounceいらね!ってなって、たまたま取得した件数が2件とか少数だった場合...もうリストを更新できなくなるっていうことなのです。
(bounceはいらんとは言ったが引っ張って更新までいらんとは言っていない!みたいな...?)
とりあえずこの2つのケースで挙動による差異がありましたが、
いずれもなんか新バージョンのほうが正しい挙動なような気がするので、
特別な理由がない限り新バージョンのほうで導入しておいたほうが良さそうですね。
追加したからにはそりゃ意味ありますよね😇
(そう意味はあるのです!)
というか旧バージョンはそもそもアカン!?
らしい(笑)
当初はUITableViewController
前提でUIRefreshControl
が導入されていて、
いやいやUIViewController
+ UITableView
という構成でも使いたいでしょっていうあれから生まれたハック的な手法っぽい?
新旧とかじゃなかった..正式か非公式かだ😇
そりゃ挙動ちがうし、refreshControlプロパティのほうが正しいですね!
UIScrollView
を継承している全てのViewでrefreshControlプロパティが有効になった今...
addSubview()
でやる意味はなさそうですね。むしろ非推奨か。(iOS9以前でも対応するならやむなしかもですが)...
いまざっくりぐぐってみても新しい記事でもaddSubview()
のほうもバンバン出てくるので根強く浸透しちゃってるなぁ...
参考
いろいろ検証するきっかけになりました🙏
昔はこちらのドキュメントに
Because the refresh control is specifically designed for use in a table view that's managed by a table view controller, using it in a different context can result in undefined behavior.
という注釈があったみたい。今は消えているけど
iOS10が出てScrollViewにrefreshControlプロパティが追加されたので、
UITableViewController
を前提にしているわけじゃなくなったからでしょうね...