[NSAnimationContext被观察者调用时崩溃

问题描述 投票:0回答:1

我有两个WebView:webViewcustomizerWebView。这两个WKWebView均由尾随约束附加。本质上,当我进入菜单并单击“显示自定义程序” showCustomizer()或“隐藏自定义程序” hideCustomizer()时,它将调用相应的函数,并显示或隐藏与customizerWebView相关的所有内容。

为清楚起见,从所附的NSMenuItems调用这些函数时,一切都会按预期进行并进行动画处理。 但是,当从实质上检测到URL的观察者处调用show/hideCustomizer()时-即。 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),但无济于事。

swift macos core-graphics core-animation nsanimationcontext
1个回答
0
投票

在线:

ViewController().urlDidChange(urlString: url)

您错误地创建了视图控制器类的新实例,并在that实例上调用了urlDidChange。由于不是从情节提要/ xib创建此新实例,所以它的所有出口都为零,因此当您尝试在animator中的webView上调用hideCustomizer方法时,它会崩溃,因为它为零。

相反,请在urlDidChange上调用self(实际上是弱化的self,这样就不会创建保留周期):

customizerURLObserver = customizerWebView.observe(\.url, options: .new) { [weak self] webView, change in
    let url = "\(String(describing: change.newValue))"
    self?.urlDidChange(urlString: url)
}
© www.soinside.com 2019 - 2024. All rights reserved.