首页 > 解决方案 > 循环遍历描述按键后应在屏幕上执行的操作的实体

问题描述

如果我没有很好地描述这个问题,请原谅我,我是使用 Swift 编写 MacOS 应用程序的新手。我知道我这样做的方式可能是错误的,我只需要有人告诉我正确的方式。

我的主应用程序屏幕

我有一个 Core Data 应用程序,它存储一个名为 Items 的有序实体列表。这些项目旨在描述一个活动中的一个步骤,该步骤描述了屏幕上应该发生的事情。如果您知道 Mac 应用程序 QLab,则每个 Item 就像 QLab 中的单个提示。

我创建了一个 Activity 类,旨在通读每个 Item 以确定 Item 类型及其相关信息。一旦确定了 Item 类型,Activity 类需要提供一个 View,其中包含与该特定 Item 相关的信息,然后等到用户按下右箭头键,然后继续到 Core Data 存储中的下一个 Item,该过程重复直到已阅读所有项目。每次在循环中读取一个新项目时,用户每次按下右箭头后,屏幕上的信息都会发生变化。

问题是我不确切知道如何以编程方式解决这个问题。我有检索项目数组作为 NSFetchRequest 的代码:

let moc = (NSApplication.shared.mainWindow?.contentViewController?.representedObject as! NSPersistentDocument).managedObjectContext!
    let fetchRequest : NSFetchRequest = Item.fetchRequest()
    do {
        let items = try moc.fetch(fetchRequest)
        print("Found " + String(items.count) + " items to use in the activity.")
        for item in items {
            print(item.itemType)
    // How do I pause this loop for a user keypress after using data from this Item to display?
        }
    } catch {
        print("Error retrieving Items")
    }

我可以使用检索 keydown 事件NSEvent.addLocalMonitorForEvents(matching: .keyDown),还可以创建视图控制器以在第二个屏幕上显示信息。我只是不知道我应该如何创建“主循环”,可以这么说,以便显示信息,然后应用程序等到用户按下一个键继续......

如果需要更多信息,我可以分享我的项目代码,非常感谢任何可以启发我的人...... :)

标签: swiftxcodemacosloopsonkeypress

解决方案


您可以尝试使用NSPageController。在您的 NSPageController 中,您添加一个 ContainerView,它将显示 ViewControllers,显示每个项目的信息。每个 ViewController 都需要一个故事板标识符,例如ViewControllerItem1

您的 NSPageController 类必须符合 NSPageControllerDelegate 协议并包含要显示的 ViewController 数组。

override func viewDidLoad() {
    super.viewDidLoad()
    delegate = self
    arrangedObjects = ["ViewControllerItem1", "ViewControllerItem2", "...","ViewControllerItemN" ]
}

注意NSPageController 文档中的arrangedObjects:一个包含页面控制器视图中显示的对象的数组。

然后你实现 NSPageControllersviewControllerForIdentifier来返回你当前想要在 ContainerView 中显示的 ViewController。

func pageController(_ pageController: NSPageController, viewControllerForIdentifier identifier: String) -> NSViewController {

switch identifier {
    case "ViewControllerItem1":
        return mainStoryboard().instantiateController(withIdentifier:"ViewControllerItem1") as? ViewControllerItem1
    case "...":
    default:
    }
}

在您实现的按键按下事件的操作处理程序中。

self.navigateForward(sender) or self.navigateBack(sender)

我也实现了这个方法,但我不记得是否需要它。

func pageControllerDidEndLiveTransition(_ pageController: NSPageController) {
    self.completeTransition()
}

推荐阅读