You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

除扩展Button外,是否有其他实现ButtonStyle条件切换的方案?

SwiftUI实现ButtonStyle条件切换的替代方案

你提到无法直接使用.buttonStyle(selected : .bordered : .borderedProminent)的写法(推测是语法书写错误,正确的三元表达式应为selected ? .bordered : .borderedProminent),除了扩展Button类之外,还有以下几种实用的替代方案:

方案一:直接使用三元运算符(修正语法后)

.bordered和.borderedProminent同属PrimitiveButtonStyle类型,完全可以通过三元表达式直接传入buttonStyle修饰符,这是最简洁的写法:

struct DepartureArrivalView: View {
    @Binding var value: String
    @Binding var selected: Bool
    
    var body: some View {
        VStack(spacing: 0) {
            Button {
                
            } label: {
                Text(value)
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .font(.title)
            }
            .buttonStyle(selected ? .bordered : .borderedProminent)
            .padding(16)
        }
    }
}

方案二:自定义条件ButtonStyle结构体

通过实现PrimitiveButtonStyle协议封装条件逻辑,适合需要在多个视图中复用该样式规则的场景:

// 封装条件样式的结构体
struct ConditionalButtonStyle: PrimitiveButtonStyle {
    let isSelected: Bool
    
    func makeBody(configuration: Configuration) -> some View {
        if isSelected {
            configuration.label.buttonStyle(.bordered)
        } else {
            configuration.label.buttonStyle(.borderedProminent)
        }
    }
}

// 视图中使用自定义样式
struct DepartureArrivalView: View {
    @Binding var value: String
    @Binding var selected: Bool
    
    var body: some View {
        VStack(spacing: 0) {
            Button {
                
            } label: {
                Text(value)
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .font(.title)
            }
            .buttonStyle(ConditionalButtonStyle(isSelected: selected))
            .padding(16)
        }
    }
}

方案三:内联@ViewBuilder条件判断

无需扩展或自定义结构体,直接在修饰链中通过@ViewBuilder实现分支逻辑,适合临时场景:

struct DepartureArrivalView: View {
    @Binding var value: String
    @Binding var selected: Bool
    
    var body: some View {
        VStack(spacing: 0) {
            // 内联判断样式
            @ViewBuilder
            let styledButton = Button {
                
            } label: {
                Text(value)
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .font(.title)
            }
            .applyStyle(selected)
            
            styledButton.padding(16)
        }
    }
}

// 辅助扩展让内联逻辑更清晰
extension View {
    @ViewBuilder
    func applyStyle(_ isSelected: Bool) -> some View {
        if isSelected {
            self.buttonStyle(.bordered)
        } else {
            self.buttonStyle(.borderedProminent)
        }
    }
}

内容的提问来源于stack exchange,提问作者Jason Rich Darmawan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 03:53:14