从视图中执行Segue

时间:2018-11-25 21:02:05

标签: ios swift uicollectionview segue

我有一个名为MenuBar的自定义类,它是一个UIView,用于向视图控制器呈现UICollectionView。当选择UICollectionViewCell时,我遇到的问题是对另一个视图控制器使用segue。由于MenuBar不是视图控制器,因此我似乎无法调用performSegue()。我在情节提要中的两个视图控制器之间创建了一个带有标识符的序列。如何在自定义视图类中正确触发segue?通常如何做?我尝试创建一个新的视图控制器实例,以便可以从.performSegue() didSelectItemAt函数中使用collectionView,但是我认为这不是在其中执行此操作的正确方法所有。例如:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let vc = UARTModuleViewController()
    vc.performSegue(withIdentifier: "colorSelection", sender: nil)
}

任何有关如何从此功能中执行segue的建议将不胜感激。下面,我将提供现有代码的关键组件,以便您可以看到我在做什么。这两个类中都有很多代码,但是我认为这足以满足我要完成的工作的总体思路。

视图控制器:

class UARTModuleViewController: UIViewController, CBPeripheralManagerDelegate {
    override func viewDidLoad() {
        setupMenuBar()
    }

    let menuBar: MenuBar = {
        let mb = MenuBar()
        return mb
    }()

    private func setupMenuBar() {
        view.addSubview(menuBar)

        menuBar.translatesAutoresizingMaskIntoConstraints = false
        menuBar.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
        menuBar.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
        menuBar.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
        menuBar.heightAnchor.constraint(equalToConstant: 80).isActive = true
    }
}

MenuBar.swift:

class MenuBar : UIView, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

    lazy var collectionView : UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cv.backgroundColor = UIColor.clear
        cv.dataSource = self
        cv.delegate = self
        return cv
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupCollectionView()
    }

    private func setupCollectionView() {
        self.addSubview(collectionView)
        collectionView.register(MenuCell.self, forCellWithReuseIdentifier: "MenuCell")

        collectionView.translatesAutoresizingMaskIntoConstraints = false
        collectionView.topAnchor.constraint(equalTo: topAnchor).isActive = true
        collectionView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
        collectionView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
        collectionView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
    }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let vc = UARTModuleViewController() // I want to perform a segue from here
        vc.performSegue(withIdentifier: "colorSelection", sender: nil)
    }

}

在此先感谢任何可以提供有用建议的人!

1 个答案:

答案 0 :(得分:1)

let vc = UARTModuleViewController()

动态创建另一个与显示的对象无关的对象,如果未以编程方式创建vc,则可能导致崩溃,而您需要委托

lazy var menuBar: MenuBar = {
    let mb = MenuBar()
    mb.delegate = self
    return mb
}()

并在MenuBar

中添加此变量
weak var delegate:UARTModuleViewController?

然后像这样使用它

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 
    delegate?.performSegue(withIdentifier: "colorSelection", sender: nil)
}

应该说,更好的可重用性方法是创建协议

protocol ColManager { 
   func navigate()
}

使用

weak var delegate:ColManager?

任何要使用的类都应遵守协议并实现navigate方法