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

为SwiftUI的@State属性添加自定义属性包装器遇错求助

解决SwiftUI中@State与自定义属性包装器的兼容问题

你遇到的错误是因为属性包装器的应用顺序和类型不匹配:当前写法是让@Trimmed包装@State<String>实例,但你的Trimmed包装器仅针对String类型设计,无法处理State<String>,因此出现类型转换错误。

下面提供两种可行的解决方案:

方案一:修改Trimmed包装器,集成状态管理功能

直接让Trimmed内部封装@State,无需同时使用两个属性包装器,既保留自动trim逻辑,又能支持SwiftUI的状态绑定:

@propertyWrapper
struct Trimmed {
    private var state: State<String>
    private let characterSet: CharacterSet

    var wrappedValue: String {
        get { state.wrappedValue }
        set { state.wrappedValue = newValue.trimmingCharacters(in: characterSet) }
    }

    // 提供Binding支持,供SwiftUI控件使用
    var projectedValue: Binding<String> {
        state.projectedValue
    }

    // 默认初始化器:自动去除空白和换行符
    init(wrappedValue: String) {
        self.characterSet = .whitespacesAndNewlines
        self.state = State(wrappedValue: wrappedValue.trimmingCharacters(in: self.characterSet))
    }

    // 自定义字符集的初始化器
    init(wrappedValue: String, characterSet: CharacterSet) {
        self.characterSet = characterSet
        self.state = State(wrappedValue: wrappedValue.trimmingCharacters(in: characterSet))
    }
}

使用方式(无需再写@State):

struct Login: View {
    @Trimmed(characterSet: .whitespaces)
    private var userName: String = ""

    var body: some View {
        VStack {
            TextEditor(text: $userName)
        }
    }        
}

方案二:通过自定义Binding实现自动trim

如果不想修改原有的Trimmed包装器,也可以直接在TextEditor的绑定中处理trim逻辑,保留@State的使用:

struct Login: View {
    @State private var userName: String = ""

    var body: some View {
        VStack {
            TextEditor(text: Binding(
                get: { userName },
                set: { userName = $0.trimmingCharacters(in: .whitespaces) }
            ))
        }
    }        
}

方案对比

  • 方案一:封装性强,适合在多个视图中复用自动trim的逻辑,代码更整洁。
  • 方案二:轻量灵活,无需修改原有包装器,适合单个视图的简单需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 01:53:14