I have a SwipeActions on my list so when the user swipes on a list row, it give's them the option to delete the current list cell. I have a button inside the SwipeActions that handles the deletion. But the actual problem is inside the label for the button. Currently I have a Text displaying "Delete" with a red background. However, when I try anything else other than Text, it doesn't display it, and it defaults to displaying "Delete" nothing else.
.swipeActions {
Button {
context.delete(todo)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
if let category = todo.categories,
category.todos.isEmpty {
context.delete(category)
}
}
} label: {
// Display a custom UI here
Text("Delete")
}
.tint(.red)
}
I created a custom UI I want to display for that Delete button
struct CellDeleteButton: View {
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 15)
.foregroundStyle(.red)
.frame(width: 90, height: 30)
Text("Delete")
.foregroundStyle(.text)
.font(.regularText.bold())
}
}
}
Now when I use that custom design for the Button, it doesn't display it and only shows "Delete"
} label: {
CellDeleteButton()
}
Here is what shows after I call CellDeleteButton()
I have attempted to look for tutorials on how to do this but I can't seem to find any
The end goal is to replace "Delete" with a custom UI I created.
The answer to Showing image and text in swipe actions in SwiftUI shows how you can create an image from drawing instructions and use this as the label for the swipe action (it was my answer).
If you want the icon to fill the full height of the row then it works best to give the image square proportions. However, since you are using a capsule shape, it works fine to use the dimensions of the capsule.
struct CellDeleteButton: View {
let iconSize = CGSize(width: 90, height: 30)
var body: some View {
Image(
size: iconSize,
label: Text("Delete")
) { ctx in
let path = Path(
roundedRect: CGRect(origin: .zero, size: iconSize),
cornerRadius: iconSize.height / 2
)
ctx.fill(path, with: .color(.red))
ctx.draw(
Text("Delete"),
at: CGPoint(x: iconSize.width / 2, y: iconSize.height / 2),
anchor: .center
)
}
.fontWeight(.bold)
.foregroundStyle(.white)
}
}
By default, a gray background will be shown around the image. To avoid this, apply a .tint
to the button using the same background as for the list row. Using UIColor.secondarySystemGroupedBackground
will match the default background in both light and dark modes:
Button {
print("delete")
} label: {
CellDeleteButton()
}
.tint(Color(.secondarySystemGroupedBackground))