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

SwiftUI自定义ButtonStyle传递字号参数报错问题求助

解决自定义ButtonStyle传递字体大小的问题

正确实现代码

Button(action: {
    bleManager.writeOutgoingValue(data: "sky")
}) {
    Text("Sky")
}
.background(LinearGradient(gradient: Gradient(colors: [Color.blue, Color.white, Color.blue]), startPoint: .leading, endPoint: .trailing))
.foregroundColor(.black)
.buttonStyle(LightButtonStyle1(fontSize: customFontSize.large))
.cornerRadius(5)

struct LightButtonStyle1: ButtonStyle {
    // 将fontSize声明为结构体的存储属性,可设置默认值
    var height: CGFloat = 40
    var width: CGFloat = 140
    var textSidePadding: CGFloat = 4
    var fontSize: CGFloat = 20
    var weight: Font.Weight = .semibold
    var disabled: Bool = false

    // 若需自定义初始化逻辑,直接给结构体属性赋值即可
    init(fontSize: CGFloat, height: CGFloat = 40, width: CGFloat = 140, textSidePadding: CGFloat = 4, weight: Font.Weight = .semibold, disabled: Bool = false) {
        self.fontSize = fontSize
        self.height = height
        self.width = width
        self.textSidePadding = textSidePadding
        self.weight = weight
        self.disabled = disabled
    }

    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .padding([.leading, .trailing], textSidePadding)
            .scaleEffect(configuration.isPressed ? 3 : 1)
            .animation(.easeOut(duration: 0.5), value: configuration.isPressed)
            .font(.system(size: fontSize, weight: weight, design: .default))
            .frame(maxWidth: width, maxHeight: height)
    }
}

错误原因分析

  1. 局部变量作用域问题:你在init里定义的fontVal是局部变量,仅在init方法内部有效,makeBody方法无法访问。需要把跨方法使用的变量声明为结构体的存储属性(放在结构体大括号内、方法外部)。

  2. 错误使用@State:@State是SwiftUI管理视图内部状态的属性包装器,仅适用于View结构体,且不能在init中直接声明。当前场景只是传递外部自定义值,用普通存储属性即可,不需要状态包装。

  3. 字体方法调用错误:.font(.system(size: fontVal: $fontVal, ...))是语法错误,system方法的size参数直接传值即可,$符号用于双向绑定,这里完全不需要。

简化写法(无需自定义init)

如果仅需传递字体大小,其他属性保留默认值,甚至可以不用自定义init,直接像你第一个正常示例那样声明属性,使用时传入对应参数即可:

struct LightButtonStyle1: ButtonStyle {
    var height: CGFloat = 40
    var width: CGFloat = 140
    var textSidePadding: CGFloat = 4
    var fontSize: CGFloat = 20
    var weight: Font.Weight = .semibold
    var disabled: Bool = false

    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .padding([.leading, .trailing], textSidePadding)
            .scaleEffect(configuration.isPressed ? 3 : 1)
            .animation(.easeOut(duration: 0.5), value: configuration.isPressed)
            .font(.system(size: fontSize, weight: weight, design: .default))
            .frame(maxWidth: width, maxHeight: height)
    }
}

// 使用时直接传fontSize参数
.buttonStyle(LightButtonStyle1(fontSize: customFontSize.large))

内容的提问来源于stack exchange,提问作者dmytyk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 15:23:24