我有一个视图,该视图的顶部有一个按钮,底部有一个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
}
}
—
答案 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: [])
}
}
}