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)
}
}
}
CodePudding user response:
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)}
CodePudding user response:
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:
Finally, the results of the experiment can be seen in the gif below, followed by the code:
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)
})
}
}