web-dev-qa-db-ja.com

SwiftUIでビューを動的に非表示にする

SwiftUIでDatePickerを条件付きで非表示にしようとしています。ただし、タイプが一致しないと問題が発生します。

_var datePicker = DatePicker($datePickerDate)
if self.showDatePicker {
    datePicker = datePicker.hidden()
}
_

この場合、datePickerは_DatePicker<EmptyView>_タイプですが、datePicker.hidden()は__ModifiedContent<DatePicker<EmptyView>, _HiddenModifier>_です。そのため、datePicker.hidden()datePickerに割り当てることができません。私はこれのバリエーションを試しましたが、うまくいく方法を見つけることができないようです。何か案は?

[〜#〜]更新[〜#〜]

__ModifiedContent_タイプのラップを解除して、contentプロパティを使用して基になるタイプを取得できます。ただし、これは根本的な問題を解決しません。 contentプロパティは、元の変更されていない日付ピッカーであるように見えます。

22
Jake

変数を動的に設定してビューで使用するのではなく、次のように日付ピッカーを非表示または表示できることがわかりました。

struct ContentView : View {
    @State var showDatePicker = true
    @State var datePickerDate: Date = Date()

    var body: some View {
        VStack {
            if self.showDatePicker {
                DatePicker($datePickerDate)
            } else {
                DatePicker($datePickerDate).hidden()
            }
        }
    }
}

または、オプションで、日付ピッカーを非表示にするのではなく、含めません。

struct ContentView : View {
    @State var showDatePicker = true
    @State var datePickerDate: Date = Date()

    var body: some View {
        VStack {
            if self.showDatePicker {
                DatePicker($datePickerDate)
            }
        }
    }
}
21
Jake

私はエクステンションを作成したので、モディファイアを使用して、ビューを非表示にすることができます。

Text("Hello World!")
    .isHidden(true)

または完全に削除するには:

Text("Label")
    .isHidden(true, remove: true)

サンプルプロジェクトのソースコードは、GitHubの George-J-E/HidingViews で入手できます。


ViewModifierを作成するコードは次のとおりです:

このコードを独自のファイルで使用することをお勧めします(import SwiftUI):

extension View {

    /// Hide or show the view based on a boolean value.
    ///
    /// Example for visibility:
    /// ```
    /// Text("Label")
    ///     .isHidden(true)
    /// ```
    ///
    /// Example for complete removal:
    /// ```
    /// Text("Label")
    ///     .isHidden(true, remove: true)
    /// ```
    ///
    /// - Parameters:
    ///   - hidden: Set to `false` to show the view. Set to `true` to hide the view.
    ///   - remove: Boolean value indicating whether or not to remove the view.
    func isHidden(_ hidden: Bool, remove: Bool = false) -> some View {
        modifier(HiddenModifier(isHidden: hidden, remove: remove))
    }
}


/// Creates a view modifier to show and hide a view.
///
/// Variables can be used in place so that the content can be changed dynamically.
fileprivate struct HiddenModifier: ViewModifier {

    private let isHidden: Bool
    private let remove: Bool

    init(isHidden: Bool, remove: Bool = false) {
        self.isHidden = isHidden
        self.remove = remove
    }

    func body(content: Content) -> some View {
        Group {
            if isHidden {
                if remove {
                    EmptyView()
                } else {
                    content.hidden()
                }
            } else {
                content
            }
        }
    }
}
18
George_E

代わりにアルファを設定できます。これにより、ビューのレイアウトスペースも保持され、他の回答のようにダミービューを追加する必要もありません。

struct ContentView : View {
    @State var showDatePicker = true
    @State var datePickerDate: Date = Date()

    var body: some View {
        VStack {
            DatePicker($datePickerDate)
            .opacity(showDatePicker ? 1 : 0)
        }
    }
}

hidden修飾子が後で引数を取得することを願っています。

9

問題のビューをコマンドキーを押しながらクリックして、ベータ5で[条件付きにする]オプションを選択します。これを自分のビューの1つ(LiftsCollectionView)で実行すると、以下が生成されます。

    if suggestedLayout.size.height > 150 {
      LiftsCollectionView()
    } else {
      EmptyView()
    }
3
Justin Ekins

また、opacity修飾子はViewにあります。

ActivityIndicator(tint: .black)
   .opacity(self.isLoading ? 1.0 : 0.0)
0
PiKey