【发布时间】:2021-04-18 16:12:56
【问题描述】:
我有这门课:
class Cell {
/// The view that contains everything.
///
/// Use this view to present this `Cell`.
var view: UIView
/// The view that contains the content of the cell without `openedView`.
var cellView: UIView
var openedView: UIView
var topOpenedView: UIView
var button: UIButton! = nil
private var isOpenedProtected: Bool = false
/// The visibility of ```openedView```.
///
/// Changing this variable is the same as ```changeOpened(to:animated:)``` with animation.
var isOpened: Bool {
get {
return isOpenedProtected
}
set {
changeOpened(to: newValue, animated: true)
}
}
private var openedViewHeightConstraint: NSLayoutConstraint! = nil
private var openedViewBottomConstraint: NSLayoutConstraint! = nil
lazy private var buttonHandler: UIActionHandler = { _ in
self.isOpened.toggle()
}
init(tint color: UIColor, openedView givenOpenedView: UIView) {
self.openedView = givenOpenedView
openedView.translatesAutoresizingMaskIntoConstraints = false
// VIEW
self.view = UIView(frame: .zero)
view.translatesAutoresizingMaskIntoConstraints = false
view.clipsToBounds = true
self.topOpenedView = UIView(frame: .zero)
topOpenedView.clipsToBounds = true
topOpenedView.translatesAutoresizingMaskIntoConstraints = false
topOpenedView.addSubview(openedView)
openedView.clipsToBounds = true
topOpenedView.topAnchor.constraint(equalTo: openedView.topAnchor).isActive = true
topOpenedView.leadingAnchor.constraint(equalTo: openedView.leadingAnchor).isActive = true
topOpenedView.trailingAnchor.constraint(equalTo: openedView.trailingAnchor).isActive = true
self.openedViewBottomConstraint = topOpenedView.bottomAnchor.constraint(equalTo: openedView.bottomAnchor)
openedViewBottomConstraint.isActive = false
self.openedViewHeightConstraint = topOpenedView.heightAnchor.constraint(equalToConstant: 0)
openedViewHeightConstraint.isActive = true
for constraint in openedView.constraints {
constraint.priority -= 1
}
// ---
self.cellView = UIView(frame: .zero)
cellView.translatesAutoresizingMaskIntoConstraints = false
cellView.clipsToBounds = true
// Button
self.button = UIButton(frame: .zero, primaryAction: UIAction(handler: buttonHandler))
button.translatesAutoresizingMaskIntoConstraints = false
// Add subviews
cellView.addSubview(button)
cellView.heightAnchor.constraint(equalToConstant: 45).isActive = true
cellView.leadingAnchor.constraint(equalTo: button.leadingAnchor).isActive = true
cellView.trailingAnchor.constraint(equalTo: button.trailingAnchor).isActive = true
cellView.topAnchor.constraint(equalTo: button.topAnchor).isActive = true
cellView.bottomAnchor.constraint(equalTo: button.bottomAnchor).isActive = true
cellView.backgroundColor = color
cellView.heightAnchor.constraint(greaterThanOrEqualToConstant: 40).isActive = true
// View
view.layer.cornerRadius = 10
view.backgroundColor = .clear
view.addSubview(cellView)
view.addSubview(topOpenedView)
view.topAnchor.constraint(equalTo: cellView.topAnchor).isActive = true
view.leadingAnchor.constraint(equalTo: cellView.leadingAnchor).isActive = true
view.leadingAnchor.constraint(equalTo: topOpenedView.leadingAnchor).isActive = true
view.trailingAnchor.constraint(equalTo: cellView.trailingAnchor).isActive = true
view.trailingAnchor.constraint(equalTo: topOpenedView.trailingAnchor).isActive = true
view.bottomAnchor.constraint(equalTo: topOpenedView.bottomAnchor).isActive = true
topOpenedView.topAnchor.constraint(equalTo: cellView.bottomAnchor).isActive = true
cellView.bringSubviewToFront(button)
}
func changeOpened(to open: Bool, animated: Bool) {
if isOpenedProtected == open { return }
isOpenedProtected = open
let duration: Double = animated ? 0.5 : 0.0
self.view.layoutIfNeeded()
print(open ? "Opening" : "Closing")
self.openedViewHeightConstraint.isActive = !open
self.openedViewBottomConstraint.isActive = open
UIView.animate(withDuration: duration/*, delay: 0, options: .transitionFlipFromTop*/) {
self.view.layoutIfNeeded()
}
}
}
这个类基本上创建了一个视图,当按下它时另一个视图在它下面打开
这是我调用该类的代码:(在视图中确实加载了):
let myView = UIView(frame: .zero)
myView.translatesAutoresizingMaskIntoConstraints = false
myView.backgroundColor = .systemPink
myView.heightAnchor.constraint(equalToConstant: 120).isActive = true
let cell = Cell(tint: .blue, openedView: myView)
view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(cell.view)
cell.view.topAnchor.constraint(equalTo: view.topAnchor, constant: 100).isActive = true
cell.view.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
cell.view.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
但是动画的结果并不是我所期望的:
如您所见,动画很跳跃,因为它从中间而不是顶部开始。 我希望蓝色视图在粉红色视图打开和关闭时保持原位。
提前致谢
【问题讨论】:
标签: ios swift animation uiview uikit