struct Item: Identifiable {
let id = UUID()
let title: String
}
struct ContentView: View {
let items = [Item(title: "One"), Item(title: "Two"), Item(title: "Three")]
var body: some View {
NavigationStack {
ScrollView (showsIndicators: false) {
ForEach(items) { item in
NavigationLink {
ItemDetailView(item: item)
} label: {
ItemView(item: item)
}
//how to disable the default NavigationLink pressed state styling?
}
}
}
.padding()
}
}
#Preview {
ContentView()
}
struct ItemView: View {
let item: Item
@State var isPressed = false //how to change this?
var body: some View {
HStack {
Text(item.title)
.foregroundStyle(.purple)
.multilineTextAlignment(.leading)
Spacer()
}
.frame(maxWidth: .infinity)
.padding()
.background(isPressed ? .blue : .green)
.clipShape(RoundedRectangle(cornerRadius: 10))
.border(.red, width: isPressed ? 2 : 0)
.padding(3)
}
}
struct ItemDetailView: View {
let item: Item
var body: some View {
Text(item.title)
}
}
I don't want the default grayed-out pressed state of the NavigationLink. When the view is pressed, I want the background color to change to blue and the red border to be displayed. The scrollview should still work - once the user starts scrolling the view should go back to its normal, unpressed state (as it normally does).
You can apply a ButtonStyle
to a NavigationLink
. This lets you apply a different style when the button is pressed.
So, all you need to do is move the styling from ItemView
to a custom ButtonStyle
. If you want the red border to have rounded corners (like the button background) then you need to apply it as an overlay.
struct MyNavViewButton: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.frame(maxWidth: .infinity)
.padding()
.foregroundStyle(.purple)
.background(configuration.isPressed ? .blue : .green)
.clipShape(RoundedRectangle(cornerRadius: 10))
.overlay {
RoundedRectangle(cornerRadius: 10)
.stroke(.red, lineWidth: configuration.isPressed ? 2 : 0)
}
.padding(3)
}
}
struct ItemView: View {
let item: Item
var body: some View {
HStack {
Text(item.title)
.multilineTextAlignment(.leading)
Spacer()
}
}
}
// ContentView
ForEach(items) { item in
NavigationLink {
ItemDetailView(item: item)
} label: {
ItemView(item: item)
}
.buttonStyle(MyNavViewButton())
}