Comment centrer horizontalement un View
(Image
) dans un HStack
? Je veux qu'un bouton soit aligné à gauche et que l'image soit centrée horizontalement sur la vue.
Actuellement, j'ai cette structure:
VStack {
HStack {
Button(action: {
print("Tapped")
}, label: {
Image("left-arrow")
.resizable()
.frame(width: 30, height: 30, alignment: .leading)
}).padding(.leading, 20)
Spacer()
Image("Twitter-logo")
.resizable()
.frame(width: 30, height: 30, alignment: .center)
}
Spacer()
}
Ce qui me donne ceci:
Mais je veux y parvenir:
Mettre à jour:
Qu'en est-il de l'enregistrement de la taille du bouton dans une propriété et d'ajouter un remplissage négatif à l'image? Et faites attention à une entretoise supplémentaire après l'image.
struct ContentView: View {
var buttonSize: Length = 30
var body: some View {
VStack {
HStack {
Button(action: {
print("Tapped")
}, label: {
Image(systemName: "star")
.resizable()
.frame(width: buttonSize, height: buttonSize, alignment: .leading)
})
Spacer()
Image(systemName: "star")
.resizable()
.frame(width: 30, height: 30, alignment: .center)
.padding(.leading, -buttonSize)
Spacer()
}
Spacer()
}
}
}
Le résultat:
Vous pouvez incorporer deux HStack
dans un ZStack
et placer des entretoises en conséquence pour l'espacement horizontal. Intégrez tout cela dans un VStack
avec une Spacer()
pour que tout soit poussé vers le haut.
struct ContentView : View {
var buttonSize: Length = 30
var body: some View {
VStack {
ZStack {
HStack {
Button(action: {
}, label: {
Image(systemName: "star")
.resizable()
.frame(width: CGFloat(30), height: CGFloat(30), alignment: .leading)
}).padding(.leading, CGFloat(20))
Spacer()
}
HStack {
Image(systemName: "star")
.resizable()
.frame(width: CGFloat(30), height: CGFloat(30), alignment: .center)
}
}
Spacer()
}
}
}
Remarque: Dans le second HStack
, l'image doit automatiquement être alignée au centre, mais si ce n'est pas le cas, vous pouvez placer une Spacer()
avant et après l'image.
Edit: Ajout de la fonction VStack
et Spacer()
pour tout déplacer vers le haut comme l'OP le souhaitait.
Edit 2: Suppression du rembourrage sur l'image car cela entraînait un léger décalage de l'image par rapport au centre. Comme il est dans son propre HStack
et aligné au centre, il n'a pas besoin de remplissage.
Edit 3: Merci à @Chris Prince dans les commentaires, j'ai décidé de créer une simple vue personnalisée NavigationBar que vous pouvez fournir des arguments gauche, central et droit pour créer l'effet souhaité par l'OP (où chaque ensemble de vues est aligné indépendamment les uns des autres):
struct CustomNavBar<Left, Center, Right>: View where Left: View, Center: View, Right: View {
let left: () -> Left
let center: () -> Center
let right: () -> Right
init(@ViewBuilder left: @escaping () -> Left, @ViewBuilder center: @escaping () -> Center, @ViewBuilder right: @escaping () -> Right) {
self.left = left
self.center = center
self.right = right
}
var body: some View {
ZStack {
HStack {
left()
Spacer()
}
center()
HStack {
Spacer()
right()
}
}
}
}
Utilisation :
struct ContentView: View {
let buttonSize: CGFloat = 30
var body: some View {
VStack {
CustomNavBar(left: {
Button(action: {
print("Tapped")
}, label: {
Image(systemName: "star")
.resizable()
.frame(width: self.buttonSize, height: self.buttonSize, alignment: .leading)
}).padding()
}, center: {
Image(systemName: "star")
.resizable()
.frame(width: 30, height: 30, alignment: .center)
}, right: {
HStack {
Text("Long text here")
Image(systemName: "star")
.resizable()
.frame(width: 30, height: 30, alignment: .center)
.padding(.trailing)
}.foregroundColor(.red)
})
Spacer()
Text("Normal Content")
Spacer()
}
}
}
Vous centrez la vue en utilisant la propriété position essayez ce code
Group{ // container View
Image("Twitter-logo")
.resizable()
.frame(width: 30, height: 30, alignment: .center)
}.position(x: UIScreen.main.bounds.width/2)