skip to Main Content

How can I make scrollview scroll to bottom a little bit and scroll to top a little bit again. I has to be animated so users will notice there is a scroll view. I tried this code block but didn’t work.

public extension UIScrollView {
   
    func scrollToBottom(animated: Bool) {
        let bottomOffset = CGPoint(x: 0, y: contentSize.height - bounds.size.height + contentInset.bottom)
        setContentOffset(bottomOffset, animated: animated)
    }
    
    func scrollToTop(animated: Bool) {
        setContentOffset(.zero, animated: animated)
    }
    
    func scrollableAnimation(animated: Bool) {
        scrollToBottom(animated: animated)
        UIView.animate(withDuration: 0.5, delay: 0.5) {
            self.scrollToTop(animated: animated)
        }
    }
} 

2

Answers


  1. You can play with this code and also change the animation accordingly . you can change the x and y value to change the scroll position accordingly

    UIView.animate(withDuration: 1.0, delay: 0.3, options: .transitionCurlDown) {
       self.scrollView.setContentOffset(CGPoint(x: 0, y: 200), animated: true)
     } completion: { res in
          self.scrollView.setContentOffset(CGPoint(x: 0, y: -200), animated: true)}
    
    Login or Signup to reply.
  2. I have reason to believe that your call to get the contentSize.height of the scrollview content returns 0.

    Example I have used

    I made a VC with a UIScrollView which embeds a UIStackView, which in return has multiple UIViews of various sizes embedded in it.

    Heights of each UIViews embedded in the UIStackView are as follows (See the results gif for to better understand):

    Yellow: 250
    Blue: 1000
    LightBlue: 500
    Pink: 250
    
    Total: 2000
    

    Solution

    To rectify the issue of content height being 0, add a computed property that will get the contentSize after laying out any subviews in the scroll view. Refer to scrollViewContentHeight: CGFloat in the following code:

    class ViewController: UIViewController {
        
        // Any IBOutlets
    
        /// To get the height of the content embedded inside the scrollview
        var scrollViewContentHeight: CGFloat {
            scrollview.layoutIfNeeded()
            return scrollview.contentSize.height
        }
        
        override func viewDidLoad() {...}
        
        override func viewDidAppear(_ animated: Bool) {...}
    }
    

    This will return the actual content height (in the case of my example, 2000) of the scrollView. Using this, you can run the animations using the scroll view animations you have provided.

    It is important that you trigger the animations in the viewDidAppear(animated:) lifecycle function as that is where animations are usually triggered. And more importantly, that’s when the user will first see the view, meaning the content of the entire VC (including the scroll view) would have already been loaded.

    Results

    Here I have added a print() statement inside the viewDidAppear(animated:) function to verify the content height of the scroll view:

    enter image description here

    Finally, the results of the experiment can be seen in the gif below, followed by the code:

    enter image description here

    class ViewController: UIViewController {
    
        @IBOutlet weak var scrollview: UIScrollView!
        
        /// Height of the content embedded inside the scrollview
        var scrollViewContentHeight: CGFloat {
            scrollview.layoutIfNeeded()
            return scrollview.contentSize.height
        }
        
        override func viewDidLoad() {
            super.viewDidLoad()
        }
        
        override func viewDidAppear(_ animated: Bool) {
            super.viewDidAppear(animated)
    
            print("The scrollView height is:",scrollViewContentHeight)
    
            // Begin scroll to bottom animation
            DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
                self.scrollview.scrollToBottom(animated: true)
            })
            
            // Begin scroll to top animation
            DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: {
                self.scrollview.scrollToTop(animated: true)
            })
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search