从底部向左扩展UIView高度,反之亦然

时间:2020-06-25 12:24:39

标签: ios swift animation uiview

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

我使用了解决方案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

2 个答案:

答案 0 :(得分:0)

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

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

希望它对您有用..

答案 1 :(得分:0)

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

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

  • 从按钮底部到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: [])
        }
    }
}