【问题标题】:How to change border of image in button on press using SwiftUI?如何使用 SwiftUI 在按下按钮时更改图像的边框?
【发布时间】:2021-01-13 09:55:22
【问题描述】:

我有一个由图像和一些文本组成的 NavigationLink,我想在按下链接时更改图像的边框颜色。

这是导航链接:

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 的特定部分(在本例中为图像的边框)。

【问题讨论】:

    标签: animation button swiftui swiftui-navigationlink


    【解决方案1】:

    您可以使用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()
                }))
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      由于在 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)
                              })
                              
                          })
                      
                  }
              }
          }
      

      【讨论】:

      • 我认为 OP 想要唯一的图像,而不是整个按钮。
      • @RajaKishan 是的
      猜你喜欢
      • 2020-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-20
      • 1970-01-01
      相关资源
      最近更新 更多