如何将子类化视图控制器的视图放入超类baseviewcontroller的contentview中?

时间:2019-08-13 05:36:34

标签: ios swift uiview uiviewcontroller storyboard

我创建了一个名为uiviewcontroller的超类baseviewcontroller类,以包含我的应用程序屏幕大部分所需的基本UI。它包括一个自定义navigation栏和一个我在xib中使用视图底部的UIViewprotocols在xib中创建的“自定义标签栏”。因此,将来,我希望将此baseviewcontroller子类化,以包括其所有基本UI元素。我可以毫无问题地将这个baseviewcontroller子类化,但是底部的新uiviewcontroller's ui元素将被我创建的“标签栏”覆盖。

我尝试在UIView中添加一个称为内容视图的新baseviewcontroller,设置与“标签栏”相关的约束,并在随后的视图控制器中尝试将其视图添加到contentview。但这给了我错误(CALayer需要它自己的图层树),基本上说我不应该contentview.addsubview(self.view)。因此,我尝试使用约束将新的viewcontroller's视图与内容视图进行匹配,但是约束失败,并且不再显示选项卡栏。关于如何执行此操作的任何想法(可能是从baseviewcontroller来的?)

class BaseViewController: UIViewController, SlideMenuDelegate, SwitchTabBarDelegate{

//some other ui,custom nav and controls stuff

private var switchTabBar : SwitchTabBar!
var contentView : UIView!

override func viewDidLoad(){
    super.viewDidLoad()
    self.configureNavBar()
    self.configureScreenEdgeRecognizer()
    self.configureBaseView()
}

private func configureBaseView(){
        //set up contentView for future View to add into
        self.contentView = UIView(frame: CGRect.zero)
        self.view.addSubview(contentView)
        self.contentView.translatesAutoresizingMaskIntoConstraints = false
        self.contentView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor).isActive = true
        self.contentView.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor).isActive = true
        self.contentView.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor).isActive = true

        //set up switchtabbar for switching between viewcontrollers that inherit from base viewcontroller
        self.switchTabBar = SwitchTabBar(frame: CGRect.zero)
        self.switchTabBar.delegate = self
        self.view.addSubview(switchTabBar)
        self.switchTabBar.translatesAutoresizingMaskIntoConstraints = false
        self.view.addConstraint(NSLayoutConstraint(item: self.contentView!, attribute: .bottom, relatedBy: .equal, toItem: self.switchTabBar!, attribute: .top, multiplier: 1, constant: 0))
        self.switchTabBar.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor).isActive = true
        self.switchTabBar.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor).isActive = true
        self.switchTabBar.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor).isActive = true
        self.switchTabBar.heightAnchor.constraint(equalToConstant: self.view.bounds.size.height/10).isActive = true
    }

// some other ui functions and controls + delegate method
}

class MainPageViewController: BaseViewController{

    override func viewDidLoad(){
        super.viewDidLoad()
        contentView.addsubview(self.view) //gives error
        //or
        self.view.frame = contentView.frame //doesn't work
        //or
        self.view.frame = contentView.bounds //doesn't work
        self.view.topAnchor.constraint(contentView.topAnchor).isActive = true
         /* lead,trail,bottom constraint etc but constraint breaks onruntime and won't show tab-bar anymore */
    }

    //edit: tried new method
    override func viewDidLayoutSubviews(){
         super.viewDidLayoutSubviews()
         // this create half black screen so still doesn't work
         self.view.frame = self.contentView.bounds //think because contentView is constraint to the actual view it doesn't work.
    }

}

请注意,BaseViewController没有.xib或没有出现在storyboard中,并且完全由代码组成,但是随后的viewcontroller可以并且将位于{ {1}}和网点等,以便我的设计师可以更改外观。

编辑后:从这个实验来看,storyboard的视图和继承类的视图似乎是相同的,从我尝试放入{{1 }}。现在猜,我将通过在情节提要板上添加具有清晰颜色的空视图并围绕它来构建底部标签栏周围的设计。

2 个答案:

答案 0 :(得分:0)

不是设置框架,而是尝试在子视图控制器中使用边界,例如:self.view.frame = contentView.bounds

还删除行contentView.addsubview(self.view),因为该视图已经是视图层次结构的一部分

因此,子视图控制器的didLoad方法可能类似于:

class MainPageViewController: BaseViewController{

    override func viewDidLoad(){
        super.viewDidLoad()
        self.view.frame = contentView.bounds //doesn't work
    }

}

希望它会有所帮助.. !!!

答案 1 :(得分:0)

好的,我知道了。在尝试了不同的方法之后,我发现一种方法可以达到某种效果,但并不十分优雅。

在继承类contentView的故事板上,我从BaseViewController中删除了MainPageViewController,添加了一个视图,并将其命名为contentView,并使其自动布局到安全区域,但是我抓住了bottomConstraint并在viewController中有一个出口。 然后我在运行时将其删除,然后将contentView的底部的连接约束添加到switchTabBar的顶部和瞧。

class MainViewController: BaseViewController {

    @IBOutlet weak var newContentView: UIView!
    @IBOutlet weak var newContentBottomConstraint: NSLayoutConstraint!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.setUpView()
    }

    private func setUpView(){
        self.newContentBottomConstraint.isActive = false
        self.view.addConstraint(NSLayoutConstraint(item: self.newContentView!, attribute: .bottom, relatedBy: .equal, toItem: self.switchTabBar!, attribute: .top, multiplier: 1, constant: 0))
    }

}

所以现在我只需要首先在将来的viewController类上添加“ contentView”,并在“ contentView”中进行所有设计,就像您对contentView进行scrollView一样。这个答案不是很好,但是我猜它可以完成工作。如果其他人有更好的解决方案,请发布,以便在没有太大麻烦的情况下我可以相应地更改