Je suis en train d'apprendre SwiftUI. Et je suis tombé sur "GeometryReader". Et je veux savoir pourquoi et quand l'utiliser ?
Réponses
Trop de publicités?UPDATE
Depuis que j'ai posté la réponse, j'ai également écrit un article sur le fonctionnement de GeometryReader. Consultez-le pour une explication plus détaillée : https://swiftui-lab.com/geometryreader-to-the-rescue/
GeometryReader est une vue qui vous donne accès à la taille et à la position de son parent. Par exemple :
struct MyView: View {
var body: some View {
GeometryReader { geometry in
// Here goes your view content,
// and you can use the geometry variable
// which contains geometry.size of the parent
// You also have function to get the bounds
// of the parent: geometry.frame(in: .global)
}
}
}
Je le combine généralement avec .background() pour obtenir les limites d'une autre vue. Par exemple, il est difficile de prévoir à l'avance la taille de la vue Text. Lorsque j'ai besoin de cette information, j'utilise cette astuce :
J'ai d'abord défini une vue appelée GeometryGetter :
struct GeometryGetter: View {
@Binding var rect: CGRect
var body: some View {
return GeometryReader { geometry in
self.makeView(geometry: geometry)
}
}
func makeView(geometry: GeometryProxy) -> some View {
DispatchQueue.main.async {
self.rect = geometry.frame(in: .global)
}
return Rectangle().fill(Color.clear)
}
}
Ensuite, pour obtenir les limites d'une vue Texte (ou toute autre vue) :
struct MyView: View {
@State private var rect: CGRect = CGRect()
var body: some View {
Text("some text").background(GeometryGetter($rect))
// You can then use rect in other places of your view:
Rectangle().frame(width: 100, height: rect.height)
}
}
Pour certains cas d'utilisation, j'ai posté des réponses à d'autres questions qui utilisent GeometryReader. Consultez-les :
Déplacez les champs de texte pour éviter qu'ils ne soient masqués par le clavier : https://stackoverflow.com/a/56721268/7786555
Comment faire en sorte que la vue ait la taille d'une autre vue dans SwiftUI : https://stackoverflow.com/a/56661706/7786555
Nota
Dans GeometryGetter, j'ai ajouté un DispatchQueue.main.async {} pour définir le rectangle. Dans certains cas, cela pourrait entraîner un avertissement d'exécution dans le cas contraire : Modification de l'état pendant la mise à jour de la vue .
Ce que l'on appelle Reader
dans SwiftUI ?
En plus de la réponse du kontiki, Reader
sont des vues de conteneurs qui définissent leur contenu comme une fonction. Ainsi, elles peuvent avoir un certain accès et des capacités sur leur parent
. Ce sont des structures génériques si vous regardez de plus près et il y a 2 lecteurs disponibles maintenant dans SwiftUI 2.0 :
Notez qu'il s'agit juste d'une convention, ils ne se conforment pas à un protocole spécial, mais plutôt à l'esprit de l'Union européenne. <code>View</code> protocl. .
GeometryReader
struct GeometryReader<Content: View> : View
Il s'agit d'une vue conteneur qui définit son contenu en fonction de sa propre taille et de son espace de coordonnées. Ainsi, vous pouvez détecter les changements d'image et de position ainsi que l'état actuel de n'importe quelle vue au sein d'une GeometryReader
. L'un des usages populaires de ce lecteur que lorsque vous avez besoin de vues séparées dans des piles distinctes ont les mêmes (ou relative) tailles.
ScrollViewReader
struct ScrollViewReader<Content: View> : View
Il s'agit d'une vue dont l'enfant est défini comme une fonction d'une ScrollViewProxy
ciblant les vues défilantes dans l'enfant. Ainsi, vous pouvez avoir un accès à la vue de défilement comme le défilement vers un élément spécifique d'une liste ou des choses similaires.
Pour minimiser la duplication, je n'ai pas posté d'exemples, vous pouvez vérifier le lien pour plus d'informations si vous voulez