首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSAnimationContext在被观察者调用时崩溃

NSAnimationContext在被观察者调用时崩溃
EN

Stack Overflow用户
提问于 2020-03-26 23:35:07
回答 1查看 70关注 0票数 1

我有两个WebViews:webViewcustomizerWebView。这两个WKWebViews都是由一个尾部约束附加的。本质上,当我转到菜单并单击“显示定制器”showCustomizer()或“隐藏定制器”hideCustomizer()时,它将调用相应的函数,并显示或隐藏与customizerWebView相关的所有内容。

为了澄清,当从附加的NSMenuItems调用这些函数时,一切都按预期工作和动画化。但是,当show/hideCustomizer()从观察者那里被调用时,它实际上检测到了一个URL。url.contains("#close") --应用程序在animator()代码的第一行上崩溃,错误是:Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value

ViewController.swift

代码语言:javascript
复制
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次,而当hideCustomizer()从一个观察者函数调用一次时却崩溃了吗?

我也尝试过调用NSMenu对象函数hideCustomizerMenu(self),但没有结果。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-26 23:43:39

在线路上:

代码语言:javascript
复制
ViewController().urlDidChange(urlString: url)

您错误地创建了视图控制器类的新实例,并对该实例调用了urlDidChange。由于这个新实例不是从故事板/xib创建的,所以它的所有出口都是零,因此当您试图在其webView上调用hideCustomizer中的webView方法时,它会崩溃,因为它是零。

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

代码语言:javascript
复制
customizerURLObserver = customizerWebView.observe(\.url, options: .new) { [weak self] webView, change in
    let url = "\(String(describing: change.newValue))"
    self?.urlDidChange(urlString: url)
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60877819

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档