ios - 使用 UITabBarController 的持久视图
问题描述
我正在尝试构建一个布局类似于 Apple Music 的应用程序——一个带有持久视图的标签栏导航,可以从应用程序的任何地方访问。视图可以扩展以占据整个屏幕或最小化,静态高度为 80。UI 内置在带有普通UITabBarController
. 这是初稿:
这就是我构建它的方式:
class TabbarViewController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
embedLiveFeedbackController()
}
private func embedLiveFeedbackController() {
guard let feedbackController = UIStoryboard(name: "LiveFeedback", bundle: nil).instantiateInitialViewController() as? LiveFeedbackViewController else { return }
feedbackController.stateDelegate = self
addChildViewController(feedbackController)
view.addSubview(feedbackController.view)
feedbackController.view.translatesAutoresizingMaskIntoConstraints = false
feedbackController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
feedbackController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
feedbackController.view.bottomAnchor.constraint(equalTo: tabBar.topAnchor).isActive = true
liveFeedbackTopConstraint = feedbackController.view.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor)
liveFeedbackHeightConstraint = feedbackController.view.heightAnchor.constraint(equalToConstant: Constants.minimizedHeight)
liveFeedbackHeightConstraint?.isActive = true
liveFeedbackTopConstraint?.isActive = false
}
}
我遇到的问题是视图控制器的内容位于持久视图之后并且不完全可见。我尝试过的一件事是将视图控制器限制在持久视图的顶部:
private func constraintViewControllers() {
guard let vcs = viewControllers else { return }
guard let topAnchor = liveFeedbackTopAnchor else { return } // a reference to the top anchor of the persistent view
for viewController in vcs {
viewController.view.translatesAutoresizingMaskIntoConstraints = false
viewController.view.bottomAnchor.constraint(equalTo: topAnchor).isActive = true
}
}
当然,我收到以下错误:
Unable to activate constraint with anchors <NSLayoutYAxisAnchor:0x600000864640 "UILayoutContainerView:0x7fc813f0ea60.bottom"> and <NSLayoutYAxisAnchor:0x60400047b980 "UIView:0x7fc813f08af0.bottom"> because they have no common ancestor. Does the constraint or its anchors reference items in different view hierarchies? That's illegal.'
有什么建议如何实施吗?
解决方案
这是我的建议,我测试了它并且工作正常
创建一个主 viewController 并在其中放置 2 个视图(如图所示):
-startViewController
--containerView (your app root viewController/tabBarController goes here)
--persistentView
在启动视图控制器中
class ViewController: UIViewController {
var tabController : TabController!
@IBOutlet weak var containerView: UIView!
@IBOutlet weak var persistentView: UIView!
@IBOutlet weak var persistentBottomConstraint: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
tabController = TabController.initFromStoryBord()
self.addChild(tabController)
tabController.view.frame = containerView.bounds
containerView.addSubview(tabController.view)
tabController.view.autoresizingMask = [.flexibleHeight, .flexibleWidth]
persistantBottomConstraint.constant = tabController.tabBar.frame.height
}
}
然后是 TabBarController 的一个类:
确保为 tabController 设置 Stroyboard ID
class TabController : UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
}
static func initFromStoryBord() -> TabController {
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "TabController") as! TabController
return vc
}
}
推荐阅读
- r - 用 R 进行三重积分计算
- payment-gateway - Salt and Hash Sage 支付令牌
- c - 如何运行在最快线程完成后停止的并行线程(C、pthreads 或 openmp)
- python - 有效地将大数据传递给 python 3 函数
- excel - 跨工作表的 Excel 公式:如果 a=x,b=y,则 c=z
- css - 试图在即将被删除的 GridView 行上应用样式
- node.js - 使用 node.js 的可扩展架构
- python - 异常终止 multiprocessing.map
- python - 大写并替换列数据框中的空格
- ruby-on-rails - 每个应用程序保留/限制乘客线程