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

在tvOS的SwiftUI中使用.focused(_:equals:)实现自定义视图可聚焦

解决方案

要让自定义视图配合FocusState和.focused(_:equals:)实现焦点切换时的缩放效果,需要解决两个核心问题:让自定义视图可聚焦,以及同步焦点状态到视图内部的缩放逻辑。

步骤1:修改自定义视图,使其可聚焦并感知焦点状态

自定义视图默认不具备焦点能力,必须添加.focusable()修饰符。同时,通过@Environment(\.isFocused)可以直接获取当前视图的焦点状态,无需手动传递绑定,更符合SwiftUI的设计逻辑:

public struct SimpleView: View {
    // 通过环境变量获取当前视图的焦点状态
    @Environment(\.isFocused) private var isFocused

    public init() {}

    public var body: some View {
        RoundedRectangle(cornerRadius: 20)
            .fill(.green)
            .scaleEffect(isFocused ? 1.0 : 0.8)
            .animation(.easeInOut, value: isFocused)
            .focusable() // 关键:让自定义视图具备接收焦点的能力
    }
}

步骤2:调整容器视图,关联焦点枚举与自定义视图

容器视图中只需保留@FocusState变量,并用.focused(_:equals:)修饰符将每个SimpleView与对应的枚举值绑定即可:

public enum EnumView: Hashable {
    case one, two, three
}

public struct GalleryView: View {
    @FocusState private var fokus: EnumView?

    public init() {}

    public var body: some View {
        HStack(alignment: .center) {
            SimpleView()
                .focused($fokus, equals: .one)
                .onChange(of: fokus) { newFocus in
                    print("New focus: \(newFocus)")
                }

            SimpleView()
                .focused($fokus, equals: .two)
                .onChange(of: fokus) { newFocus in
                    print("New focus: \(newFocus)")
                }

            SimpleView()
                .focused($fokus, equals: .three)
                .onChange(of: fokus) { newFocus in
                    print("New focus: \(newFocus)")
                }
        }
    }
}

原代码失效原因

  1. 自定义视图不可聚焦:原生控件(如Button)默认自带.focusable(),但自定义视图需要手动添加该修饰符才能成为焦点目标。
  2. 焦点状态未同步:原代码中SimpleView的@State focused是内部独立状态,无法感知外部.focused(_:equals:)标记的焦点变化,导致缩放逻辑无法触发。

现在你可以通过方向键横向切换焦点,每个SimpleView会根据自身焦点状态自动放大或缩小。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 20:34:52