在 SwiftUI (tvOS) 上关注列表中的特定项目

问题描述 投票:0回答:1

我很难弄清楚如何在 SwiftUI 2.0 和 tvOS 14 中关注列表中的特定单元格/行。当我导航到视图时,我需要能够聚焦并选择特定记录。但是,当焦点切换到列表时,某些随机行将获得焦点。我尝试使用 ScrollView 和 List 创建一个项目列表,其中包含按钮作为项目并具有适当的prefersDefaultFocus。什么都不起作用。这是一些示例代码:

struct ChannelListView: View {
    @Namespace private var namespace
    @ObservedObject var viewModel : LiveViewModel
    @State var selection = Set<ChannelItem>()
    var body: some View {
        List(viewModel.channels, selection: $selection){ item in
            ScrollViewReader { proxy in
                        Button(action: {
                        }){
                            ChannelItemView(item: item, selectedItem: $viewModel.selectedChannel, onSelected: { id in
                            })
                            .padding(.vertical, 2)
                        }
                        .buttonStyle(ChannelButtonStyle())
                        .prefersDefaultFocus(item == viewModel.selectedChannel, in: namespace)
            }
        }
        .focusScope(namespace)
    }
}
swiftui tvos
1个回答
0
投票

找到了实现它的方法。使用

defaultFocus
修饰符就可以解决问题。您需要从列表中提供所需的元素作为其参数,另外您需要将优先级指定为
.userInitiated
,没有它,它无法正常工作。 另外,我们跟踪哪个是最后关注的(又名来自
remembersLastFocusedIndexPath
UIKit

@main
struct FocusApp: App {
    var body: some Scene {
        WindowGroup {
            VStack(spacing: 50) {
                CustomRow()
                CustomRow()
            }
        }
    }
}

struct CustomRow: View {
    let items = [1, 2, 3, 4]

    @FocusState private var currentFocusItem: Int?
    @State private var lastFocusItem: Int?

    var body: some View {
        ScrollView(.horizontal) {
            LazyHStack(spacing: 50) {
                ForEach(items, id: \.self) { item in
                    Button { } label: {
                        Text("Item \(item)")
                            .frame(width: 300, height: 300, alignment: .center)
                            .background(Color.red)
                    }
                    .focused($currentFocusItem, equals: item)
                }
            }
        }
        .defaultFocus($currentFocusItem, lastFocusItem ?? items.first, priority: .userInitiated)
        .onChange(of: currentFocusItem) {
            if currentFocusItem != nil {
                lastFocusItem = currentFocusItem
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.