如何使用 SwiftUI 在按下按钮时更改图像边框?
How to change border of image in button on press using SwiftUI?
我有一个由图像和一些文本组成的 NavigationLink,我想在按下 link 时更改图像的边框颜色。
这是导航链接:
NavigationLink(destination: TrickSelectView()) {
HStack{
Image("learnTricksButton")
.resizable()
.clipShape(Circle())
.overlay(Circle().stroke(Color(red: 0.95, green: 0.32, blue: 0.34), lineWidth: 4))
.shadow(radius: 7)
.frame(width: width, height: width)
VStack{
Text("Trick")
.font(.system(.largeTitle, design: .rounded))
.foregroundColor(Color(red: 0.13, green: 0.15, blue: 0.22))
Text("Personalise your learning!")
.font(.system(.subheadline, design: .rounded))
.foregroundColor(Color(red: 0.28, green: 0.32, blue: 0.37))
}
}.padding(.bottom, 50)
}.buttonStyle(LearnButtonEffect())
这是我目前为止获得的按钮样式:
struct LearnButtonEffect: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.background(configuration.isPressed ? Color.green.opacity(0.5) : Color.green)
.shadow(color: Color.gray, radius: 10, x: 0, y: 0)
.scaleEffect(configuration.isPressed ? 0.9 : 1.0)
}
}
总的来说,我想知道如何在按钮样式定义中引用 NavigationLink 的特定部分(在本例中是图像的边框)。
因为在 SwiftUI 中,我们不保留对任何视图的任何引用。相反,我们更改值(@State
、@Binding
、@ObservableObject
、@StatObject
..)反映视图。
struct ContentView: View {
@State var isActive = false //To start navigation
@State var isClicked = false //to track wather click
var body: some View {
NavigationView {
NavigationLink(
destination: Text("Destination"),
isActive: $isActive,
label: {
Button(action: {
isActive = true
isClicked = true
}, label: {
HStack{
Image("learnTricksButton")
.resizable()
.clipShape(Circle())
.overlay(Circle().stroke(isClicked ? Color.black:Color(red: 0.95, green: 0.32, blue: 0.34), lineWidth: 4))
.shadow(radius: 7)
.frame(width: 100, height: 100)
VStack{
Text("Trick")
.font(.system(.largeTitle, design: .rounded))
.foregroundColor(Color(red: 0.13, green: 0.15, blue: 0.22))
Text("Personalise your learning!")
.font(.system(.subheadline, design: .rounded))
.foregroundColor(Color(red: 0.28, green: 0.32, blue: 0.37))
}
}.padding(.bottom, 50)
})
})
}
}
}
您可以使用 PrimitiveButtonStyle
并传递特定视图并执行您的操作。
这是演示:
创建样式
struct LearnButtonEffectButtonStyle: PrimitiveButtonStyle {
var image: Image
var action: () -> Void
func makeBody(configuration: PrimitiveButtonStyle.Configuration) -> some View {
ButtonView(configuration: configuration, image: image, action: action)
}
struct ButtonView: View {
@State private var pressed = false
let configuration: PrimitiveButtonStyle.Configuration
let image: Image
var action: () -> Void
var body: some View {
return HStack{
image
.resizable()
.clipShape(Circle())
.overlay(Circle().stroke(self.pressed ? Color.yellow : Color.blue, lineWidth: 4)) // <<- You can change here .overlay(Circle().stroke(self.pressed ? Color.yellow : Color.blue, lineWidth: 4))
.shadow(radius: 7)
.frame(width: 100, height: 50)
.border(self.pressed ? Color.yellow : Color.blue, width: 2) //<<- remove it if not required
configuration.label
}
.padding(.bottom, 50)
.onLongPressGesture(minimumDuration: 0.2, maximumDistance: .infinity, pressing: { pressing in
withAnimation(.easeInOut(duration: 0.2)) {
self.pressed = pressing
}
if !pressing {
action()
}
}, perform: {
print("Perform")
})
.background(self.pressed ? Color.green.opacity(0.5) : Color.green)
.shadow(color: Color.gray, radius: 10, x: 0, y: 0)
.scaleEffect(self.pressed ? 0.9 : 1.0)
}
}
}
如何使用?
struct ContentView: View {
@State private var isActive = false
var body: some View {
NavigationView{
NavigationLink(destination: Text("test"), isActive: $isActive) {
VStack{
Text("Trick")
.font(.system(.largeTitle, design: .rounded))
.foregroundColor(Color(red: 0.13, green: 0.15, blue: 0.22))
Text("Personalise your learning!")
.font(.system(.subheadline, design: .rounded))
.foregroundColor(Color(red: 0.28, green: 0.32, blue: 0.37))
}
}.buttonStyle(LearnButtonEffectButtonStyle(image: Image("learnTricksButton"), action: {
self.isActive.toggle()
}))
}
}
}
我有一个由图像和一些文本组成的 NavigationLink,我想在按下 link 时更改图像的边框颜色。
这是导航链接:
NavigationLink(destination: TrickSelectView()) {
HStack{
Image("learnTricksButton")
.resizable()
.clipShape(Circle())
.overlay(Circle().stroke(Color(red: 0.95, green: 0.32, blue: 0.34), lineWidth: 4))
.shadow(radius: 7)
.frame(width: width, height: width)
VStack{
Text("Trick")
.font(.system(.largeTitle, design: .rounded))
.foregroundColor(Color(red: 0.13, green: 0.15, blue: 0.22))
Text("Personalise your learning!")
.font(.system(.subheadline, design: .rounded))
.foregroundColor(Color(red: 0.28, green: 0.32, blue: 0.37))
}
}.padding(.bottom, 50)
}.buttonStyle(LearnButtonEffect())
这是我目前为止获得的按钮样式:
struct LearnButtonEffect: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.background(configuration.isPressed ? Color.green.opacity(0.5) : Color.green)
.shadow(color: Color.gray, radius: 10, x: 0, y: 0)
.scaleEffect(configuration.isPressed ? 0.9 : 1.0)
}
}
总的来说,我想知道如何在按钮样式定义中引用 NavigationLink 的特定部分(在本例中是图像的边框)。
因为在 SwiftUI 中,我们不保留对任何视图的任何引用。相反,我们更改值(@State
、@Binding
、@ObservableObject
、@StatObject
..)反映视图。
struct ContentView: View {
@State var isActive = false //To start navigation
@State var isClicked = false //to track wather click
var body: some View {
NavigationView {
NavigationLink(
destination: Text("Destination"),
isActive: $isActive,
label: {
Button(action: {
isActive = true
isClicked = true
}, label: {
HStack{
Image("learnTricksButton")
.resizable()
.clipShape(Circle())
.overlay(Circle().stroke(isClicked ? Color.black:Color(red: 0.95, green: 0.32, blue: 0.34), lineWidth: 4))
.shadow(radius: 7)
.frame(width: 100, height: 100)
VStack{
Text("Trick")
.font(.system(.largeTitle, design: .rounded))
.foregroundColor(Color(red: 0.13, green: 0.15, blue: 0.22))
Text("Personalise your learning!")
.font(.system(.subheadline, design: .rounded))
.foregroundColor(Color(red: 0.28, green: 0.32, blue: 0.37))
}
}.padding(.bottom, 50)
})
})
}
}
}
您可以使用 PrimitiveButtonStyle
并传递特定视图并执行您的操作。
这是演示:
创建样式
struct LearnButtonEffectButtonStyle: PrimitiveButtonStyle {
var image: Image
var action: () -> Void
func makeBody(configuration: PrimitiveButtonStyle.Configuration) -> some View {
ButtonView(configuration: configuration, image: image, action: action)
}
struct ButtonView: View {
@State private var pressed = false
let configuration: PrimitiveButtonStyle.Configuration
let image: Image
var action: () -> Void
var body: some View {
return HStack{
image
.resizable()
.clipShape(Circle())
.overlay(Circle().stroke(self.pressed ? Color.yellow : Color.blue, lineWidth: 4)) // <<- You can change here .overlay(Circle().stroke(self.pressed ? Color.yellow : Color.blue, lineWidth: 4))
.shadow(radius: 7)
.frame(width: 100, height: 50)
.border(self.pressed ? Color.yellow : Color.blue, width: 2) //<<- remove it if not required
configuration.label
}
.padding(.bottom, 50)
.onLongPressGesture(minimumDuration: 0.2, maximumDistance: .infinity, pressing: { pressing in
withAnimation(.easeInOut(duration: 0.2)) {
self.pressed = pressing
}
if !pressing {
action()
}
}, perform: {
print("Perform")
})
.background(self.pressed ? Color.green.opacity(0.5) : Color.green)
.shadow(color: Color.gray, radius: 10, x: 0, y: 0)
.scaleEffect(self.pressed ? 0.9 : 1.0)
}
}
}
如何使用?
struct ContentView: View {
@State private var isActive = false
var body: some View {
NavigationView{
NavigationLink(destination: Text("test"), isActive: $isActive) {
VStack{
Text("Trick")
.font(.system(.largeTitle, design: .rounded))
.foregroundColor(Color(red: 0.13, green: 0.15, blue: 0.22))
Text("Personalise your learning!")
.font(.system(.subheadline, design: .rounded))
.foregroundColor(Color(red: 0.28, green: 0.32, blue: 0.37))
}
}.buttonStyle(LearnButtonEffectButtonStyle(image: Image("learnTricksButton"), action: {
self.isActive.toggle()
}))
}
}
}