31
votes

Comment rendre la largeur de vue égale à Superview dans SwiftUI

J'ai Button

entrez la description de l'image ici

struct ContentView : View {
    var body: some View {
        HStack {
            Button(action: {}) {
                Text("MyButton")
                    .color(.white)
                    .font(Font.system(size: 17))
            }
            .frame(height: 56)
            .background(Color.red, cornerRadius: 0)
        }
    }
}

Mais je veux l'épingler sur les bords de supreview (à la fin de la fin et au début de superview). Comme ça:

entrez la description de l'image ici

HStack ne HStack pas, et il attend. Le frame fixe ou la largeur égale UIScree.size ne sont pas des solutions flexibles.


0 commentaires

5 Réponses :


1
votes

J'ai trouvé une solution:

var body: some View {
    Button(action: {}) {
            HStack {
                Spacer()
                Text("MyButton")
                    .color(.white)
                    .font(Font.system(size: 17))
                Spacer()
            }
            .frame(height: 56)
            .background(Color.red, cornerRadius: 0)
        }.padding(20)
}

Mais je ne suis pas sûr que ce soit le meilleur. Peut-être que quelqu'un trouvera une solution plus élégante /


1 commentaires

Un problème ici est que le bouton peut être tapé en dehors de ses limites visibles. Cela signifie que l'utilisateur peut taper de manière incorrecte sur un bouton, même s'il tapait sur des espaces.



24
votes

Vous pouvez utiliser GeometryReader : https://developer.apple.com/documentation/swiftui/geometryreader

Selon Apple:

Cette vue renvoie une taille préférée flexible à sa disposition parente.

entrez la description de l'image ici

C'est une solution flexible, car elle change en fonction des changements de mise en page parent.


1 commentaires

Je peux confirmer que cela fonctionne pour définir le bouton pour classer toute la largeur, mais je ne parviens pas à ajouter de rembourrage à l'une ou l'autre taille du bouton.



56
votes

Vous devez utiliser le .frame(minWidth: 0, maxWidth: .infinity)

Ajouter le code suivant

        Button(action: tap) {
            Text("Button")
                .frame(minWidth: 0, maxWidth: .infinity)
                .background(Color.red)
        }
        .padding([.leading, .trailing], 20)

Le modificateur de remplissage vous permettra d'avoir un peu d'espace sur le bord.

Gardez à l'esprit que l'ordre des modificateurs est important . Parce que les modificateurs sont en fait des fonctions qui enveloppent la vue ci-dessous (ils ne changent pas les propriétés des vues)


4 commentaires

.infinity est une bonne chose, merci! Mais il est impossible de définir certains instets à superviser. Mais si vous définissez .frame (minWidth: 0, maxWidth: .infinity) sur Text , et ajoutez padding() à Button - cela fonctionnera!


Comment puis-je ajouter une hauteur spécifique pour le bouton? Par exemple, si je dois définir la hauteur du bouton à 43 pixels, comment puis-je faire cela?


Un petit ajout, c'est que vous pouvez maintenant utiliser le .padding(.horizontal, 20) si vous voulez le rembourrage des deux côtés, sans mentionner la gauche et la droite individuellement.


Pourquoi minWidth: 0? Lorsque je le supprime, je trouve ma vue plus grande que la vue parent. Je ne comprends pas la logique ici



4
votes

L'ajout simple de suivi à votre code fera que le bouton s'étendra d'un bord à l'autre. (Vous pouvez également ajouter un rembourrage si vous le souhaitez)

struct ContentView : View {
    var body: some View {
        HStack {
            Button(action: {}) {
                Text("MyButton")
                    .color(.white)
                    .font(Font.system(size: 17))
            }
            .frame(minWidth: 0, maxWidth: .infinity)
            .padding(.top, 8)
            .padding(.bottom, 8)
            .background(Color.red, cornerRadius: 0)
        }
    }
}

L'ensemble du code du bouton ressemblera à ceci:

.frame(minWidth: 0, maxWidth: .infinity)


0 commentaires

0
votes

Voici une solution SwiftUI pure où vous voulez remplir la largeur du parent mais contraindre la hauteur à un rapport hauteur / largeur arbitraire (disons que vous voulez des images carrées):

            ZStack {
                Image("myImage")
                    .resizable()
                    .scaledToFill()
                    .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
                    .clipped()
            }
            .aspectRatio(1.0, contentMode: .fill)

Remplacez simplement 1.0 par le rapport hauteur / largeur souhaité.

J'ai passé environ une journée à essayer de comprendre cela parce que je ne voulais pas utiliser GeometryReader ou UIScreen.main.bounds (qui n'est pas multiplateforme)


0 commentaires