【问题标题】:SwiftUI + Dynamic action closure for ButtonSwiftUI + Button 的动态操作闭包
【发布时间】:2020-04-10 20:26:59
【问题描述】:

我正在探索 SwiftUI,并且能够创建 Button 的子类。

子类包含image & title 属性,这使它成为一个可重用的组件。

但我无法为 Button 类定义动态操作行为。

请参考下面的代码。

圆形按钮的子类:

struct RoundButton: View {
    var image: String
    var title: String
    var body: some View {
        VStack {
            Button(action: {
                print("Button pressed")
            }){
                Image(image)                
                   .renderingMode(Image.TemplateRenderingMode?.init(Image.TemplateRenderingMode.template))
            }
            .frame(width: 40, height: 40)
            .background(Color.blue)
            .cornerRadius(20)
            .accentColor(.white)

            Text(title)
                .font(.footnote)
        }
    }
}

使用示例:

HStack(alignment: .center) {
    Spacer(minLength: 50)
    RoundButton(image: "chat", title: "message")
    Spacer()
    RoundButton(image: "call", title: "call")
    Spacer()
    RoundButton(image: "video", title: "video")
    Spacer()
    RoundButton(image: "mail", title: "mail")
    Spacer(minLength: 50)
}

您将在此处看到action 块打印一条消息。

我想知道我们如何为按钮的动作事件传递函数?

【问题讨论】:

    标签: swift button swiftui


    【解决方案1】:

    按钮更新...

    struct RoundButton: View {
        var image: String
        var title: String
        var action: () -> Void
    
        var body: some View {
            VStack {
                Button(action: action){
                    Image(image)
                       .renderingMode(Image.TemplateRenderingMode?.init(Image.TemplateRenderingMode.template))
                }
        ...
    

    使用更新...

    RoundButton(image: "chat", title: "message") {
        print("Button pressed")
    }
    

    【讨论】:

    • 我不完全明白你是怎么做到的,但这太棒了!
    • 嗨,我想知道我们如何在单击该按钮时转到特定视图,这意味着我需要传递一个视图而不是仅仅打印一些文本。你能帮我解决一下吗?
    • @Fattie:愿我的回答对您也有用。我也只是添加了新的答案。
    【解决方案2】:

    这是另一种方法,您可以直接创建自定义按钮而无需对其进行操作!如果您需要执行某个操作,您也可以执行此操作,例如 ContentView 中的示例:

    PS:我注意到你刚刚给 Image 赋予了点击或点击的可能性,这使得点击或点击更加困难!相反,您可以将所有内容放在 VStack 中,这样可以更轻松地为用户点击或单击,并且可以更好地点击动画。而且你不需要使用cornerRadius来制作圆形,你可以使用clipShape。

    struct RoundButton: View {
        
        var image: String
        var title: String
        var action: (() -> Void)?
        
        init(image: String, title: String, action: (() -> Void)? = nil) {
            self.image = image
            self.title = title
            self.action = action
        }
        
        var body: some View {
            VStack {
                Button(action: {
                    action?()
                }){
                    VStack {
                        Image(image)
                            .renderingMode(Image.TemplateRenderingMode?.init(Image.TemplateRenderingMode.template))
                            .frame(width: 40, height: 40)
                            .background(Color.blue)
                            .foregroundColor(.white)
                            .clipShape(Circle())
    
                        Text(title)
                            .font(.footnote)
                            .foregroundColor(.black) 
                    }
                }
            }
        }
    }
    

    用例:

    struct ContentView: View {
        
        var body: some View {
            
            RoundButton(image: "person", title: "person")
    
            RoundButton(image: "person", title: "person", action: { print("Button pressed") })
    
            RoundButton(image: "person", title: "person") {
                print("Button pressed") 
            }
    
        }
    }
    

    【讨论】:

    • Button 不采取行动有什么意义?用户会期望两个看起来相同的元素具有相同的行为,例如成为一个按钮。我正在使用类似的东西,但在没有操作时也会禁用按钮,但它仍然与问题无关。
    • @PhilipDukhov:基本上我们可以在需要时使用不带任何操作的按钮!例如,您可以通过操作开始工作,并且在某些情况下,如果用户点击,您可以给出 nil 值!另一个原因是 UI 问题,例如,您正在设计视图,并且只想将对象和事物放在视图中,然后开始给出真正的代码操作!希望对您有所帮助。
    • 将堆栈 inside 放置在按钮上是个不错的主意,@swiftPunk 欢呼
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-28
    • 2020-06-12
    • 2022-11-19
    • 2014-08-29
    • 2021-07-19
    • 2017-09-12
    相关资源
    最近更新 更多