【问题标题】:Presenting View Controllers with a different view depending on which option is selected: Swift 4根据选择的选项为视图控制器呈现不同的视图:Swift 4
【发布时间】:2018-11-01 13:50:06
【问题描述】:

我将尽我所能解释我的问题,所以提前感谢。

我通常通过让每个视图控制器代表不同的视图来构建具有多个视图控制器的应用程序。现在,我正在创建一个具有许多不同视图的大型应用程序。我不想在我的应用程序中有 15 个以上的 viewController。我宁愿让一个视图控制器继承不同的 UIViews。

例如,如果我在菜单栏上选择“设置”选项。然后我会被带到 selectionController 并让 selectionController 继承名为 Settings View

的 UIView

目前我可以导航到我的 settingsController 并让导航栏代表所选的选项。但是我该如何继承 SettingsView 呢?

HomeController

class HomeController: UIViewController {
    lazy var menu: Menu = {
        let menuLauncher = Menu()
        menuLauncher.homeController = self
        return menuLauncher
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        navigationItem.title = "Home"
            view.backgroundColor = Color.blue
            navigationItem.leftBarButtonItem = UIBarButtonItem(image: UIImage(named: "menu"), style: .plain, target: self, action: #selector(displayMenu))
    }

    func displayController(menuOption: MenuOption) {
        let selectionController = UIViewController()
        selectionController.navigationItem.title = menuOption.name
        selectionController.view.backgroundColor = Color.blue
        navigationController?.navigationBar.tintColor = UIColor.white
        navigationController?.pushViewController(selectionController, animated: true)
    }

    @objc func displayMenu() {
        menu.displayMenu()
    }
}

菜单视图

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return menuOptions.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! MenuCell
    let menuOption = menuOptions[indexPath.row]
    cell.menuOption = menuOption
    return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: collectionView.frame.width, height: 30)
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let menuOption = self.menuOptions[indexPath.row]
    print(menuOption.name)
    UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
        self.blackView.alpha = 0

        if let app = UIApplication.shared.delegate as? AppDelegate, let window = app.window {
            let width = window.frame.width - 150

            self.menuView.frame = CGRect(x: -width, y: 0, width: 0, height: window.frame.height)
        }

    }) { (completed: Bool) in


//THIS IS WHERE I CALL MY FUNCTION TO SET UP THE SELECTIONCONTROLLER
        self.homeController?.displayController(menuOption: menuOption)
    }
}

override init(frame: CGRect) {
    super.init(frame: frame)
    self.collectionView.delegate = self
    self.collectionView.dataSource = self
    collectionView.register(MenuCell.self, forCellWithReuseIdentifier: cellId)

    setUpView()
    setUpCollectionView()

}

选择选项后(以索引路径的形式),菜单动画完成后。我在 HomeController 中调用我的函数 displayController 并设置新的控制器。

我还将如何实现视图?如果我选择了“设置”,如何让 selectionController 也显示 SettingsView

【问题讨论】:

    标签: ios iphone swift uiview viewcontroller


    【解决方案1】:

    我个人认为拥有很多ViewController 不是问题。它为您可以利用的视图提供了一些好处,例如生命周期控制。

    很好的解释:https://stackoverflow.com/a/30459226/7591205

    当视图变得复杂时,最好封装成ViewController

    但是,如果您坚持使用多个 View 对应 1 个 ViewController。我的建议是拥有一个容器视图概念,然后在其中切换您的视图。实现这一目标的一个好方法是拥有一个 UIStackView,然后将所有视图放在那里。然后根据您的需要隐藏/显示。

    【讨论】:

      【解决方案2】:

      您可以将子视图添加到现有视图:

      //The container view can be in the vc with constraints already setup.
      //Or you can use the vc's default view.
      enum MyView: Int { case settingsView = 0, otherView }
      
      //Add view
      let view = UIView(frame: containerView.bounds)
      view.tag = MyView.settingsView.rawValue
      containerView.addSubview(view)
      
      //Remove view
      if let remove = containerView.viewWithTag(MyView.settingsView.rawValue) {
          remove.removeFromSuperview()
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-18
        • 1970-01-01
        • 1970-01-01
        • 2017-09-19
        • 1970-01-01
        • 2019-02-01
        相关资源
        最近更新 更多