【发布时间】:2019-12-19 15:38:30
【问题描述】:
我创建了一个名为baseviewcontroller 的超类uiviewcontroller 来包含我的大多数应用程序屏幕所需的基本用户界面。它包括一个自定义的navigation 栏和一个“自定义选项卡栏”,我使用视图底部的UIView 和protocols 在xib 中创建。因此,在未来,我希望仅将这个baseviewcontroller 子类化,以包含其所有基本UI 元素。我可以继承这个baseviewcontroller 没问题,但是底部的新uiviewcontroller's ui 元素将被我创建的“标签栏”覆盖。
我尝试在baseviewcontroller 中添加一个名为内容视图的新UIView,设置其与“标签栏”相关的约束,并在随后的视图控制器中尝试将其视图添加到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 可以并且将在storyboard 上使用网点等设计师可以改变它的外观。
编辑后:从这个实验来看,从我尝试输入viewDidLayoutSubviews 时得到的半黑屏来看,似乎BaseViewController 的视图和inherit-class 的视图是相同的。现在猜猜我将通过在情节提要中添加一个具有清晰颜色的空视图然后围绕它构建来围绕底部标签栏构建设计。
【问题讨论】:
-
除了在底部的那个栏周围设置视图之外别无他法,你不能创建视图控制器并将其隐藏在它自己的视图中。就像你想躲在自己的口袋里一样
标签: ios swift uiview uiviewcontroller storyboard