2019年9月24日火曜日

SwiftUI で ScrollView / Listの現在のスクロール位置 (UIKitにおけるcontentOffset) に相当する値を参照する/コード上から指定する方法は iOS SDK 13.0 地点では存在しない

タイトルの通りですが一応補足しておきます。

先日、奇しくもAppleのSwift UIを実際に手掛けている開発者に直接質問する機会に恵まれましたので以前から気になっていた内容を質問してみたのですが、やはり現段階のリリースではcontentOffsetに相当するものの変更タイミングを取得したり、またプログラム的にcontentOffsetを調整することもできないと明言されてしまいました。

ただしcontentOffsetの変化したタイミングを取得するだけであれば、以下の方法で擬似的に再現することができるとアドバイスを頂きました。


  1. ScrollView / List 上の特定の位置に、ダミーの隠しViewを配置する。
  2. 隠しViewのonAppear() / onDisappear() を利用する。


彼曰く、コミュニティの誰かが作ったサンプルのVideoPlayerアプリがこのテクを使って動画が画面内に入ってきたときに自動再生を開始する挙動を実現していると言っていたのですが、具体的にどのサンプルアプリなのかは教えてもらえなかったので発見できず。残念。

あとは例によっていつものごとく、機能追加が欲しい場合は https://developer.apple.com/bug-reporting/ 経由で要望を上げてくれると対応できるよと言っていましたので皆さんガンガン書けばいいと思います。

2019年6月8日土曜日

SwiftUI 未解決問題まとめ

一通り試してほぼほぼ理解できたのですが、現状どこをどのように調べてもわからなかった内容がいくつかあるので未解決問題としておいておきます。誰か教えて\(^o^)/

Transition

type-eraseされたAnyTransitionはSwiftUI.frameworkに居るのですが、元のProtocolが見えない上にドキュメンテーションも一切ありません。おそらくはNavigationViewの中で使われているのだと思いますが詳細不明。

ScrollView / Listの現在のスクロール位置 (UIKitにおけるcontentOffset) に相当する値を参照する/コード上から指定する方法

今の所、一番怪しいのが以下のpreferenceの仕組みではないかと睨んでいるのですが、
問題は肝心要のPreferenceKeyの具体実装がSwiftUI.framework上には一切見つからず、したがってキーが指定できないためonPreferenceChange(_:perform:)がうまく利用できません。特定位置までスクロールしたら発火、とかビューが50%スクロールして隠れたら発火、とか普通に使いたいのですが、困りました。それとかあとはenvironment経由なりイニシャライザ経由なりでinitialScrollPositionのようなプロパティを用意してScrollViewのスクロール初期位置を与える、みたいなテクも使いたいですし、普通に必要だと思うんですけど(´・_・`)

ちなみにView.offsetではない・・・と思います、たぶん。一応念のためにList.offset()で試してみましたが、ドキュメンテーションにもある通り、全く違う挙動になります。

SwiftUI チュートリアル ヘルプ ドキュメント FAQ 困ったらとりあえずここ見ればOK

https://github.com/Juanpe/About-SwiftUI

いろいろ調べたのですが、これよりよくまとまっているドキュメントを現状発見できませんでしたので、2019/06/08現在では上記のドキュメントを参照するのがベストだと思います。

特に以下の記事は役立ち度が高かったです。この2つだけで問題の9割ぐらいは解決できると思います。

SwiftUI by Example
https://www.hackingwithswift.com/quick-start/swiftui

Answers to the most common questions about SwiftUI
https://wwdcbysundell.com/2019/swiftui-common-questions/

あとは直接SwiftUI.frameworkの中身を見るのが良いと思います。正直Appleのドキュメンテーションは未だにSwiftのExtensionベースの実装をきれいにドキュメントに起こす事ができておらず、複数のドキュメントに重複した記載が見られたり、どこで定義されているfunc/varなのかを正しく表現できていなかったりします。なのでシグネチャの名前さえわかっていればSwiftUI.frameworkの中を自分で検索したほうが正確にどういう定義になっているか判断できて便利です。