簡體   English   中英

被觀察者調用時 NSAnimationContext 崩潰

[英]NSAnimationContext crashing when called by an Observer

我有兩個網頁視圖: webViewcustomizerWebView 這兩個 WKWebViews 都由尾隨約束附加。 從本質上講,當我去到菜單,然后單擊“顯示定制” showCustomizer()或“隱藏定制” hideCustomizer()它調用相應的功能,要么顯示或隱藏所有相關的事物customizerWebView

澄清一下,當從它們附加的NSMenuItems調用這些函數時,一切都按預期工作和動畫。 但是,show/hideCustomizer()從本質上檢測到 URL 的觀察者調用時 - 即。 url.contains("#close") - 應用程序在animator()代碼的第一行崩潰並出現錯誤: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value

視圖控制器.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 次,但在從觀察者函數調用一次hideCustomizer()時崩潰嗎?

我也試過調用 NSMenu 對象函數hideCustomizerMenu(self) ,但無濟於事。

在線上:

ViewController().urlDidChange(urlString: url)

您錯誤地創建了視圖控制器類的新實例並在實例上調用了urlDidChange 由於這個新實例不是從故事板/xib 創建的,它的所有出口都是 nil,因此當您嘗試在hideCustomizer webView上調用animator方法時,它會崩潰,因為它是 nil。

相反,在self上調用urlDidChange (實際上是一個弱化的self這樣你就不會創建一個保留循環):

customizerURLObserver = customizerWebView.observe(\.url, options: .new) { [weak self] webView, change in
    let url = "\(String(describing: change.newValue))"
    self?.urlDidChange(urlString: url)
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM