在Swift中推送和弹出NavigationController

时间:2017-05-16 19:15:28

标签: ios swift button uinavigationcontroller onbackpressed

我有一个问题。

我在下面的代码中收到错误消息:"无法转换值类型' Node'预期的参数类型' UIViewController' 如何解决这个问题?

文档视图控制器的代码如下:



import UIKit
import WebKit
import AEXML
import STPopup
import Kanna
import DropDownMenuKit
import Toaster
typealias DocumentOpenAction = (_ node: Node) -> ()

class DocumentViewController: BaseViewController {

    var currentNode:Node! {
        didSet {
            if popupController == nil {
                navigationItem.titleView = UILabel.forTitleView(withText: currentNode.title)
                if titleView != nil {
                    navigationItem.titleView = titleView
                }
            } else {
                navigationItem.titleView = UILabel.forTitleView(withText: currentNode.title)
            }
            
        }
    }
    
    //ausgegebene HTML's
    var sections:[[String:String]] = []
    var changeMarksVisible:Bool? {
        didSet {
            self.updateChangeMarking()
        }
    }
    
    var nightModeOn:Bool? {
        didSet {
            self.updateNightMode()
        }
    }
    
    var readAccessFolder:URL?
    
    lazy var statusBarHeight: CGFloat = {
        let statusBarSize = UIApplication.shared.statusBarFrame.size
        return min(statusBarSize.width, statusBarSize.height)
    }()
    
    //
   
   
    override func viewDidLoad() {
    
        super.viewDidLoad()
        
        NotificationCenter.default.addObserver(self, selector: #selector(DocumentViewController.taskGotDeleted(withNotification:)), name: PackageManager.shared.tasksDeletedNotification, object: nil)

        contentSizeInPopup = CGSize(width: 600, height: 500)
        landscapeContentSizeInPopup = CGSize(width: 600, height: 500)
        
        changeMarksVisible = UserDefaults.standard.bool(forKey: "ChangeMarkings")
        nightModeOn = UserDefaults.standard.bool(forKey: "nightTheme")

        
        if popupController == nil {
            
            PackageManager.shared.setCurrentNodeAndAddToHistory(currentNode)
            setupNavBar()
            
            // create the drop down menu
            createDropDownMenu()
            
            //
            jumpToGraphicsViewButton.addTarget(self, action: #selector(DocumentViewController.showGraphicsView), for: .touchUpInside)
            jumpToGraphicsViewButtonLeadingConstraint.constant = 8.0
            jumpToGraphicsViewButtonWidthConstraint.constant = 48.0
            jumpToGraphicsViewButton.isEnabled = false
            jumpToGraphicsViewButton.isHidden = false
            
        } else {
            
            setupNavBarForPreview()
            
            //
            jumpToGraphicsViewButton.isHidden = true
            jumpToGraphicsViewButtonLeadingConstraint.constant = 0.0
            jumpToGraphicsViewButtonWidthConstraint.constant = 0.0
            
        }

        // webview
        setupWebview()
        
        // process html of current node
        splitHTML(forCurrentNode: currentNode)
        
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    }
    
    override func viewDidAppear(_ animated: Bool) {
        
        super.viewDidAppear(animated)
        
        PackageManager.shared.currentDisplayedModuleNode = currentNode
        navigationBarMenu?.container = view
        
    }

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        
        super.viewWillTransition(to: size, with: coordinator)
        
        coordinator.animate(alongsideTransition: { (ctx) in
            
            self.show3dModelButtonLeadConstraint?.constant = self.view.frame.width - 50
            self.show3dModelButton?.updateConstraintsIfNeeded()
            
            self.webview?.scrollView.updateConstraintsIfNeeded()
            
            // If we put this only in -viewDidLayoutSubviews, menu animation is
            // messed up when selecting an item
            self.updateMenuContentOffsets()
            
        }) { (ctx) in
            
            
        }
        
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        URLCache.shared.removeAllCachedResponses()
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
        webview?.scrollView.delegate = nil
    }
    
    func showListOfContent(_ sender: AnyObject) {
        _ = navigationController?.popViewController(animated: true)
    }

}

// MARK: - UI
extension DocumentViewController {
    
    func setupWebview() {
        
        //Content Controller object
        let controller = WKUserContentController()
        
        //Add message handler reference
        controller.add(self, name: "shoppingcart")
        
        //Create configuration
        let configuration = WKWebViewConfiguration()
        configuration.userContentController = controller
        
        var f = webViewView.frame
        f.origin.y = 0
        
        webview = WKWebView(frame: f, configuration: configuration)
        webview?.configuration.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")
        webview?.backgroundColor = .white
        webview?.scrollView.bounces = true
        webview?.scrollView.delegate = self
        webview?.navigationDelegate = self
        webview?.uiDelegate = self
        
        webViewView.addSubview(webview!)
        webview?.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        
    }
    
    func setupNavBar() {
        
        //loads nav bar if not presented in popup
        settingsButton = UIBarButtonItem(image: UIImage(named: "Settings"), style: .plain, target: self, action: #selector(DocumentViewController.showSettings(_:)))
        navigationItem.rightBarButtonItems = [noticeButton,settingsButton]
        
        listOfContentButton = UIBarButtonItem(image: UIImage(named: "List"), style: .plain, target: self, action: #selector(DocumentViewController.showListOfContent(_:)))
        shoppingCartButton = UIBarButtonItem(image: UIImage(named: "Checkout"), style: .plain, target: self, action: #selector(DocumentViewController.shoppingCartButtonPressed(_:)))
        
        taskListButton = ZABarButtonItem(image: UIImage(named: "TaskList"), style: .plain, target: self, action: #selector(DocumentViewController.taskListButtonPressed(_:)))
        taskListButton.isSelected = PackageManager.shared.nodeIsInTasks(currentNode)
        taskListButton.tintColor = taskListButton.isSelected ? navigationController?.navigationBar.tintColor : .lightGray
        
        favoritesButton = ZABarButtonItem(image: UIImage(named: "Star"), style: .plain, target: self, action: #selector(DocumentViewController.favoritesButtonPressed(_:)))
        favoritesButton.isSelected = PackageManager.shared.nodeIsInFavorites(currentNode)
        let img = favoritesButton.isSelected ? UIImage(named: "StarFilled"): UIImage(named: "Star")
        favoritesButton.image = img
        
        
        backToManualStructure = UIBarButtonItem(image: UIImage(named: "List"), style: .plain, target: self, action: #selector(DocumentViewController.structureButtonPressed(_:)))
        
        var items:[UIBarButtonItem] = [backToManualStructure,shoppingCartButton, favoritesButton]
        
        if currentNode.canBeAddedToTasks() {
            items.append(taskListButton)
        }
        
        navigationItem.leftBarButtonItems = items
        
    }
    
    func setupNavBarForPreview() {
        
        //loads nav bar if presented in popup
        closeButton = UIBarButtonItem(title: NSLocalizedString("Close", tableName: "Localizable", bundle: Bundle.main, value: "", comment: ""), style: .plain, target: self, action: #selector(DocumentViewController.cancel))
        navigationItem.leftBarButtonItems = [closeButton]
        navigationItem.leftItemsSupplementBackButton = false
        
        openButton = UIBarButtonItem(title: NSLocalizedString("Open in new tab", tableName: "Localizable", bundle: Bundle.main, value: "", comment: ""), style: .plain, target: self, action: #selector(DocumentViewController.openDocument))
        navigationItem.rightBarButtonItems = [openButton]
        
    }
    
}

// MARK: - DropDownMenu
extension DocumentViewController {
    
    func createDropDownMenu() {
        
        // create the drop down menu
        let title = prepareNavigationBarMenuTitleView()
        prepareNavigationBarMenu(title)
        updateMenuContentOffsets()
        
    }
    
    func prepareNavigationBarMenuTitleView() -> String {
        
        // Both title label and image view are fixed horizontally inside title
        // view, UIKit is responsible to center title view in the navigation bar.
        // We want to ensure the space between title and image remains constant,
        // even when title view is moved to remain centered (but never resized).
        titleView = DropDownTitleView(frame: CGRect(x: 0, y: 0, width: 150, height: 40))
        titleView.addTarget(self,
                            action: #selector(DocumentViewController.willToggleNavigationBarMenu(_:)),
                            for: .touchUpInside)
        titleView.addTarget(self,
                            action: #selector(DocumentViewController.didToggleNavigationBarMenu(_:)),
                            for: .valueChanged)
        titleView.titleLabel.textColor = UIColor.black
        titleView.title = currentNode.title
        
        navigationItem.titleView = titleView
        
        return titleView.title!
    }
    
    func prepareNavigationBarMenu(_ currentChoice: String) {
        
        navigationBarMenu = DropDownMenu(frame: view.bounds)
        navigationBarMenu?.delegate = self
        
        var cells:[DropDownMenuCell] = []
        for (index, doc) in PackageManager.shared.openNodes.enumerated() {
            
            let cell = DropDownMenuCell()
            
            cell.textLabel!.text = doc.title
            cell.tag = index
            cell.menuAction = #selector(DocumentViewController.choose(_:))
            cell.menuTarget = self
            if currentChoice == doc.title {
                cell.accessoryType = .checkmark
            }
            
            cells.append(cell)
            
        }
        
        navigationBarMenu?.menuCells = cells
        
        // If we set the container to the controller view, the value must be set
        // on the hidden content offset (not the visible one)
        navigationBarMenu?.visibleContentOffset = (navigationController?.navigationBar.frame.size.height ?? 44.0) + statusBarHeight
        
        // For a simple gray overlay in background
        navigationBarMenu?.backgroundView = UIView(frame: view.bounds)
        navigationBarMenu?.backgroundView!.backgroundColor = UIColor.black
        navigationBarMenu?.backgroundAlpha = 0.7
    }
    
    func updateMenuContentOffsets() {
        navigationBarMenu?.visibleContentOffset = (navigationController?.navigationBar.frame.size.height ?? 44.0) + statusBarHeight
    }
    
    @IBAction func choose(_ sender: AnyObject) {
        
        let cell = (sender as! DropDownMenuCell)
        titleView.title = cell.textLabel!.text
        
        let index = cell.tag
        let node = PackageManager.shared.openNodes[index]
        if node != currentNode {
            
            initalSegment = 0
            currentNode = node
            setupNavBar()
            splitHTML(forCurrentNode: currentNode)
            
        }
        
        if let menu = navigationBarMenu {
            didTapInDropDownMenuBackground(menu)
        }

    }
    
    @IBAction func willToggleNavigationBarMenu(_ sender: DropDownTitleView) {
        sender.isUp ? navigationBarMenu?.hide() : navigationBarMenu?.show()
    }
    
    @IBAction func didToggleNavigationBarMenu(_ sender: DropDownTitleView) {
        
    }
    
}

// MARK: - DropDownMenuDelegate
extension DocumentViewController : DropDownMenuDelegate {
    
    func didTapInDropDownMenuBackground(_ menu: DropDownMenu) {
        if menu == navigationBarMenu {
            titleView.toggleMenu()
        }
        else {
            menu.hide()
        }
    }
    
}

// MARK: - data module
extension DocumentViewController {
    
    func splitHTML(forCurrentNode node:Node) {
        
        node.deleteTemporaryHtmls()
        if let nodePath = node.path {
            let pathComponents = URL(fileURLWithPath: nodePath).pathComponents
            
            if pathComponents.count >= 2 {
                
                let rootFolder = "\(pathComponents[1])"
                readAccessFolder = URL(fileURLWithPath: "\(PackageManager.shared.packageFolder)\(rootFolder)")
            }
        }
        
        // segmented control
        segmentedControl.removeAllSegments()
        
        // process html of current node
        do {
            
            sections = try node.processHTMLSections()
            
            if sections.count > 0 {
                
                var index = 0
                for sec in sections {
                    
                    segmentedControl.insertSegment(withTitle: sec["title"], at: index, animated: false)
                    index += 1
   
                }
                
                // 
                let hasWCN = sections.first(where: { (sec) -> Bool in
                    return sec["contenttype"] == "safety"
                })
                
                if let _ = hasWCN {
                } else {
                    
                    let index = sections.index(where: { (sec) -> Bool in
                        return sec["contenttype"] == "container"
                    })
                    
                    if let i = index {
                        initalSegment = i
                    }
                    
                }
                
                //
                if initalSegment > 5 {
                    
                    initalSegment = 0
                    loadHTML(forSection: initalSegment)
                    
                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
                        self.show3DModel(self.show3dModelButton as Any)
                    })
                    
                }
                else {
                    
                    if initalSegment > sections.count {
                        initalSegment = 0
                    }
                    loadHTML(forSection: initalSegment)
                }
                
                segmentedControl.selectedSegmentIndex = initalSegment
                
                // configure show 3d model button
                let button = UIButton(forAutoLayout: ())
                button.imageView?.contentMode = .scaleAspectFit
                button.imageView?.tintColor = .gray
                button.setImage(UIImage(named: "Next"), for: .normal)
                button.backgroundColor = UIColor.lightGray.withAlphaComponent(0.3)
                button.borderColor = .black
                button.borderWidth = 1.0
                button.addTarget(self, action: #selector(DocumentViewController.show3DModel(_:)), for: .touchUpInside)
                webViewView.addSubview(button)
                
                button.autoAlignAxis(.horizontal, toSameAxisOf: webViewView)
                button.autoSetDimension(.height, toSize: 150.0)
                button.autoSetDimension(.width, toSize: 50.0)
                show3dModelButtonLeadConstraint = button.autoPinEdge(.trailing, to: .trailing, of: webViewView, withOffset: 0)
                
                show3dModelButton = button
                
                // we dont need the button any longer
                show3dModelButton?.isHidden = true
                
            }
            
        } catch {
            
            loadPDF()
            segmentedControlHeight.constant = 0
            segmentedControlMarginTop.constant = 0
            segmentedControlMarginBottom.constant = 0
            
        }
        
        if let dmc = node.moduleCode {
            dmcLabel.text = dmc
        }
        if let issno = node.issueNumber {
            issnoLabel.text = issno
        }
        if let issdate = node.issueDate {
            issdateLabel.text = DateFormatter.stringFromDate(issdate, format: "yyyy-MM-dd")
        }
        
        let edgePan = UIScreenEdgePanGestureRecognizer(target: self, action: #selector(returnToGraphicView))
        edgePan.edges = .right
        view.addGestureRecognizer(edgePan)
        
    }
    
    func loadHTML(forSection section: Int) {
        
        URLCache.shared.removeAllCachedResponses()
        URLCache.shared.diskCapacity = 0
        URLCache.shared.memoryCapacity = 0
        
        if section > sections.count {
            return
        }
        
        if webview?.isLoading == true {
            webview?.stopLoading()
        }
        
        if let urlString = sections[section]["url"], let contenttype = sections[section]["contenttype"], let readAccessFolder = readAccessFolder {
            
            var url = URL(fileURLWithPath: urlString)
            if var components = URLComponents(url: url, resolvingAgainstBaseURL: false), contenttype == "requirements" {
                
                let sc = URLQueryItem(name: "shoppingcart", value: "true")
                let domain = URLQueryItem(name: "domain", value: "*")
                components.queryItems = [sc, domain]
                if let newUrl = components.url {
                    url = newUrl
                }
                
            }
            
            _ = webview?.loadFileURL(url, allowingReadAccessTo: readAccessFolder)
        }
        
    }
    
    func loadPDF() {
        
        URLCache.shared.removeAllCachedResponses()
        URLCache.shared.diskCapacity = 0
        URLCache.shared.memoryCapacity = 0
        
        if webview?.isLoading == true {
            webview?.stopLoading()
        }
        
        let fileStr = "\(PackageManager.shared.packageFolder)\(currentNode.path ?? "")"
        
        let url = URL(fileURLWithPath: fileStr)
        let request = URLRequest(url: url)
        
        if let readAccessFolder = readAccessFolder {
            _ = webview?.loadFileURL(url, allowingReadAccessTo: readAccessFolder)
        } else {
            _ = webview?.load(request)
        }
        
    }
    
}

// MARK: - Illustrations
extension DocumentViewController {
    
    func showFullscreenFigure(with boardNo: String, and components: URLComponents?) {
        
        if let gv = self.storyboard?.instantiateViewController(withIdentifier: "GraphicsViewController") as? GraphicsViewController {
        
            gv.url = URL(fileURLWithPath: "\(PackageManager.shared.packageFolder)\(currentNode.path ?? "").\(boardNo).$tmp.htm")
            gv.caption = components?.queryItems?.filter({ (item) in item.name == "caption"}).first?.value
            gv.javascript = components?.queryItems?.filter({ (item) in item.name == "javascript"}).first?.value
            gv.readAccessFolder = readAccessFolder
            
            graphicsView = gv
        }
        
        if popupController != nil {
            popupController?.push(graphicsView!, animated: true)
        } else {
            navigationController?.pushViewController(graphicsView!, animated: true)
        }
        
    }
    
    func showGraphicsView() {
        if let graphicsView = graphicsView {
            if popupController != nil {
                popupController?.push(graphicsView, animated: true)
            } else {
                navigationController?.pushViewController(graphicsView, animated: true)
            }
        }
    }
    
    func returnToGraphicView(_ recognizer: UIScreenEdgePanGestureRecognizer) {
        if recognizer.state == .recognized {
            showGraphicsView()
        }
    }
    
}

// MARK: - Preview
extension DocumentViewController {
    
    func cancel() {
        onClose?()
    }
    
    func openDocument() {
        onOpen?(currentNode)
    }
    
    func showPreview(for node:Node) {
        
        let onOpen:DocumentOpenAction = { node in
            self.currentNode = node
            PackageManager.shared.setCurrentNodeAndAddToHistory(self.currentNode)
            self.initalSegment = 0
            self.splitHTML(forCurrentNode: self.currentNode)
            self.createDropDownMenu()
        }
        
        let contentView = self.storyboard?.instantiateViewController(withIdentifier: "DocumentViewController") as! DocumentViewController
        contentView.initalSegment = 0
        contentView.currentNode = node
        
        //
        if popupController != nil {
            
            contentView.onOpen = self.onOpen
            contentView.onClose = self.onClose
            self.popupController?.push(contentView, animated: true)
            
        } else {
            
            let popup = STPopupController(rootViewController: contentView)
            popup.style = .formSheet
            popup.hidesCloseButton = false
            popup.backgroundView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
            popup.containerView.layer.cornerRadius = 4
            
            contentView.onOpen = { node in
                
                popup.dismiss(completion: {
                    onOpen(node)
                })
                
            }
            contentView.onClose = {
                
                popup.dismiss(completion: {
                    // we dont need to split the html again for now
//                    self.splitHTML(forCurrentNode: self.currentNode)
                })
                
            }
            
            popup.present(in: self, completion: nil)
            
        }
        
        contentView.navigationItem.titleView = UILabel.forTitleView(withText: node.title)
        
    }
    
    func showProcedureStepCheckboxes() {
        
        if popupController == nil {
            self.webview?.evaluateJavaScript("showProcedureStepCheckboxes()", completionHandler: {(result, error) in
                guard let err = error else {return}
                print(err)
            })
        }
        
    }
    
    func setLastScrollingPosition() {
      
        if let code = currentNode.contentobjectcode {
            webview?.restoreContentOffset(forKey: code)
        }
        
    }
    
}

// MARK: - Settings
extension DocumentViewController {
    
    func showSettings(_ sender: AnyObject) {
        
        let vc = self.storyboard?.instantiateViewController(withIdentifier: "SetSettingsViewController") as! SetSettingsViewController
        vc.modalPresentationStyle = .popover
        vc.onChange = {
            self.changeMarksVisible = (UserDefaults.standard.bool(forKey: "ChangeMarkings"))
            self.nightModeOn = (UserDefaults.standard.bool(forKey: "nightTheme"))
        }
        
        if let popover = vc.popoverPresentationController {
            popover.barButtonItem = settingsButton
            popover.permittedArrowDirections = .any
        }
        
        present(vc, animated: true, completion: nil)
        
    }
    
    func updateChangeMarking() {
        
        if (self.changeMarksVisible ?? false) {
            self.webview?.evaluateJavaScript("handleChangemarks()", completionHandler: {(result, error) in
            })
        }
        else {
            self.webview?.evaluateJavaScript("deleteChangemarks()", completionHandler: {(result, error) in
            })
        }
        
    }
    
    func updateNightMode() {
        
        let mode = self.nightModeOn ?? false
        self.webview?.evaluateJavaScript("s1000d.setNightMode(\(mode))", completionHandler: {(result, error) in
        })
        
    }
    
}






// Mark: - Structure Manual
extension DocumentViewController {
    
    func structureButtonPressed(_ sender: AnyObject) {
        
        PackageManager.shared.structureButtonPressed(currentNode)
        
        if let root = self.parent?.parent as? RootTabBarViewController {
            root.selectedIndex = 0
            if let navController = root.viewControllers?.first as? UINavigationController, let firstController = navController.viewControllers.first as? ManualsViewController {
            
                PackageManager.shared.strucutreArrayNode.removeLast()
                
                for var i in PackageManager.shared.strucutreArrayNode {
                    
                    print("\(i.title)")
                    
                    
                    // get next child node
                    if let next = i.nextChild() {
                        i = next
                    }
                    
                    
                    if i.type == "document" || i.subnodes.count == 0 {
                        firstController.showDocumentViewController(for: i)
                    } else {
                        firstController.navigationController?.pushViewController(i, animated: false)
                    }

                }
                
            }
        }
    }
}




0 个答案:

没有答案