- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
手头的问题是响应者链。据 Apple 称:
In addition, in macOS 10.10 and later, a view controller participatesin the responder chain. NSViewController
如果我在 macOS Storyboard中使用 standard segue,目标 View Controller 的行为符合预期——焦点、等效键、响应链等。
但是,如果我使用自定义 segue,目标 View Controller 不会按预期运行 :( 具体来说,关键等效项神秘地无法工作 — 然而,在测试中,来自 source View Controller 的按钮上的等效键继续工作(这没有帮助/不需要)
在 macOS 10.12 上,我正在使用以下自定义转场……我做错了什么?
class PushSegue: NSStoryboardSegue {
override func perform() {
(sourceController as AnyObject).presentViewController(destinationController as! NSViewController, animator: PushAnimator())
}
}
class PushAnimator: NSObject, NSViewControllerPresentationAnimator {
func animatePresentation(of viewController: NSViewController, from fromViewController: NSViewController) {
viewController.view.wantsLayer = true
viewController.view.frame = CGRect(x: fromViewController.view.frame.size.width, y: 0,
width: fromViewController.view.frame.size.width, height: fromViewController.view.frame.size.height)
fromViewController.addChildViewController(viewController)
fromViewController.view.addSubview(viewController.view)
let futureFrame = CGRect(x: 0, y: 0, width: viewController.view.frame.size.width,
height: viewController.view.frame.size.height)
NSAnimationContext.runAnimationGroup({ context in
context.duration = 0.75
viewController.view.animator().frame = futureFrame
}, completionHandler:nil)
}
func animateDismissal(of viewController: NSViewController, from fromViewController: NSViewController) {
let futureFrame = CGRect(x: viewController.view.frame.size.width, y: 0,
width: viewController.view.frame.size.width, height: viewController.view.frame.size.height)
NSAnimationContext.runAnimationGroup({ context in
context.duration = 0.75
context.completionHandler = {
viewController.view.removeFromSuperview()
viewController.removeFromParentViewController()
}
viewController.view.animator().frame = futureFrame
}, completionHandler: nil)
}
}
最佳答案
根据我的理解,你的问题分为四个部分:
我有以下示例与您的自定义 segue 类、一个等效键示例、一个响应链示例和一个< strong>focus 示例(假设您指的是 TextField 焦点)。
正如您在下面的 gif 中看到的,您可以单击 Segue 按钮以使用 PushSegue
segue 进行转换。然后点击关闭按钮返回。右箭头和左箭头分别是 Segue 和 Dismiss 按钮的等效键。响应链成功地将数据从 SheetController
(红屏)传递到 MainViewController
(灰屏)。此外,textFields 在 segueing 时会正确地聚焦。我将更详细地解释每个功能。
我使用了您发布的 PushAnimator
子类,并向 View 添加了红色背景,以便我可以直观地看到它。为此,我在 PushAnimator
类的 animatePresentation
方法中添加了以下行:
viewController.view.layer?.backgroundColor = CGColor.init(red: 1, green: 0, blue: 0, alpha: 1)
Segue 按钮分配了 NSRightArrowFunctionKey
的 keyEquivalent,Dismiss 按钮分配了 NSLeftArrowFunctionKey
。您可以点击向右和向左箭头键在两个 View 之间切换。为了设置右箭头,我在 MainViewController
viewDidLoad()
函数中添加了以下内容:
let array = [unichar(NSRightArrowFunctionKey)]
mainViewSegueButton.keyEquivalent = String(utf16CodeUnits: array, count: 1)
为了设置左箭头,我在 SheetController
viewDidLoad()
函数中添加了以下内容:
let array = [unichar(NSLeftArrowFunctionKey)]
dismissButton.keyEquivalent = String(utf16CodeUnits: array, count: 1)
由于您没有描述您在响应链中遇到的具体问题,我只是实现了一个简单的测试以查看它是否有效。我将使用 MainViewController
的 nextResponder 设置 SheetController
的 dismissButton
。我在 SheetController
的 viewDidLoad()
中有以下内容:
// SheetController viewDidLoad()
// Set Accessibility Label
dismissButton.setAccessibilityLabel("DismissButton")
// Set button target and action
dismissButton.target = nil
dismissButton.action = #selector(MainViewController.dismissAction(_:))
// Set nextResponder
dismissButton.nextResponder = self.parent
为了解释以上内容:我首先设置了带有辅助功能标签的 dismissButton
,以便 MainViewController
稍后可以识别该按钮。将按钮的目标设置为 nil 意味着它将寻找 nextResponder 来处理它检测到的任何事件。我将按钮的操作设置为 dismissAction
方法,该方法在 MainViewController
中声明。最后,我将 dismissButton
的 nextResponder 设置为 MainViewController
。
回到 MainViewController
,我在下面设置了 dismissAction
方法。它只是递增一个计数器变量并将该计数器与按钮的 accessibilityLabel(我们之前设置的相同访问标签)一起显示到 textField。最后一行关闭 SheetController
。
// MainViewController
func dismissAction(_ sender: AnyObject) {
counter += 1
let buttonAccessLabel = (sender as! NSButton).accessibilityLabel()
helloWorldTextField.stringValue = "Action #" + counter.description + " from: " + buttonAccessLabel!
self.dismissViewController(self.presentedViewControllers!.first!)
}
为此,我假设您指的是 textField 焦点。在 SheetController
中,我将 sheetFocusTextField
焦点放在 viewDidAppear
中:
override func viewDidAppear() {
super.viewDidAppear()
sheetFocusTextField.becomeFirstResponder()
}
在 MainViewController
中,我在 dismissAction
方法中有 mainFocusTextField
焦点:
mainFocusTextField.becomeFirstResponder()
https://github.com/starkindustries/mac-os-segue-test
关于swift - 自定义 NSStoryboardSegue 未将 NSViewController 添加到响应链,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43401324/
您好,我在将数据发送到 NSSplitViewController 时遇到问题。看起来不像IOS开发那样工作。 第一个 Controller : class LoginController: NSVi
我正在将游戏从 iOS 移植到 MacOS。我知道 Apples Catalyst 是一种选择,但我不想走这条路,因为如果通过触摸或鼠标控制,它会对我的用户界面产生巨大的影响。 在 iOS 中,我在旧
我有一个问题,我已经尝试解决很长一段时间了。还提供了项目文件。 所以我有以下想法,有一个带有按钮的侧边栏,当单击按钮时,它仅切换右侧内容。 我最初创建的项目只有 1 个 Storyboard。 Win
我一直在尝试在 NSPopover 内创建从一个 subview Controller 到另一个 subview Controller 的滑动过渡。 我的问题是 subview Controller
我在使用 Xcode 时遇到了一个愚蠢的问题。有时 - 我不知道为什么,因为我总是遵循相同的过程 - 如果我从 NSViewController 的 nib 文件创建一个 IBAction 到此 NS
我的主应用菜单中有一个菜单项,我想将其操作路由到 View Controller (NSViewController)。界面层次结构如下所示:有一个由 NSWindowController 组成的主应
因此,我将 NSViewController 作为一张禁用了调整大小的窗口呈现。 以工作表形式呈现的 View Controller 仍然可以调整大小。 如何禁用 NSViewController 的
我对 MAC OSX 应用程序开发很陌生。 在我的应用程序中,我有三个 NSViewController,它们是 PracticeController、NoteController 和 Questio
我是 cococa 和 swift 的新手,我想创建一个自定义 ViewController。 class StatusUpdate : NSViewController { @IBOutlet
我是 macOS 开发的新手,我正在使用 Xcode 10 和 Swift 4.2 为 macOS 开发一个项目。 该项目主要包含 3 个 View Controller 。 首先,ViewContr
我对 Windows 与 View Controller 的所有权以及它们何时发布有疑问。我创建了一个测试项目,只在 NSViewController 中添加了一行代码: deinit { print
让我从头告诉你,我有这个初始 View Controller 。从那里我转到主页 View Controller ,通过从初始 View Controller 呈现它,然后我在初始 View Cont
我正在尝试学习 Swift,但我似乎陷入了这个(不可否认,可能非常简单)问题 - 错误如下: Could not connect action, target class NSViewControll
我一直在为 OS X 开发一个小图片上传菜单栏应用程序。我为上传的项目创建了自定义 NSView 子类。 这是默认情况下的样子: 鼠标事件由 View 的 NSViewController 按以下方式
我正在开发一个 OSX 应用程序,如果用户尚未登录,我会首先显示一个登录/注册窗口。 登录成功后,我会显示我的主视图 Controller 。 如果用户已经登录(存储 token ),则应用程序必须直
总结: 使用 Cocoa 的内置用户界面保存机制,在我的 NSViewController 中保存/恢复 NSSearchField 状态的正确方法是什么? 详细信息: 我正在开发我的第一个 macO
我正在构建一个 cocoa 应用程序,其中包含一个带有 xib 的主窗口 Controller 。该 xib 包含许多自定义 View 类。我想向 xib 添加一个 NSViewController,
我正在尝试弄清楚如何在 NSViewController 中重新加载数据。 我有一个这样的项目,左侧栏是 NSOutlineView (由我的outlineViewController控制),右侧
我来自 iOS 世界,其中 viewDidAppear、viewDidDisappear 对于跟踪用户何时切换到另一个 View 或从该 View 返回非常有用。 跟踪与 NSViewControll
我想在 cocoa MAC 应用程序开发中交换 View ,例如 UINavigationController 在 cocoa touch 中的推送/弹出 View 。它是应用程序对推送和弹出 Vie
我是一名优秀的程序员,十分优秀!