【问题标题】:expand UIView height bottom to left and vice versa将 UIView 高度从下到左展开,反之亦然
【发布时间】:2020-06-25 12:24:39
【问题描述】:

我有一个视图,顶部有一个按钮,底部有一个 textview 作为子视图,我试图让按钮展开并显示 textview 或折叠并隐藏它(如显示/隐藏)

我使用了here 解决方案,它有点帮助,除了子视图(文本视图)仍然显示并与其他视图重叠,所以它只隐藏了主 UIView。

在这里,我将高度约束初始化为 25,以便为按钮留出空间: heightConstraint = detailView.heightAnchor.constraint(equalToConstant: 25)

根据高度限制展开/折叠视图的操作函数

    @objc func expandViewPressed(sender: UIButton) {
    if isAnimating { return }
    let shouldCollapse = detailView.frame.height > 25
    animateView(isCollapsed: shouldCollapse)
}

动画功能

private func animateView(isCollapsed: Bool) {
    heightConstraint[enter image description here][1].isActive = isCollapsed
    isAnimating = true
    UIView.animate(withDuration: 1, animations: {
        self.detailText.isHidden = isCollapsed
        self.view.layoutIfNeeded()
    }) { (_) in
        self.isAnimating = false
    }
}

expanded view

【问题讨论】:

  • 使用动态高度约束。
  • @user3344236 这就是我所做的,只是它只改变了主视图的高度,而不是它的子视图。
  • 如果文本视图是“仍在显示并与其他视图重叠”,则很可能包含的UIView 有@987654326 @设置为true
  • @DonMag 是的,这有效.. 但我仍然得到 [LayoutConstraints] Unable to 同时满足约束错误。

标签: ios swift animation uiview


【解决方案1】:

Sherbini .. 请确保您已为您的子视图添加了适当的约束 .. 确保不要在您的任何子视图上添加高度约束 ..

还要确保您已添加 view.clipsToBounds == true

希望它对你有用..

【讨论】:

  • 这成功了,但现在我得到了 [LayoutConstraints] Unable to 同时满足约束调试错误..
  • 如果你能显示代码或视图会很棒..这样我就可以帮你解决这个问题..谢谢!
  • 我在问题帖中添加了视图的图片
  • 哦..好像你想展开折叠表格视图单元格对吗??
  • 不,它们不是表格视图单元格,它们只是 UIViews
【解决方案2】:

有多种方法可以解决这个问题。

一种方法是使用两个“底部”约束:

  • 从按钮底部到detailView底部的一个
  • detailText 底部到detailView 底部的一个

然后根据视图是“折叠”还是“展开”来设置每个的约束优先级。

这是一个完整的实现供您尝试:

class ExpandViewController: UIViewController {
    
    let myButton: UIButton = {
        let v = UIButton()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.setTitle("Collapse", for: [])
        v.backgroundColor = .red
        return v
    }()
    
    let detailText: UITextView = {
        let v = UITextView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.text = "This is text in the text view."
        return v
    }()
    
    let detailView: UIView = {
        let v = UIView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = UIColor(red: 0.25, green: 0.5, blue: 1.0, alpha: 1.0)
        v.clipsToBounds = true
        return v
    }()

    var isAnimating: Bool = false
    
    var collapsedConstraint: NSLayoutConstraint!
    var expandedConstraint: NSLayoutConstraint!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = UIColor(red: 0.0, green: 0.75, blue: 0.0, alpha: 1.0)
        
        detailView.addSubview(myButton)
        detailView.addSubview(detailText)
        view.addSubview(detailView)
        
        let g = view.safeAreaLayoutGuide
        
        // when collapsed, we want button bottom to constrain detailView bottom
        collapsedConstraint = myButton.bottomAnchor.constraint(equalTo: detailView.bottomAnchor, constant: -12.0)
        
        // when expanded, we want textView bottom to constrain detailView bottom
        expandedConstraint = detailText.bottomAnchor.constraint(equalTo: detailView.bottomAnchor, constant: -12.0)

        // we'll start in Expanded state
        expandedConstraint.priority = .defaultHigh
        collapsedConstraint.priority = .defaultLow
        
        NSLayoutConstraint.activate([
            
            // constrain detailView Top / Leading / Trailing
            detailView.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
            detailView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 40.0),
            detailView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -40.0),
            
            // no Height or Bottom constraint for detailView
            
            // constrain button Top / Center / Width
            myButton.topAnchor.constraint(equalTo: detailView.topAnchor, constant: 12.0),
            myButton.centerXAnchor.constraint(equalTo: detailView.centerXAnchor),
            myButton.widthAnchor.constraint(equalToConstant: 200.0),
            
            // constrain detailText Top / Leading / Trailing
            detailText.topAnchor.constraint(equalTo: myButton.bottomAnchor, constant: 12.0),
            detailText.leadingAnchor.constraint(equalTo: detailView.leadingAnchor, constant: 12.0),
            detailText.trailingAnchor.constraint(equalTo: detailView.trailingAnchor, constant: -12.0),

            // constrain detailText's Height
            detailText.heightAnchor.constraint(equalToConstant: 200.0),
            
            expandedConstraint,
            collapsedConstraint,
            
        ])
        
        myButton.addTarget(self, action: #selector(self.expandViewPressed(sender:)), for: .touchUpInside)
        
    }
    
    @objc func expandViewPressed(sender: UIButton) {
        if isAnimating { return }
        animateView()
    }
    
    private func animateView() {
        isAnimating = true
        
        // if it's expanded
        if expandedConstraint.priority == .defaultHigh {
            expandedConstraint.priority = .defaultLow
            collapsedConstraint.priority = .defaultHigh
        } else {
            collapsedConstraint.priority = .defaultLow
            expandedConstraint.priority = .defaultHigh
            detailText.isHidden = false
        }
        UIView.animate(withDuration: 1, animations: {
            self.view.layoutIfNeeded()
        }) { (_) in
            self.detailText.isHidden = self.expandedConstraint.priority == .defaultLow
            self.isAnimating = false
            self.myButton.setTitle(self.detailText.isHidden ? "Expand" : "Collapse", for: [])
        }
    }
}

【讨论】:

    猜你喜欢
    • 2016-03-29
    • 2017-07-08
    • 1970-01-01
    • 2017-08-29
    • 2022-01-23
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 2016-04-26
    相关资源
    最近更新 更多