Swiftui TVO:处理第一个按钮的焦点,以向下导航方向

发布于 2025-02-03 19:38:17 字数 1570 浏览 3 评论 0原文

我想关注底部hstack hstack 的第一个按钮 当用户向下导航时。我该如何实现? 截至目前,该指南正在选择最近的元素。

代码:

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()
        }
    }
}

ScreenShot:

I want to focus on the first Button A of the bottom Hstack when the user navigates downwards. How can I achieve that?
As of now, the guide is picking the nearest element.

Code:

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()
        }
    }
}

Screenshot:

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

抱猫软卧 2025-02-10 19:38:17

我已经使用@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()
        }
    }
}

I've used @FocusState to achieve this. You can bind the focus state of the view to an enum, then create an empty view to intercept/direct focus when it receives focus:

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()
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文