Home > Enterprise >  Add/ expand animation will cause unwanted UIScrollView scrolling
Add/ expand animation will cause unwanted UIScrollView scrolling

Time:08-08

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!

enter image description here

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

enter image description here

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

enter image description here

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

  • Related