尝试从外部模态视图控制器调用视图控制器功能时出现致命错误

时间:2017-01-16 23:07:49

标签: ios swift uiviewcontroller uinavigationcontroller webkit

摘要

我目前面临的问题始终在Objective-C中运行良好,但我似乎无法在Swift(特别是v3)中使用它。这都是使用Storyboard构建的。我有两个独立的视图控制器:

  1. ViewController: WKWebView& UIButtonItems
  2. SideMenuTableView: UITableView& UIButtons
  3. 目前,SideMenu以模态方式在ViewController之上弹出,并通过UIButtons列出一组操作。我想我会脱离最简单的例子,只是为了让想法失效。我在这个例子中想要完成的是从UIButton tap(SideMenuTableView)重新加载WKWebView(ViewController)。如果事情仍然不清楚,下面是我想要了解的更清晰的图片:

    Screenshots.png

    目前,我可以使用简单的故事板segue (Kind: Present Modally)调用SideMenu。此外,我可以忽略已实现为简单close()函数的SideMenu。但是,在尝试调用刷新函数时,我收到以下错误消息:

    fatal error: unexpectedly found nil while unwrapping an Optional value
    

    代码

    import UIKit
    import WebKit
    
    class ViewController: UIViewController, UINavigationControllerDelegate, WKNavigationDelegate {
    
        var webView: WKWebView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let webURL = URL(string: "https://google.ca")
            let webRequest = URLRequest(url: webURL!)
            webView.load(webRequest)
    
        func refresh() {
            webView.reload()
        }
    }
    
    
    
    import Foundation    
    
    class SideMenuTableView: UITableViewController {
    
        @IBAction fileprivate func close() {
            self.dismiss(animated: true, completion: nil)
        }
    
        @IBAction func refresh(sender: AnyObject!) {
            ViewController().refresh()
            close()
        }
    }
    

    编辑:更新了segue代码。

    // MARK: - Navigation
    
        // In a storyboard-based application, you will often want to do a little preparation before navigation
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            // Get the new view controller using segue.destinationViewController.
            // Pass the selected object to the new view controller.
            if let vc = segue.destination as? SideMenuTableView {
                vc.delegate = self
            }
        }
    }
    

1 个答案:

答案 0 :(得分:3)

您正在使用UIViewController初始化新的ViewController().refresh()。委托模式是实现目标的更好方式:

创建协议:

protocol MainViewControllerDelegate /* Can be called whatever you like */ {
    func refresh()
}

让你的ViewController符合它。

SideMenuTableView创建变量以保存对其委托的引用。

weak var delegate: MainViewControllerDelegate? 

ViewController的prepareForSegue()函数中。检查目的地segue是否为SideMenuTableView

if let vc = destination.vc as? SideMenuTableView {
    vc.delegate = self
}

现在在@IBAction按钮中点击SideMenuTableView调用委托方法。

@IBAction func refresh(sender: AnyObject!) {
        delegate?.refresh()
        close()
}

因为你的ViewController符合这个协议(它必须在它的类中有一个刷新功能),所以将执行刷新功能。

相关问题