J'essaie de masquer conditionnellement un DatePicker
dans SwiftUI. Cependant, je rencontre des problèmes avec les types incompatibles:
var datePicker = DatePicker($datePickerDate)
if self.showDatePicker {
datePicker = datePicker.hidden()
}
Dans ce cas, datePicker
est un type DatePicker<EmptyView>
Mais datePicker.hidden()
est un _ModifiedContent<DatePicker<EmptyView>, _HiddenModifier>
. Je ne peux donc pas affecter datePicker.hidden()
à datePicker
. J'ai essayé des variantes de cela et je n'arrive pas à trouver un moyen qui fonctionne. Des idées?
MISE À JOUR
Vous pouvez déballer le type _ModifiedContent
Pour obtenir le type sous-jacent à l'aide de sa propriété content
. Cependant, cela ne résout pas le problème sous-jacent. La propriété content
semble être simplement le sélecteur de date d'origine et non modifié.
Plutôt que de définir dynamiquement une variable et de l'utiliser à mon avis, j'ai constaté que j'étais en mesure de masquer ou d'afficher le sélecteur de date de cette façon:
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()
}
}
}
}
Ou, éventuellement, sans inclure le sélecteur de date au lieu de le masquer:
struct ContentView : View {
@State var showDatePicker = true
@State var datePickerDate: Date = Date()
var body: some View {
VStack {
if self.showDatePicker {
DatePicker($datePickerDate)
}
}
}
}
J'ai créé une extension, vous pouvez donc utiliser un modificateur, comme ça pour masquer la vue:
Text("Hello World!")
.isHidden(true)
Ou pour un retrait complet:
Text("Label")
.isHidden(true, remove: true)
Le code source avec un exemple de projet est disponible sur GitHub ici: George-J-E/HidingViews .
Voici le code pour créer le ViewModifier
:
Je vous recommande d'utiliser ce code dans son propre fichier (n'oubliez pas de 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
}
}
}
}
Vous pouvez définir l'alpha à la place, cela préservera également l'espace de mise en page de la vue et ne vous obligera pas à ajouter des vues factices comme les autres réponses:
struct ContentView : View {
@State var showDatePicker = true
@State var datePickerDate: Date = Date()
var body: some View {
VStack {
DatePicker($datePickerDate)
.opacity(showDatePicker ? 1 : 0)
}
}
}
J'espère que le modificateur hidden
obtiendra un argument plus tard.
Commande-cliquez sur la vue en question et sélectionnez l'option Rendre conditionnel dans la version bêta 5. Je l'ai fait sur l'une de mes vues (LiftsCollectionView), et cela a généré ce qui suit:
if suggestedLayout.size.height > 150 {
LiftsCollectionView()
} else {
EmptyView()
}
Vous avez également le modificateur opacity
sur n'importe quel View
:
ActivityIndicator(tint: .black)
.opacity(self.isLoading ? 1.0 : 0.0)