I notice that, if I perform add/ expand animation within an UIScrollView
, it will cause unwanted scrolling behavior, when the UIScrollView
fill with enough content to become scroll-able.
As you can see in the following animation, initially, the add/ expand animation works just fine.
When we have added enough item till the UIScrollView
scrollable, whenever a new item is added, and UIScrollView
will first perform scroll down, and then scroll up again!
My expectation is that, the UIScrollView
should remain static, when add/ expand animation is performed.
Here's the code which performs add/ expand animation.
Add/ expand animation
@IBAction func add(_ sender: Any) {
let customView = CustomView.instanceFromNib()
customView.hide()
stackView.addArrangedSubview(customView)
// Clear off horizontal swipe in animation caused by addArrangedSubview
stackView.superview?.layoutIfNeeded()
customView.show()
// Perform expand animation.
UIView.animate(withDuration: 1) {
self.stackView.superview?.layoutIfNeeded()
}
}
Here's the constraint setup of the UIScrollView
& added custom view item
Constraint setup
Custom view
class CustomView: UIView {
private var zeroHeightConstraint: NSLayoutConstraint!
@IBOutlet weak var borderView: UIView!
@IBOutlet weak var stackView: UIStackView!
override func awakeFromNib() {
super.awakeFromNib()
borderView.layer.cornerRadius = stackView.frame.height / 2
borderView.layer.masksToBounds = true
borderView.layer.borderWidth = 1
zeroHeightConstraint = self.safeAreaLayoutGuide.heightAnchor.constraint(equalToConstant: 0)
zeroHeightConstraint.isActive = false
}
func hide() {
zeroHeightConstraint.isActive = true
}
func show() {
zeroHeightConstraint.isActive = false
}
}
Here's the complete source code
The "add view" function now becomes (I added a Bool so we can skip the animation on the initial add in viewDidLoad()
):
func addCustomView(_ animated: Bool) {
let customView = CustomView.instanceFromNib()
stackView.addArrangedSubview(customView)
customView.isHidden = true
if animated {
DispatchQueue.main.async {
UIView.animate(withDuration: 1) {
customView.isHidden = false
}
}
} else {
customView.isHidden = false
}
}
And we can get rid of all of the hide() / show()
and zeroHeightConstraint
in the custom view class:
class CustomView: UIView {
@IBOutlet weak var borderView: UIView!
@IBOutlet weak var stackView: UIStackView!
override func awakeFromNib() {
super.awakeFromNib()
borderView.layer.masksToBounds = true
borderView.layer.borderWidth = 1
}
override func layoutSubviews() {
super.layoutSubviews()
borderView.layer.cornerRadius = borderView.bounds.height * 0.5
}
}
Since it's a bit difficult to clearly show everything here, I forked your project with the changes: https://github.com/DonMag/add-expand-animation-in-scroll-view