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

Xcode 11 Beta 7中SwiftUI Picker功能异常问题咨询

SwiftUI Picker选中项无勾选、点击无响应(Xcode 11 Beta 7)

我刚碰到过类似的问题,结合你的代码来看,这主要是Xcode 11 Beta7对SwiftUI和Combine的行为做了严格调整,加上你的代码里有两个小细节没跟上版本变化,导致了这个问题。

问题原因分析

  1. Picker的selection与tag类型不匹配
    你的Picker绑定的是$userSettings.fontName(FontName枚举类型),但每个选项的.tag()传的是fontName.rawValue(String类型)。在之前的Beta版本里可能还能兼容,但Beta7开始对Picker的selection和tag类型一致性要求非常严格——类型不匹配的话,Picker无法正确识别选中状态,也无法响应用户的选择操作。

  2. ObservableObject的手动事件发送冗余
    你在@Published var fontName的willSet里手动调用了objectWillChange.send(),但在Beta7中,@Published属性已经会自动触发objectWillChange事件,手动发送反而会导致状态更新逻辑混乱,进而影响Picker的状态同步。

修复方案

1. 修正Picker的tag类型

把每个选项的tag从rawValue改成枚举本身,让它和selection的类型完全一致:

Picker(selection: $userSettings.fontName, label: Text("Font Type")) {
    ForEach(fontNames, id: \.self) { fontName in
        Text(fontName.rawValue).tag(fontName) // 改为传递FontName枚举实例
            .font(FontFactory.noteFont(for: fontName))
    }
}

2. 优化UserSettings的ObservableObject实现

删掉手动声明的objectWillChange和willSet里的事件发送,让@Published自动处理状态更新:

import Foundation
import Combine

class UserSettings: ObservableObject {
    // 移除手动声明的objectWillChange,@Published会自动使用默认的Subject
    enum StringSettingsKey: String {
        case fontName
    }
    struct Default {
        static let fontName = FontName.sanFrancisco
    }
    
    @Published var fontName: FontName = Default.fontName {
        didSet {
            set(string: fontName.rawValue, for: .fontName)
        }
        // 移除手动的willSet逻辑
    }
    
    init() {
        setFromUserDefaults(settingsKey: .fontName)
    }
    
    private func setFromUserDefaults(settingsKey: StringSettingsKey) {
        if let storedString = UserDefaults.standard.string(forKey: settingsKey.rawValue) {
            switch settingsKey {
            case .fontName:
                fontName = FontName(rawValue: storedString) ?? Default.fontName
            }
        }
    }
    
    private func set(string: String, for settingsKey: StringSettingsKey) {
        UserDefaults.standard.set(string, forKey: settingsKey.rawValue)
    }
    
    private func storedString(for settingsKey: StringSettingsKey) -> String? {
        return UserDefaults.standard.string(forKey: settingsKey.rawValue)
    }
}

额外说明

Xcode的Beta版本本身就是用来测试API稳定性的,每个版本都会调整一些细节——这次的问题就是典型的「旧代码适配新Beta版本的API变化」,不是你的代码逻辑有根本性错误,只是没跟上版本的严格要求。修改完这两处之后,Picker应该就能恢复正常的选中标记和响应逻辑了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:36:21