Open19
SwiftUIで困ってきたあれこれ(未解決含む)
WebView表示がSwiftUI標準ではサポートされていない(Xcode13.0では)
- UIViewRepresentableを使用して、UIKitと統合する必要がある
import SwiftUI
import WebKit
struct WebView: UIViewRepresentable {
let url: String
func makeUIView(context: Context) -> WKWebView {
return WKWebView()
}
func updateUIView(_ uiView: WKWebView, context: Context) {
guard let url = URL(string: url) else {
return
}
let request = URLRequest(url: url)
uiView.load(request)
}
}
セルのEditModeでセルをスライドした時の色を変えたり、文字を変更したりすることができない
- 現状は不可能なので、デフォルトの赤のままで妥協するか、諦めてUIKitを使用する必要がある
- 例えば、
onDelete
を使うと「削除」の文字が出るが、これ以外に変えることは現状できないし、文字以外に変えることもできない(英語の場合は「Delete」になる)
- 例えば、
Viewを10個までしか並べることができない
-
Group
やVStack
、HStack
、ZStack
などで囲う - 別のviewのstructとして外出しする(↑をやるとネストが大変なことになるのでこっちが良いと思う)
パディングの設定の仕方
-
auto layoutでは基本的に、マージンを固定で決めて、コンテンツ自体の縦横は可変にすることが多いみたい?
-
VStackやHStackを使っているのであれば、その
spacing
を使ってパディングを決めるか、view自体にpaddinigを設定するのが良さそう -
あとは、GeometryReaderを使う
VStack(spacing: 10) {
Text("テスト1")
Text("テスト2")
}
- 最初はよくわからなくて、こんなことしてたけど、そもそもコンテンツ自体のwidthとheightを決めるのはiOS的開発ではないらしい
let screen = UIScreen.main.bounds
Text("xxxx")
.frame(width: screen.width * 0.5)
変更前と変更後のセルの数が違うエラー
- Listで条件分岐による表示非表示を行っているとたまに発生する
- 原因がよく分かっていないので、次回発生時に要調査
- SwiftUI固有かわからないけど、書き方が悪いのか結構出ちゃうのなんで
popoverやfullScreenのモディファイアを1つのviewに対して複数つけられない
- OSバージョンによっては、問題なく動くが、動かないOSバージョンもあるので要確認
- しかもマイナーバージョンが違うだけでも挙動が違うことがあるので要注意(iOS14代の話)
- 別のViewでフルスクリーン表示したい時は、fullScreenを複数つけるんじゃなくて、つけるのは1つのみでswitch文で分岐する
プレビューでLandscapeモードがサポートされていない
- Xcode13から対応済み
- もしプレビューさせたいサイズがデフォルトで用意されていない場合は、自分でサイズを決めることもできる
struct SampleButton_Previews: PreviewProvider {
static var previews: some View {
SampleButton(text: "bright", isDark: false)
.previewLayout(.fixed(width: 375, height: 100))
}
}
カスタムURLスキームなど外部からアプリの特定画面に遷移したい(ディープリンク)場合の処理
- レイヤーの一番基盤になっているViewに、ZStackで表示させたいViewが一番上になるように被せる?
- どの画面に表示したいというわけではないから、そうなりそう?UIKitでもそうなのかな?よくわからん
印刷機能がSwiftUI標準でサポートされていない(Xcode13.0)
- UIKitの機能を使用する必要がある
MVVMで実装していると、ViewModelのDIを工夫する必要がある
- テスタブルに実装しようとすると、ViewModelをテスト時やプレビュー時に差し替え可能にできるように実装すると思う
- ViewにViewModelを注入するとき、ジェネリクスとして実装する必要がある
TextFieldを実装した時のキーボードの挙動
- SwiftUIのTextFieldはデフォルトでキーボードがTextFieldの真下まで上がってくれるけど、その下にボタンがある場合、ボタンの下まで上がるようにしたいなら、UIKitを使用して実装する必要がある
- iOSDC2021で講演した人が言ってた & 自分で実装した時もそうだった
よくわからんメモリリークが発生する
- 現在原因調査中
Firebaseでスクリーンログが取れない
- iOSDC2021で何人かが言ってた。
- 自分で確認したことはない
NavigationView
を使用すると、不要なインスタンスが作成されてしまう
- iOSDC2021で言ってた
- LazyViewを使用して防ぐらしいが、自分でやったことはまだない
xx分ごとのDatepickerを作成することができない
- intervalが設定できないので、UIKitのDatePicker使う必要がある
- 特にSwiftUIのDatePickerStyleにある
.graphical
は拡張性が低い印象 - 日付選択だけでなく、時刻選択までついてくるのはいいのだけど、それの拡張性が特に低い。おかげで大変な思いした・・・
Navigation bar UI周りの設定をするときのベストプラクティスがわからない
実験結果は以下
- 参考
PDF表示が標準でサポートされていない
- UIKitでPDFKitを使って実装する必要がある
struct PDFKitRepresentedView: UIViewRepresentable {
let url: URL
init(_ url: URL) {
self.url = url
}
func makeUIView(context: UIViewRepresentableContext<PDFKitRepresentedView>) -> PDFKitRepresentedView.UIViewType {
// Create a `PDFView` and set its `PDFDocument`.
let pdfView = PDFView()
pdfView.document = PDFDocument(url: self.url)
return pdfView
}
func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<PDFKitRepresentedView>) {
// Update the view.
}
}
SwiftUIについてのその他Tips
Slider のタッチイベント