So im building my first App im trying to get some Text below the Button, but it should still be a part of the button. So thats what i got:
`Button{
print("tapped")
} label: {
Image("Wand")
.resizable()
.frame(width: 100, height: 100)
}
.font(.title3)
.background(Color.gray)
.foregroundColor(.black)
.cornerRadius(20)`
this looks like this: Button
But i want it like this: Button2
Ive tryed putting an "VStack" into the Label but the Text stays in the gray button
CodePudding user response:
I think it may help you
public struct VerticalLabelStyle: LabelStyle {
public let spacing: CGFloat
public init(spacing: CGFloat = 8) {
self.spacing = spacing
}
public func makeBody(configuration: Configuration) -> some View {
VStack(alignment: .center, spacing: spacing) {
configuration.icon
configuration.title
}
}
}
public struct ContentView: View {
@State private var text: String = ""
public var body: some View {
Label {
Text(text)
} icon: {
Image(systemName: "gamecontroller.fill")
.resizable()
.frame(width: 44, height: 44, alignment: .center)
}
.frame(width: 100, height: 100)
.labelStyle(VerticalLabelStyle())
.onTapGesture(perform: onTap)
}
func onTap() {
text = "tapped"
}
}
If you have some questions please ask
CodePudding user response:
Your idea with a VStack is the correct way. You just have to keep in mind where to place your modifiers. In your case you placed them on the button level. Meaning they are applied to the entire label, which is the reason why your Text is inside the gray background. Just update also the place of your modifiers inside your VStack. Here is are short example:
Button {
// Your button action
} label: {
VStack {
RoundedRectangle(cornerRadius: 25)
.frame(width: 100, height: 100)
.padding()
.background(Color.black) // new position of background modifier that is only applied on your Image (here a rectangle)
Text("Foo")
.font(.title3)
.foregroundColor(.black)
// These modifiers could stay on button level, but I moved them here to explicitly show where they applied
}
}
Keep in mind you can put any view inside the label of your button and that in this case the Text is part of the button and will trigger the action if a user taps on it. If you only want that the Image is the tap action wrap your button inside a VStack containing only the Image and a Text as the second part of the Stack like this:
VStack {
Button {
// Your button action
} label: {
VStack {
RoundedRectangle(cornerRadius: 25)
.frame(width: 100, height: 100)
.padding()
.background(Color.black)
}
}
Text("Foo")
.font(.title3)
.foregroundColor(.black)
}