NSAnimationContext 在被观察者调用时崩溃
NSAnimationContext crashing when called by an Observer
我有两个 WebView:webView
和 customizerWebView
。这两个 WKWebViews 都附加了尾随约束。本质上,当我转到菜单并单击 "Show Customizer" showCustomizer()
或 "Hide Customizer" hideCustomizer()
时,它会调用相应的函数并显示或隐藏与 [=12] 相关的所有内容=].
澄清一下,当从附加的 NSMenuItems
调用这些函数时,一切都按预期工作和动画。 然而, 当 show/hideCustomizer()
从本质上检测到 URL 的观察者调用时 - 即。 url.contains("#close")
- 应用程序在 animator()
代码的第一行崩溃并出现错误:Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
ViewController.swift
import Cocoa
import WebKit
class ViewController: NSViewController, WKUIDelegate, WKNavigationDelegate {
var customizerURLObserver: NSKeyValueObservation?
@IBOutlet var webView: WKWebView!
@IBOutlet var customizerWebView: WKWebView!
@IBOutlet var rightConstraint: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad
...
customizerURLObserver = customizerWebView.observe(\.url, options: .new) { webView, change in
let url = "\(String(describing: change.newValue))"
ViewController().urlDidChange(urlString: url) }
}
func urlDidChange(urlString: String) {
let url = cleanURL(urlString)
if url.contains("#close") { hideCustomizer() } // Observer call to hide function
}
@IBAction func showCustomizerMenu(_ sender: Any) { showCustomizer() } // These work flawlessly
@IBAction func hideCustomizerMenu(_ sender: Any) { hideCustomizer() } // These work flawlessly
func showCustomizer() {
let customTimeFunction = CAMediaTimingFunction(controlPoints: 5/6, 0.2, 2/6, 0.9)
NSAnimationContext.runAnimationGroup({(_ context: NSAnimationContext) -> Void in
context.timingFunction = customTimeFunction
context.duration = 0.3
rightConstraint.animator().constant = 280
customizerWebView.animator().isHidden = false
webView.animator().alphaValue = 0.6
}, completionHandler: {() -> Void in
})
}
func hideCustomizer() {
let customTimeFunction = CAMediaTimingFunction(controlPoints: 5/6, 0.2, 2/6, 0.9)
NSAnimationContext.runAnimationGroup({(_ context: NSAnimationContext) -> Void in
context.timingFunction = customTimeFunction
context.duration = 0.3
webView.animator().alphaValue = 1 // Found nil crash highlights this line
rightConstraint.animator().constant = 0
}, completionHandler: {() -> Void in
self.customizerWebView.isHidden = true
})
}
}
谁能告诉我为什么这个动画在从 NSMenu 调用时看起来和工作完美无瑕 100 次,但在从 Observer 函数调用一次 hideCustomizer()
时崩溃?
我也试过调用 NSMenu 对象函数 hideCustomizerMenu(self)
,但没有成功。
在线:
ViewController().urlDidChange(urlString: url)
您错误地创建了视图控制器的新实例 class 并在 那个 实例上调用了 urlDidChange
。由于这个新实例不是从 storyboard/xib 创建的,它的所有出口都是 nil,因此当您尝试在 hideCustomizer
中的 webView
上调用 animator
方法时,它崩溃了,因为它是零。
相反,在 self
上调用 urlDidChange
(实际上是一个弱化的 self
,这样您就不会创建保留循环):
customizerURLObserver = customizerWebView.observe(\.url, options: .new) { [weak self] webView, change in
let url = "\(String(describing: change.newValue))"
self?.urlDidChange(urlString: url)
}
我有两个 WebView:webView
和 customizerWebView
。这两个 WKWebViews 都附加了尾随约束。本质上,当我转到菜单并单击 "Show Customizer" showCustomizer()
或 "Hide Customizer" hideCustomizer()
时,它会调用相应的函数并显示或隐藏与 [=12] 相关的所有内容=].
澄清一下,当从附加的 NSMenuItems
调用这些函数时,一切都按预期工作和动画。 然而, 当 show/hideCustomizer()
从本质上检测到 URL 的观察者调用时 - 即。 url.contains("#close")
- 应用程序在 animator()
代码的第一行崩溃并出现错误:Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
ViewController.swift
import Cocoa
import WebKit
class ViewController: NSViewController, WKUIDelegate, WKNavigationDelegate {
var customizerURLObserver: NSKeyValueObservation?
@IBOutlet var webView: WKWebView!
@IBOutlet var customizerWebView: WKWebView!
@IBOutlet var rightConstraint: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad
...
customizerURLObserver = customizerWebView.observe(\.url, options: .new) { webView, change in
let url = "\(String(describing: change.newValue))"
ViewController().urlDidChange(urlString: url) }
}
func urlDidChange(urlString: String) {
let url = cleanURL(urlString)
if url.contains("#close") { hideCustomizer() } // Observer call to hide function
}
@IBAction func showCustomizerMenu(_ sender: Any) { showCustomizer() } // These work flawlessly
@IBAction func hideCustomizerMenu(_ sender: Any) { hideCustomizer() } // These work flawlessly
func showCustomizer() {
let customTimeFunction = CAMediaTimingFunction(controlPoints: 5/6, 0.2, 2/6, 0.9)
NSAnimationContext.runAnimationGroup({(_ context: NSAnimationContext) -> Void in
context.timingFunction = customTimeFunction
context.duration = 0.3
rightConstraint.animator().constant = 280
customizerWebView.animator().isHidden = false
webView.animator().alphaValue = 0.6
}, completionHandler: {() -> Void in
})
}
func hideCustomizer() {
let customTimeFunction = CAMediaTimingFunction(controlPoints: 5/6, 0.2, 2/6, 0.9)
NSAnimationContext.runAnimationGroup({(_ context: NSAnimationContext) -> Void in
context.timingFunction = customTimeFunction
context.duration = 0.3
webView.animator().alphaValue = 1 // Found nil crash highlights this line
rightConstraint.animator().constant = 0
}, completionHandler: {() -> Void in
self.customizerWebView.isHidden = true
})
}
}
谁能告诉我为什么这个动画在从 NSMenu 调用时看起来和工作完美无瑕 100 次,但在从 Observer 函数调用一次 hideCustomizer()
时崩溃?
我也试过调用 NSMenu 对象函数 hideCustomizerMenu(self)
,但没有成功。
在线:
ViewController().urlDidChange(urlString: url)
您错误地创建了视图控制器的新实例 class 并在 那个 实例上调用了 urlDidChange
。由于这个新实例不是从 storyboard/xib 创建的,它的所有出口都是 nil,因此当您尝试在 hideCustomizer
中的 webView
上调用 animator
方法时,它崩溃了,因为它是零。
相反,在 self
上调用 urlDidChange
(实际上是一个弱化的 self
,这样您就不会创建保留循环):
customizerURLObserver = customizerWebView.observe(\.url, options: .new) { [weak self] webView, change in
let url = "\(String(describing: change.newValue))"
self?.urlDidChange(urlString: url)
}