Open18

SwiftUIで困ってきたあれこれ(未解決含む)

kamimikamimi

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)
    }
}

https://qiita.com/kamimi01/items/b4d6cbafa587831c1be0

kamimikamimi

セルのEditModeでセルをスライドした時の色を変えたり、文字を変更したりすることができない

  • 現状は不可能なので、デフォルトの赤のままで妥協するか、諦めてUIKitを使用する必要がある
    • 例えば、onDeleteを使うと「削除」の文字が出るが、これ以外に変えることは現状できないし、文字以外に変えることもできない(英語の場合は「Delete」になる)
kamimikamimi

Viewを10個までしか並べることができない

  • GroupVStackHStackZStackなどで囲う
  • 別のviewのstructとして外出しする(↑をやるとネストが大変なことになるのでこっちが良いと思う)

https://capibara1969.com/1621/

kamimikamimi

パディングの設定の仕方

  • 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)
kamimikamimi

変更前と変更後のセルの数が違うエラー

  • Listで条件分岐による表示非表示を行っているとたまに発生する
  • 原因がよく分かっていないので、次回発生時に要調査
    • SwiftUI固有かわからないけど、書き方が悪いのか結構出ちゃうのなんで
kamimikamimi

popoverやfullScreenのモディファイアを1つのviewに対して複数つけられない

  • OSバージョンによっては、問題なく動くが、動かないOSバージョンもあるので要確認
    • しかもマイナーバージョンが違うだけでも挙動が違うことがあるので要注意(iOS14代の話)
    • 別のViewでフルスクリーン表示したい時は、fullScreenを複数つけるんじゃなくて、つけるのは1つのみでswitch文で分岐する
kamimikamimi

プレビューでLandscapeモードがサポートされていない

  • Xcode13から対応済み
  • もしプレビューさせたいサイズがデフォルトで用意されていない場合は、自分でサイズを決めることもできる

https://programming-sansho.com/swift/how-to-preview/

struct SampleButton_Previews: PreviewProvider {
    static var previews: some View {
        SampleButton(text: "bright", isDark: false)
            .previewLayout(.fixed(width: 375, height: 100))
    }
}
kamimikamimi

カスタムURLスキームなど外部からアプリの特定画面に遷移したい(ディープリンク)場合の処理

  • レイヤーの一番基盤になっているViewに、ZStackで表示させたいViewが一番上になるように被せる?
    • どの画面に表示したいというわけではないから、そうなりそう?UIKitでもそうなのかな?よくわからん
kamimikamimi

印刷機能がSwiftUI標準でサポートされていない(Xcode13.0)

  • UIKitの機能を使用する必要がある
kamimikamimi

MVVMで実装していると、ViewModelのDIを工夫する必要がある

  • テスタブルに実装しようとすると、ViewModelをテスト時やプレビュー時に差し替え可能にできるように実装すると思う
    • ViewにViewModelを注入するとき、ジェネリクスとして実装する必要がある

https://qiita.com/turara/items/dd7bee391962f945256f

kamimikamimi

TextFieldを実装した時のキーボードの挙動

  • SwiftUIのTextFieldはデフォルトでキーボードがTextFieldの真下まで上がってくれるけど、その下にボタンがある場合、ボタンの下まで上がるようにしたいなら、UIKitを使用して実装する必要がある
    • iOSDC2021で講演した人が言ってた & 自分で実装した時もそうだった
kamimikamimi

Firebaseでスクリーンログが取れない

  • iOSDC2021で何人かが言ってた。
    • 自分で確認したことはない
kamimikamimi

xx分ごとのDatepickerを作成することができない

  • intervalが設定できないので、UIKitのDatePicker使う必要がある
  • 特にSwiftUIのDatePickerStyleにある.graphicalは拡張性が低い印象
  • 日付選択だけでなく、時刻選択までついてくるのはいいのだけど、それの拡張性が特に低い。おかげで大変な思いした・・・
kamimikamimi

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.
    }
}

https://pspdfkit.com/blog/2019/how-to-show-a-pdf-in-swiftui/