我在全局垂直列表中有多个可滚动水平列表,并且很难管理焦点更改。
我有两个主要问题:
当一个视图下面没有另一个视图时,底部手势不会更新焦点。我希望焦点移动到下面的视图附近。在我的 GIF 示例中,从第 1 部分的第四个视图到第 2 部分的第二个视图。
当某个视图正下方没有另一个视图时,底部手势会将焦点移动到垂直下方的视图。我希望焦点移动到最近的底部视图。在我的示例中,从第 1 节第三视图到第 2 节第二视图,而不是第 3 节第三视图。
@Environment(\.resetFocus) var resetFocus我在我的 tvOS 应用程序中有很多这个问题的例子,我通过使用 viewModifier和viewModifier的组合来解决这些问题prefersDefaultFocus,但我在这个用例上遇到了困难。
我还看到了关于这个问题的另一个类似的用例,但还没有答案。
struct ContentView: View {
var body: some View {
VStack(alignment: .leading) {
Text("Section 1")
ScrollView(.horizontal) {
HStack() {
ForEach(0 ..< 10) { item in
Button(action: {
}) {
FocusableRectangle()
}.buttonStyle(CardButtonStyle())
}
}.padding(40)
}
Text("Section 2")
ScrollView(.horizontal) {
HStack() {
ForEach(0 ..< 2) { item in
Button(action: {
}) {
FocusableRectangle()
}.buttonStyle(CardButtonStyle())
}
}.padding(40)
}
Text("Section 3")
ScrollView(.horizontal) {
HStack() {
ForEach(0 ..< 3) { item in
Button(action: {
}) {
FocusableRectangle()
}.buttonStyle(CardButtonStyle())
}
}.padding(40)
}
Spacer()
}
}
}
struct FocusableRectangle: View {
@Environment(\.isFocused) var isFocused: Bool
@State var color = Color.blue
var body: some View {
Rectangle()
.fill(color)
.frame(width: 300.0, height: 200.0)
.onChange(of: isFocused, perform: { value in
color = value ? Color.red : Color.blue
})
}
}
Run Code Online (Sandbox Code Playgroud)
我想知道您是否尝试过.focusSection()在不同的 ScrollView 部分上添加与 tvOS 15 一起出现的内容?
这就是你的 ContentView 的样子:
struct ContentView: View {
var body: some View {
VStack(alignment: .leading) {
Text("Section 1")
ScrollView(.horizontal) {
HStack {
ForEach(0..<10) { _ in
Button(action: {}) {
FocusableRectangle()
}.buttonStyle(CardButtonStyle())
}
}.padding(40)
}.focusSection()
Text("Section 2")
ScrollView(.horizontal) {
HStack {
ForEach(0..<2) { _ in
Button(action: {}) {
FocusableRectangle()
}.buttonStyle(CardButtonStyle())
}
}.padding(40)
}.focusSection()
Text("Section 3")
ScrollView(.horizontal) {
HStack {
ForEach(0..<3) { _ in
Button(action: {}) {
FocusableRectangle()
}.buttonStyle(CardButtonStyle())
}
}.padding(40)
}.focusSection()
Spacer()
}
}
}
Run Code Online (Sandbox Code Playgroud)
它应该能够达到目的并实现可理解的焦点模式。
希望能帮助到你。
小智 4
您需要将每个部分插入到容器中,例如Group或ZStack。然后,您可以尝试覆盖.onMoveCommandwith.up和.downinstructions 以设置当前选定的部分。现在,您可以.prefersDefaultFocus为每个部分设置条件。当选择发生变化时,您还需要调用resetFocus。
struct ContentView: View {
@Namespace var mainNamespace
@Environment(\.resetFocus) var resetFocus
@State private var selectedSection = SelectedSection.sec_1
var body: some View {
VStack(alignment: .leading) {
Text("Section 1")
Group(){
ScrollView(.horizontal) {
HStack() {
ForEach(0 ..< 10) { item in
Button(action: {
}) {
FocusableRectangle()
}.buttonStyle(CardButtonStyle())
}
}.padding(40)
}
}.onMoveCommand(){direction in
print(direction)
if direction == .down{
self.selectedSection = SelectedSection.sec_2
}
}.prefersDefaultFocus(self.selectedSection == SelectedSection.sec_1, in: mainNamespace)
Text("Section 2")
Group(){
ScrollView(.horizontal) {
HStack() {
ForEach(0 ..< 2) { item in
Button(action: {
}) {
FocusableRectangle()
}.buttonStyle(CardButtonStyle())
}
}.padding(40)
}
}.onMoveCommand(){direction in
print(direction)
if direction == .down{
self.selectedSection = SelectedSection.sec_3
}
if direction == .up{
self.selectedSection = SelectedSection.sec_1
}
}.prefersDefaultFocus(self.selectedSection == SelectedSection.sec_2, in: mainNamespace)
Text("Section 3")
Group(){
ScrollView(.horizontal) {
HStack() {
ForEach(0 ..< 3) { item in
Button(action: {
}) {
FocusableRectangle()
}.buttonStyle(CardButtonStyle())
}
}.padding(40)
}
}.onMoveCommand(){direction in
print(direction)
if direction == .up{
self.selectedSection = SelectedSection.sec_2
}
}.prefersDefaultFocus(self.selectedSection == SelectedSection.sec_3, in: mainNamespace)
Spacer()
}
.focusScope(mainNamespace)
.onAppear(){
print(selectedSection)
}
.onChange(of: self.selectedSection){newValue in
resetFocus(in: mainNamespace)
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1474 次 |
| 最近记录: |