How can I create a button with image in SwiftUI?
Go to the image and change the Render As "Original Image"
SwiftUI - Button action draws on an image
I'm not 100% sure if I understand this correctly, but it's simply a matter of displaying an image when a button is clicked?
You already said that you got an image with the desired behavior, but you don't want it to be there from the beginning. I think you are looking for an alternative in SwiftUI for addSubview
, but there is no direct one.
What you might be looking for is @State
in SwiftUI. Changing a @State
variable will force your view to redraw itself. (There are more then just @State
variables that to this)
You can draw your Image based on a condition. On your button click you could change the state variable that your condition is based on to redraw your view and to display your Image. I use the toggle() function in my example, so clicking the Button a second time will result in removing the image.
import SwiftUI
struct ContentView: View {
@State private var showImage = false
var body: some View {
VStack {
if showImage {
Image(systemName: "gear") // Your working image
}
Button(action: {
self.showImage.toggle()
}, label: {
Text("draw image")
})
}
}
}
Here is an example how you could add more and more Images when clicking the button again and again. I changed the Type of the @State
variable to an array and then iterate over that array via a ForEach
.
import SwiftUI
struct ContentView: View {
@State private var images: [UUID] = []
var body: some View {
VStack {
ForEach(images, id: \.self) { _ in
Image(systemName: "gear") // Your working image
}
Button(action: {
self.images.append(UUID())
}, label: {
Text("draw image")
})
}
}
}
Picture and text when clicking on the button. SwiftUI
You can use an if
clause to conditionally display elements based on a @State
variable.
I'm using the extra frame
modifier on the VStack
that you didn't originally have to make sure that nothing changes position when the @State
variable changes and the elements inside the stack appear/disappear.
struct ContentView : View {
@State private var showImage = false
var body: some View {
VStack {
VStack {
if showImage {
Image(systemName: "house.fill").resizable().aspectRatio(contentMode: .fill).frame(width: 75, height: 75)
Text("TEST")
}
}.frame(height: 100)
Spacer().frame(height: 100)
Button(action: { showImage.toggle() }) {
Text("TEST").foregroundColor(Color.white).padding()
}.background(Color.black) .cornerRadius(10) }
}
}
How to set image to button in SwiftUI?
You could implement it as:
Button(action: {}) {
HStack(alignment: .center, spacing: 5.0) {
Image("cart")
.padding(.leading, 10.0)
Text("Add to Cart")
.foregroundColor(.black)
.padding(.all, 10.0)
}
}
.background(Color.gray)
.cornerRadius(5.0)
Passing HStack
instead of Text
would do the trick.
To clarify, adding an image next to the button label is not directly related to the button anymore! When creating a button using init(action:label:)
initializer, we are passing () -> Label
as the second parameter; If you trace the type of Label
, you'll see that it is basically a View
, so you are not forced to return a Text
type for it (as mentioned in the question's code snippet).
Obviously, you could add the image to the right of the label by adding Text
before the Image
. Also, if you are aiming to add the text on top of the image (or vice-versa), you could simply replace the HStack
with a VStack
.
Furthermore, more reusable code
You could make your code to be more reusable by creating a custom body View
for the button. Also, you could create a custom ViewModifier
:
import SwiftUI
// Custom View
struct CustomButtonBody: View {
private var iconName: String
private var title: String
init(iconName: String = "cart", title: String) {
self.iconName = iconName
self.title = title
}
var body: some View {
HStack(alignment: .center, spacing: 5.0) {
Image(iconName)
.padding(.leading, 10.0)
Text(title)
.foregroundColor(.black)
.padding(.all, 10.0)
}
}
}
// Custom Modifier
struct CustomButtonModifier: ViewModifier {
func body(content: Content) -> some View {
return content
.background(Color.gray)
.cornerRadius(5.0)
}
}
thus:
Button(action: {}) {
CustomButtonBody(title: "Add to Cart")
}
.modifier(CustomButtonModifier())
How we can change text of button when a button is clicked for list items in SwiftUI?
If I understand the question correctly, try this approach by removing all toggleText
and using @Ali Momeni advice:
struct ContentView: View {
@State var showAnswer = false
@State private var selectedRestaurant: Restaurant?
@State private var restaurants = [ Restaurant(name: "Cafe Deadend", image: "cafedeadend"),
Restaurant(name: "Homei", image: "homei"),
Restaurant(name: "Teakha", image: "teakha"),
Restaurant(name: "Cafe Loisl", image: "cafeloisl"),
Restaurant(name: "Petite Oyster", image: "petiteoyster"),
Restaurant(name: "For Kee Restaurant", image: "forkeerestaurant")
]
private func RestaurantRow(restaurant: Restaurant) -> some View {
BasicImageRow(restaurant: restaurant)
.contextMenu {
Button(action: {
showAnswer = true
setFavorite(item: restaurant)
}) {
HStack {
Text(restaurant.isFavorite ? "UnFavorite" : "Favorite")
Image(systemName: "star")
}
}
}.id(restaurant.id)
.onTapGesture {
selectedRestaurant = restaurant
}
.actionSheet(item: $selectedRestaurant) { restaurant in
ActionSheet(title: Text("What do you want to do"),
message: nil,
buttons: [
.default(
Text(restaurant.isFavorite ? "Mark as UnFavorite" : "Mark as Favorite"),
action: {
setFavorite(item: restaurant)
}),
.cancel()
])
}
}
var body: some View {
List {
ForEach(restaurants) { restaurant in
if restaurant.isFavorite {
RestaurantRow(restaurant: restaurant)
} else {
RestaurantRow(restaurant: restaurant)
}
}
}
}
private func setFavorite(item restaurant: Restaurant) {
if let index = restaurants.firstIndex(where: { $0.id == restaurant.id }) {
restaurants[index].isFavorite.toggle()
}
}
}
Related Topics
How to Use Gpx File for UI Tests Only
Reload Tableview After Clicking The Button Present Inside One of The Tableview Cell in Swift
Switch Statement Where Value Is Int But Case Can Contain Array
Why Is This Predicate Format Being Turned into '= Nil'
Swiftui New App Lifecycle How to Connect The Facebook Sdk
How to Insert a Row in Tableview Without Using Reloaddata Function in Cocoa
Audiounit Callback and Synchronization: How to Ensure Thread Safety with Gcd
Realitykit - Add Force to Entity at Specific Point
How to Refer to a Global Type from Within a Class That Has a Nested Type with The Same Name
Exc Bad Access While Creating a New Characterset
How to Allow a Generic Collection to Perform Under The Hood Conversion in Swift
How to Convert an Array to List in Realm
Do Not Copy Swift Libraries with Xcode 8
How to Make UItabbar Image Rounded in Swift Programmatically
Urlcomponents Queryitems Losing Percent Encoding When Mutated