Reputation: 11
I have a UIViewController with a UIScrollView as subview. the scrollview size and origin are computed properties.
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let sizeWidth = view.frame.size.width - (view.frame.size.width / 5)
let sizeHeight = (view.frame.height / 5) * 3
let originX = (view.width-sizeWidth) / 2
// sizes & positions of container & subviews
slideScrollView.frame = CGRect(x: originX,
y: 50,
width: sizeWidth,
height: sizeHeight)
by tapping the sign in or login button, the scrollview should expand animated. but it is the opposite.
@objc private func loginButtonTapped() {
UIView.animate(withDuration: 5, delay: 0, options: .allowAnimatedContent) {
self.slideScrollView.frame.size.height += (self.view.frame.height / 5) * 1
}
}
it should expand, but it sets back to the action height property and expand to regular size, i hope anyone can tell me why this happens and may have a solution.
Upvotes: 0
Views: 88
Reputation: 20369
Thats because your viewDidLayoutSubviews
gets called multiple times (In this case twice as I have noticed by adding debug statements) when you start your animation with UIView.animate(withDuration:
and because you always reset the slideScrollView.frame
in viewDidLayoutSubviews
you see unnecessary side effects.
You can always check this by putting a break point in viewDidLayoutSubviews
when loginButtonTapped
gets triggered. Refer this question for similar explaination
If your intention to use viewDidLayoutSubviews
is to know when view is properly loaded and its frames are updated properly you can always use
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let sizeWidth = view.frame.size.width - (view.frame.size.width / 5)
let sizeHeight = (view.frame.height / 5) * 3
let originX = (view.width-sizeWidth) / 2
// sizes & positions of container & subviews
slideScrollView.frame = CGRect(x: originX,
y: 50,
width: sizeWidth,
height: sizeHeight)
}
Now your loginButtonTapped
should work fine.
As per apple docs: viewDidLayoutSubviews
Called to notify the view controller that its view has just laid out its subviews.
With that I think my explanation above makes sense, you use UIView.animate(withDuration:
to modify the frame of scrollView
so obviously View updates/re-renders the subViews hence viewDidLayoutSubviews
gets called when you call UIView.animate(withDuration:
and because of your frame update code in viewDidLayoutSubviews
you see adverse side effects
Upvotes: 1