UITabBarController实现的持久化视图

3

我正在尝试构建一个布局类似于Apple Music的应用程序 - 一个带有持续视图的选项卡式导航,可从应用程序的任何位置访问。该视图可以扩展以占据整个屏幕,也可以缩小为静态高度为80。UI是在Storyboard中使用普通的UITabBarController构建的。这是第一版草稿:1]

这是我构建它的方式:

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.'

有什么建议如何实施这个功能?

每次我在SO上问这样的问题时,我都会得到类似的回答(几乎没有)。我开始相信滚动视图的内容插入和自动调整它们并不被广泛理解。而那些理解它的人通常不愿意回答。我很好奇是否能得到任何有见地的反馈。 - ABeard89
如果我有更多时间来探索这个问题,我会更深入地研究UIViewController.additionalSafeAreaInsetsUIScrollView.adjustedContentInset。你可能可以在viewWillLayoutSubviewsviewDidLayoutSubviews期间调整你的UITabControlleradditionalSafeAreaInsets(或其子视图控制器的additionalSafeAreaInsets)。(我不完全确定这样做是否有效,但可能会让你走上正确的轨道)。对于iOS11之前的版本,我可能会考虑一些基于UILayoutGuide的解决方案。 - ABeard89
抱歉我不能提供更多的帮助。但是我希望这足以让你找到正确的方向。如果你找到了一个好的解决方案,我很乐意看到它,我相信其他人也会从答案中受益。 - ABeard89
1个回答

0
这是我的建议,我测试过了,运行良好。
创建一个主视图控制器,并在其中放置两个视图(如图片所示):

enter image description here

-startViewController 
--containerView (your app root viewController/tabBarController goes here)
--persistentView

在 startViewController 中

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
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接