バッテラが如く

プログラミングしましょ!

【SwiftUI】SwiftUI記事まとめ

はじめに

どうも、バッテラです。

SwiftUIの記事が増えてきたので、まとめをつくりました。

ビュー関連

List

Image

ScrollView

Text

Color

Stack

プログラム関連

基本文法

PropertyWrapper

モディファイア

画面遷移/ナビゲーション

sheet

インプット

ダイアログ

アラートダイアログ

アセット

デバッグ

その他

レシピ

【SwiftUI】Listをスクロールさせた時にバウンドさせないようにする方法

はじめに

Listでスクロールさせると上下で↓のようにバウンドしますよね?

このバウンドをさせなくする方法について共有したいと思います。

バウンドをさせなくするには

UITableView.appearance().bounces = falseを呼び出すだけでOKです

struct HogeView : View {
        
    init() {
        UITableView.appearance().bounces = false
    }
}

これで実行してみると。。

バウンドしなくなりましたね!

【SwiftUI】ListでNaigationLinkすると選択状態になってしまう件について

事象

Listでセルをクリックしたら画面遷移するのを作りました(↓参照)

動画見てもらうとわかると思うのですが戻ってきた時にそのセルが選択状態になっています

※iOS15ではこの現象は発生しません

これがデザイン的に不具合に見えるので、戻った時には選択状態を解除させる方法について共有したいと思います。

※注意 実装の仕方によってこれで解決しないかもです。治ったらラッキー程度と思って下さい。

選択状態を解除する

Listに対して以下の処理を書きます。

List {
~~~~~~~省略~~~~~~~~
}
.onDisappear {
    UITableViewCell.appearance().isSelected = false
}

これで実行してみると。。。

無事選択状態が解除できました!

参考にしたサイト

ios - How to remove highlight on tap of List with SwiftUI? - Stack Overflow

【SwiftUI】前の画面に戻る方法 (NavigationLink、sheetで遷移)

SwiftUI

はじめに

今日はSwiftUIの勉強していきます。

NavigationLinkやsheetを使って別画面を表示した後にコードで戻る処理を書きたいときがやってます。

今回はコードで前の画面に戻る方法について共有したいと思います。

環境

この記事の情報は次のバージョンで動作確認しています。

* MacOS Monterey (12.1)
* Xcode (13.3.1)

コードで前の画面に戻る

画面遷移先のVIewで以下の変数を宣言します

 @Environment(\.presentationMode) var presentationMode

戻りたいタイミングのイベントメソッドで以下コードを実行します

presentationMode.wrappedValue.dismiss()

これでOK

おわりに

最後まで見ていただきヘペトナス!

読者登録・Twitterのフォローもお願いします。

【SwiftUI】何もないところを押したらキーボードを閉じさせる方法

今日はSwiftUIの勉強していきます。

TextFieldやTextEditorのようなキーボードが表示される場合に、キーボードが表示されたままで閉じれないことがありました。

とりあえず背景部分をタップしたらキーボード閉じるという方法がわかったので共有します。

■開発環境

  • MacOS Monterey (12.1) Xcode (13.3.1)
  • キーボードを閉じる処理

    extensionを作る

    SwiftUIデフォルト機能でないのでUIKitの力を使います。とりあえずおまじないという感じで以下をextesionで実装します

    import Foundation
    import UIKit
    
    extension UIApplication {
        func closeKeyboard() {
            sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
        }
    }
    
    extensionを使う
    1. ZStackで背景領域を作る
    2. .onTapGestureモディファイアで
    3. UIApplication.shared.closeKeyboard()
    var body: some View {
        ZStack {
                
            // 背景
            ZStack {
                Color.white.edgesIgnoringSafeArea(.all)
             }
             .onTapGesture {
                 UIApplication.shared.closeKeyboard()
             }
    

    おわりに

    最後まで見ていただきヘペトナス!

    読者登録・Twitterのフォローもお願いします。

    【SwiftUI】ダークモードを回避する方法

    SwiftUI

    はじめに

    今日はSwiftUIの勉強していきます。

    iOS13でダークモードの概念が加わりました。

    iPhoneiPad側の設定で簡単にダークモードとライトモードの切り替えができるようになっています。

    開発者は各モードを対応しないといけないかというとそうではなく、現在(2022年/5月)だと、 ライトモード(従来)だけで審査が通ります。

    なのでダークモード対応という余計な工数がかかる作業は別にしたくないですよね。

    新規プロジェクト作成段階ではライトとダークの両方が有効になっています。

    ということで今回はライトモードだけを有効にする方法を共有したいと思います。

    環境

    この記事の情報は次のバージョンで動作確認しています。

    * MacOS Monterey (12.1)
    * Xcode (13.3.1)

    ライトモードだけにする方法

    ① Info タブ開きます

    ② 一番下の項目の+ボタンをクリックし新しい行を作る

    ③ KeyはAppearanceと打ち込みます

    ④ TypeはStringにします

    ValueLight

    これで完了になります。

    おわりに

    最後まで見ていただきヘペトナス!

    読者登録・Twitterのフォローもお願いします。

    【SwiftUI】sheetによるモーダル画面遷移方法

    Xcode (13.3.1)

    はじめに

    今日はSwitUIの勉強していきます。

    今回はsheetという機能を使った画面遷移について共有したいと思います。

    モーダルで画面遷移する

    まず遷移前画面にて @State Boolな変数を1個作ります。

    この変数をオン・オフして画面の表示切り替えをします。

    // FirstView
    @State private var isShow: Bool = false // 変数名はなんでもいい
    

    画面を表示したいタイミングでisShow(自分がつけた変数名)toggle()とします

    // FirstView
    
     Button(action: { // ボタンなどのイベント処理の中で呼び出します
        self.isShow.toggle()
    })
    

    次画面を表示するにはsheetモディファイアを使います。

    // FirstView
    
    .sheet(isPresented: $isShow) { // ①
       SecondView(isShow: $isShow) // ②
    }
    

    ① isPresentedの引数には$をつけた変数名を指定します

    .sheetの中で遷移先のViewを作ります

    理由は後述しますがSecondViewの引数に$isShowを渡します。

    .sheettoggle()をしたViewではなくてもいいです。

    これで遷移するようになりました。

    全体のコードだとこんな感じになります。

    import SwiftUI
    
    struct FirstView: View {
        
        @State var isShow: Bool = false
        
        init() {
            
        }
        
        var body: some View {
            VStack {
                Button {
                    isShow.toggle()
                } label: {
                     Text("画面遷移")
                }
                .sheet(isPresented: $isShow) {
                    SecondView(isShow: $isShow)
                }
            }
        }
    }
    

    コードで前の画面に戻る方法

    sheetで呼びしたViewは下にスワイプすれば前の画面に戻れます。

    とはいえなんらかの処理をした後に自動で閉じてほしい時もあると思うので、コードで戻る方法を解説します。

    遷移前の画面からイニシャライザでもらったisShowを使います。(そのために渡してました)

    この変数は書き換える前提で使うため@Bindingの変数にしておく必要があります

    // SecondView
    
    @Binding var isShow: Bool
    

    あとは戻りたいタイミングでtoggle()とすれば画面が閉じてくれます。

    Button {
        isShow.toggle() 
    } label: {
        Text("戻ります")}
    

    @Environmentで戻る方法 (iOS15で可)

    参考書などでは@Environment(\.dismiss)を使うやり方が紹介されております。

    ただし@EnvironmentiOS15以上の機能になるので注意が必要です!

    dismissを使うともっと簡単に戻る処理が書くことができます。

    // SecondView
    
    /* @Binding var isShow: Bool これはいらない */
    
    @Environment(\.dismiss) var dismiss
    
    SomeView()
       Button(action: {                                        
           dismiss() // これだけ
       })
    

    dismissは初期化も不要なので遷移前の画面から引数も入りません。使う時もdismiss()だけでいいのですごく楽ちんです。

    dismissを使った場合の遷移前の実装も一応載せておきます。ほぼ一緒ですがSecondViewに渡していたフラグがなくなっています。

     // FirstView
    
     Button(action: {
        self.isShow .toggle()
    })
    .sheet(isPresented: $isShow) { 
       SecondView()  // 引数がなくなってる
    }
    

    おわりに

    最後まで見ていただきヘペトナス!

    読者登録・Twitterのフォローもお願いします。