我已经设置了一个非常简单的 SwiftUI tvOS 应用程序。我在使用 Focus 引擎时遇到了困难。当应用程序启动时,它的重点是“启动”,这是可以理解的。向下滑动,转到 StackView。在项目上向左/向右滑动效果很好。除了我无法向上滑动以进入“启动”,无论我在哪里尝试。
目标是向上滑动应始终到达“启动”按钮(关注单元格会更改上面的内容)
我在这里做错了什么吗?我的印象是我没有做任何特别或复杂的事情。谢谢
这是我的代码:
struct ContentView: View {
@ObservedObject private var viewModel = EnvironmentsViewModel()
@State private var currentEnvironment: Environment?
var environments: [Environment]?
var body: some View {
GeometryReader { geometry in
VStack(spacing: 50) {
BannerView(environment: currentEnvironment)
.frame(height: geometry.size.height * 0.6)
.clipped()
ScrollView(.horizontal, showsIndicators: false) {
HStack(alignment: .center, spacing: 50) {
ForEach(environments ?? viewModel.environments) { environment in
Button(action: {
currentEnvironment = environment
}) {
EnvironmentCard(title: environment.title, subtitle: "Coming Soon", image: environment.image, isFocused: environment.title == currentEnvironment?.title)
.frame(width: 500, height: geometry.size.height * 0.4)
.edgesIgnoringSafeArea(.all)
}
.buttonStyle(PlainButtonStyle())
}
}
}
.padding(.leading, 50)
.padding(.trailing, 50)
.frame(height: geometry.size.height * 0.4)
}
.edgesIgnoringSafeArea([.top, .leading, .trailing])
.onAppear {
self.viewModel.fetch()
}
}
}
}
struct BannerView: View {
var environment: Environment?
var body: some View {
GeometryReader { geometry in
ZStack {
if let environment = environment, let url = URL(string: environment.image) {
URLImage(url, placeholder: Image("Placeholder")) { proxy in
proxy.image
.resizable()
.aspectRatio(contentMode: .fill)
}
.edgesIgnoringSafeArea(.all)
.frame(height: geometry.size.height)
} else {
Color.darkGray.edgesIgnoringSafeArea(.all)
}
VStack(alignment: .leading, spacing: 10) {
Spacer()
Text(environment?.title ?? "Title")
Text("Description")
Button("Launch", action: {})
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.leading, 50).padding(.bottom, 50)
}
.frame(height: geometry.size.height)
}
}
}
解决方案是将焦点的每一行或级别(每个可聚焦)声明为焦点部分
只需将:
.focusSection()
添加到您想要成为“可聚焦”行的 HStack 视图的末尾
在这里阅读更多内容:
https://developer.apple.com/documentation/swiftui/view/focussection()
所以在你的代码中它应该看起来像这样:
struct ContentView: View {
@ObservedObject private var viewModel = EnvironmentsViewModel()
@State private var currentEnvironment: Environment?
var environments: [Environment]?
var body: some View {
GeometryReader { geometry in
VStack(spacing: 50) {
BannerView(environment: currentEnvironment)
.frame(height: geometry.size.height * 0.6)
.clipped()
.focusSection() // <-------- ADD THIS ############
ScrollView(.horizontal, showsIndicators: false) {
HStack(alignment: .center, spacing: 50) {
ForEach(environments ?? viewModel.environments) { environment in
Button(action: {
currentEnvironment = environment
}) {
EnvironmentCard(title: environment.title, subtitle: "Coming Soon", image: environment.image, isFocused: environment.title == currentEnvironment?.title)
.frame(width: 500, height: geometry.size.height * 0.4)
.edgesIgnoringSafeArea(.all)
}
.buttonStyle(PlainButtonStyle())
}
}
}
.padding(.leading, 50)
.padding(.trailing, 50)
.frame(height: geometry.size.height * 0.4)
.focusSection() // <-------- ADD THIS ############
}
.edgesIgnoringSafeArea([.top, .leading, .trailing])
.onAppear {
self.viewModel.fetch()
}
}
}
}