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

iOS17中绑定带Equatable的ObservableObject时Custom ToggleStyle不重绘

SwiftUI自定义ToggleStyle在iOS17不刷新的问题

当前配置

模型

Book.swift

import SwiftUI
final class Book: ObservableObject {
    @Published var games: [Game] = []
    
    init() {
        self.games = [Game(), Game(), Game()]
    }
}

Game.swift

final class Game: ObservableObject, Identifiable, Equatable {
    var id: UUID = UUID()
    @Published var isSelected: Bool = false
    
    init() {}
    
    static func ==(lhs: Game, rhs: Game) -> Bool {
        lhs.id == rhs.id
    }
}

视图

ContentView.swift

struct ContentView: View {
    @StateObject var book: Book = Book()

    var body: some View {
        Games(games: $book.games)
    }
}

Games.swift

struct Games: View {
    @Binding var games: [Game]

    var body: some View {
        ForEach($games) { game in
            Toggle("Game", isOn: game.isSelected)
                .toggleStyle(CustomToggleStyle())
        }
    }
}

ToggleStyle

CustomToggleStyle.swift

struct CustomToggleStyle: ToggleStyle {
    func makeBody(configuration: Configuration) -> some View {
        Button {
            configuration.isOn.toggle()
        } label: {
            Text(configuration.isOn ? "On" : "Off")
        }
    }
}

问题

当前配置会渲染3个对应Book中Game实例的Toggle,点击时isSelected的值能正确更新,但自定义的CustomToggleStyle始终显示"Off",视图不会跟随状态刷新。

预期行为

点击Toggle时,isSelected值切换,视图同步显示"On"或"Off"。

已发现现象

  • 移除Game类的Equatable协议后功能恢复正常,原因不明;
  • 将ForEach直接放到ContentView中、省略带Binding的Games中间视图,也能恢复正常,原因不明。

疑问

  1. 当前代码是否存在导致异常的问题?
  2. 移除Equatable为何会影响Toggle的表现?
  3. 省略中间Binding视图为何能修复问题?

上下文

  • 测试环境为Playground App;
  • 代码在iOS16上运行正常,仅iOS17出现该问题。

内容的提问来源于stack exchange,提问作者Luïs

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 20:56:17