【问题标题】:SwiftUI tvOS: Handle focus for first button on navigating downwards directionSwiftUI tvOS:处理向下导航的第一个按钮的焦点
【发布时间】:2022-08-17 06:09:21
【问题描述】:

我想专注于第一个按钮当用户向下导航时,底部HstackA。我怎样才能做到这一点? 截至目前,指南正在选择最近的元素。

代码:

import SwiftUI

struct DummyView: View {
    @Environment(\\.presentationMode) var presentationMode

    var body: some View {
        contentView
        parent
    }

    private var parent: some View {
        VStack {
            if #available(tvOS 15.0, *) {
                HStack {
                    Spacer()
                    Button (\"1\") {}
                    Button (\"2\") {}
                    Button (\"3\") {}
                    Spacer()
                }
                .focusSection()
                .border(Color.white, width: 2)
            } else {
                // Fallback on earlier versions
            }

            Spacer()
            if #available(tvOS 15.0, *) {
                HStack {
                    Button (\"A\") {}
                    Spacer()
                    Button (\"B\") {}
                    Spacer()
                    Button (\"C\") {}
                }
                .border(Color.white, width: 2)
                .focusSection()
            } else {
                // Fallback on earlier versions
            }
        }
    }

    private var contentView: some View {
        VStack {
            Spacer()
            Text(\"THIS IS DUMMY SCREEN\")
            Spacer()
        }
    }
}

截屏:

  • 阅读 Apple Human interface Guidelines for tvOS... 这个设计不符合它,所以你有麻烦。我怀疑苹果是否会在商店接受它。
  • 实际上代码太长了,所以我添加了我的问题的较小版本。你能帮助我吗 ?

标签: swift swiftui tvos uifocusguide


【解决方案1】:

我使用@FocusState 来实现这一点。您可以将视图的焦点状态绑定到枚举,然后创建一个空视图以在收到焦点时拦截/直接焦点:

import SwiftUI

struct DummyView: View {
    @Environment(\.presentationMode) var presentationMode

    var body: some View {
        contentView
        parent
    }
    
    enum FocusAreas {
        case button1
        case button2
        case button3
        case focusGuide
        case buttonA
        case buttonB
        case buttonC
    }
    
    @FocusState var focusState: FocusAreas?

    private var parent: some View {
        VStack {
            if #available(tvOS 15.0, *) {
                HStack {
                    Spacer()
                    Button ("1") {}
                        .focused($focusState, equals: .button1)
                    Button ("2") {}
                        .focused($focusState, equals: .button2)
                    Button ("3") {}
                        .focused($focusState, equals: .button3)
                    Spacer()
                }
                .border(Color.white, width: 2)
            } else {
                // Fallback on earlier versions
            }
            Color.clear
                .frame(height: 1)
                .frame(maxWidth: .infinity)
                .focusable()
                .focused($focusState, equals: .focusGuide)
                .onChange(of: focusState, perform: {[focusState] newFocus in
                    if(newFocus == .focusGuide) {
                        switch(focusState){
                        case .button1,.button2,.button3:
                            self.focusState = .buttonA
                        default:
                            //Add custom behaviors when navigating up here from buttons A,B,C here
                            self.focusState = .button1
                            break
                        }
                    }
                })
            Spacer()
            if #available(tvOS 15.0, *) {
                HStack {
                    Button ("A") {}
                        .focused($focusState, equals: .buttonA
                        )
                    Spacer()
                    Button ("B") {}
                        .focused($focusState, equals: .buttonB)
                    Spacer()
                    Button ("C") {}
                        .focused($focusState, equals: .buttonC)
                }
                .border(Color.white, width: 2)
            } else {
                // Fallback on earlier versions
            }
        }
    }

    private var contentView: some View {
        VStack {
            Spacer()
            Text("THIS IS DUMMY SCREEN")
            Spacer()
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多