带有自动布局的 SideMenu

Posted

技术标签:

【中文标题】带有自动布局的 SideMenu【英文标题】:SideMenu with AutoLayout 【发布时间】:2018-03-28 12:56:22 【问题描述】:

我正在尝试制作侧边菜单,但在设置自动布局时遇到了一些问题。 我有一个 rootViewController,我将 leftMenuVC 作为 childVC 添加到它,然后我设置约束。

class RootVC: UIViewController, NavigationBarDelegate 
    var leftMenuVC: UIViewController?
    var navigationBar = NavigationBar()
    var isMenuCollapsed = true

    override func viewDidLoad() 
        leftMenuVC = leftVC()
        addChildViewController(leftMenuVC!)
        view.addSubview(leftMenuVC!.view)
        leftMenuVC!.didMove(toParentViewController: self)
    

    override func viewDidLayoutSubviews() 
        if let v = leftMenuVC?.view 
            v.translatesAutoresizingMaskIntoConstraints = false
            v.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
            v.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
            v.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -140).isActive = true
            v.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        
    

    func menuButtonClicked()

    

所以我的问题是如何在支持方向的情况下更改约束以隐藏/显示菜单

【问题讨论】:

试试这个选项github.com/John-Lluch/SWRevealViewController 你可以使用这个第三方库:github.com/jonkykong/SideMenu 谢谢,我过去使用了这两个库,但现在我想要左右侧菜单和我自己的实现。 【参考方案1】:

当我想用约束隐藏屏幕外的视图时,我通常会做的是:

1 设置所有约束,使侧视图可见(处于活动状态)

2 参考将侧视图固定在一侧(此处为左侧)的约束

leftAnchor = NSLayoutConstraint(item: v, attribute: .left, relatedBy: .equal, toItem: view, attribute: .left, multiplier: 1, constant: 0)
view.addConstraint(leftAnchor)
view.addConstraint(NSLayoutConstraint(item: v, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 0))
view.addConstraint(NSLayoutConstraint(item: v, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: 0))
view.addConstraint(NSLayoutConstraint(item: v, attribute: .width, relatedBy: .equal, toItem: view, attribute: .width, multiplier: 0.6, constant: 0))

3 再设置一个约束,以便隐藏视图。通常是这样的。请注意,优先级设置为 999 以避免约束冲突。

var hiddingConstraint = NSLayoutConstraint(item: v, attribute: .right, relatedBy: .equal, toItem: view, attribute: .left, multiplier: 1, constant: 0)
hiddingConstraint.priority = 999
view.addConstraint(hiddingConstraint)

4 通过激活或不激活左锚来制作动画

UIView.animate(withDuration: 0.3) 
       self.leftAnchor.active = false
       self.view.layoutIfNeeded()

所以你应该得到这样的代码:

class RootVC: UIViewController, NavigationBarDelegate 
    var leftMenuVC: UIViewController?
    var navigationBar = NavigationBar()
    var isMenuCollapsed = true 
        didSet 
            UIView.animate(withDuration: 0.3) 
                self.leftAnchor?.isActive = self.isMenuCollapsed
                self.view.layoutIfNeeded()
            
        

    
    var leftAnchor : NSLayoutConstraint?

    override func viewDidLoad() 
        leftMenuVC = leftVC()
        addChildViewController(leftMenuVC!)
        view.addSubview(leftMenuVC!.view)
        leftMenuVC!.didMove(toParentViewController: self)
    

    override func viewDidLayoutSubviews() 
        if let v = leftMenuVC?.view 

            leftAnchor = NSLayoutConstraint(item: v, attribute: .left, relatedBy: .equal, toItem: view, attribute: .left, multiplier: 1, constant: 0)
            view.addConstraint(leftAnchor!)
            view.addConstraint(NSLayoutConstraint(item: v, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 0))
            view.addConstraint(NSLayoutConstraint(item: v, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: 0))
            view.addConstraint(NSLayoutConstraint(item: v, attribute: .width, relatedBy: .equal, toItem: view, attribute: .width, multiplier: 0.6, constant: 0))

            var hiddingConstraint = NSLayoutConstraint(item: v, attribute: .right, relatedBy: .equal, toItem: view, attribute: .left, multiplier: 1, constant: 0)
            hiddingConstraint.priority = 999
            view.addConstraint(hiddingConstraint)
        
    

    func menuButtonClicked()
        isMenuCollapsed = !isMenuCollapsed
    

PS:我不会将约束设置放在viewDidLayoutSubviews 中,可能放在viewWillAppear 中,因为您不必在每次旋转设备时都设置它们。这就是约束的目的

【讨论】:

谢谢RomOne,这很好用,我想我的错误是我没有降低第二约束的优先级。请记住,您已设置 translatesAutoresizingMaskIntoConstraints = false【参考方案2】:

与其自己编写此代码,不如为自己省去麻烦。 这是MMDrawerController 来拯救你。我自己正在使用它。它非常易于实施,并提供了许多自定义选项。希望你觉得它有用。 :-)

【讨论】:

以上是关于带有自动布局的 SideMenu的主要内容,如果未能解决你的问题,请参考以下文章

带有图像和文本字段的自动布局表格单元格?

带有自动布局的 uilabel 使用填充调整大小

带有自定义转场的自动布局

带有自动布局的滚动视图表单

如何解决这个带有约束的自动布局“难题”?

带有自动布局(snapkit)的圆形视图?