【问题标题】:How to scroll through items in scroll view using keyboard arrows in SwiftUI?如何使用 SwiftUI 中的键盘箭头在滚动视图中滚动项目?
【发布时间】:2022-11-12 07:35:39
【问题描述】:

我已经使用 HStack for macOS 应用程序构建了一个具有水平类型滚动视图的视图。有没有办法使用键盘箭头圈出这些项目?

(我看到 ListView 具有默认行为,但对于其他自定义视图类型则没有)

click here to see the screenshot

var body: some View {
   VStack {
     ScrollView(.horizontal, {
        HStack {
          ForEach(items.indices, id: \.self) { index in
               //custom view for default state and highlighted state
          }
        }
     }
    }
}


any help is appreciated :)

【问题讨论】:

  • 这回答了你的问题了吗? SwiftUI keyboard navigation in lists on MacOS
  • @workingdogsupportUkraine 不幸的是不,它使用 List 而在我的情况下我不能使用 List 因为它必须水平滚动
  • 使用水平滚动添加了答案。

标签: ios swift swiftui scrollview hstack


【解决方案1】:

我使用的方法

  • 在按钮上使用键盘快捷键

替代方法

代码:

模型

struct Item: Identifiable {
    var id: Int
    var name: String
}

class Model: ObservableObject {
    @Published var items = (0..<100).map { Item(id: $0, name: "Item ($0)")}
}

内容

struct ContentView: View {
    
    @StateObject private var model = Model()
    @State private var selectedItemID: Int?
    
    var body: some View {
        VStack {
            Button("move right") {
                moveRight()
            }
            .keyboardShortcut(KeyEquivalent.rightArrow, modifiers: [])
            
            
            ScrollView(.horizontal) {
                LazyHGrid(rows: [GridItem(.fixed(180))]) {
                    ForEach(model.items) { item in
                        ItemCell(
                            item: item,
                            isSelected: item.id == selectedItemID
                        )
                        .onTapGesture {
                            selectedItemID = item.id
                        }
                    }
                }
            }
        }
    }
    
    private func moveRight() {
        if let selectedItemID {
            if selectedItemID + 1 >= model.items.count {
                self.selectedItemID = model.items.last?.id
            } else {
                self.selectedItemID = selectedItemID + 1
            }
        } else {
            selectedItemID = model.items.first?.id
        }
    }
}

细胞

struct ItemCell: View {
    let item: Item
    let isSelected: Bool
    var body: some View {
        ZStack {
            Rectangle()
                .foregroundColor(isSelected ? .yellow : .blue)
            Text(item.name)
        }
    }
}

【讨论】:

    【解决方案2】:

    您可以使用我以前的帖子尝试此操作,但使用水平滚动视图而不是列表。您必须将代码调整为您的特定应用程序。

    import Foundation
    import SwiftUI
    import AppKit
    
    
    struct ContentView: View {
        let fruits = ["apples", "pears", "bananas", "apricot", "oranges"]
        @State var selection: Int = 0
        
        var body: some View {
            ScrollView(.horizontal) {
                HStack(alignment: .center, spacing: 0) {
                    ForEach(fruits.indices, id: .self) { index in
                        VStack {
                            Image(systemName: "globe")
                                .resizable()
                                .scaledToFit()
                                .frame(width: 20, height: 20)
                                .padding(10)
                            Text(fruits[index]).tag(index)
                        }
                        .background(selection == index ? Color.red : Color.clear)
                        .padding(10)
                    }
                }
            }
            .onAppear {
                NSEvent.addLocalMonitorForEvents(matching: [.keyDown]) { nsevent in
                    if nsevent.keyCode == 124 { // arrow right
                        selection = selection < fruits.count ? selection + 1 : 0
                    } else {
                        if nsevent.keyCode == 123 { // arrow left
                            selection = selection > 1 ? selection - 1 : 0
                        }
                    }
                    return nsevent
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-06
      • 2011-05-16
      • 1970-01-01
      • 1970-01-01
      • 2011-03-13
      相关资源
      最近更新 更多