One solution I found was to override willRotateToInterfaceOrientation:
and remove the UIDynamicItems
and then re-add them in didRotateFromInterfaceOrientation:
. This strikes me as rather hacky, and could potentially introduce bugs once I add more complex behaviors.
UIDynamics and Device Rotation
-
29-06-2022 - |
Question
If I add any kind of UIDynamicBehavior
to my views, it completely breaks things when the device is rotated. Here's what it is in portrait (displaying correctly):
And here it is in landscape, all broke:
I don't believe it's an autolayout issue because if I remove the calls to add the UIDynamicBehavior
it works fine with no autolayout problems. No autolayout errors are ever thrown either. Here's the code:
@interface SWViewController () {
UICollisionBehavior *coll;
UIDynamicAnimator *dynamicAnimator;
}
@implementation SWViewController
- (void)viewDidLoad {
[super viewDidLoad];
dynamicAnimator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self setupCollisions]; // commenting this out fixes the layout
}
- (void)setupCollisions {
NSArray *dynamicViews = @[greenView];
coll = [[UICollisionBehavior alloc] initWithItems:dynamicViews];
CGFloat topBound = CGRectGetMinY(greenView.frame);
[coll addBoundaryWithIdentifier:@"top"
fromPoint:CGPointMake(0, h1)
toPoint:CGPointMake(CGRectGetWidth(greenView.frame), h1)];
[dynamicAnimator addBehavior:coll];
}
If I override didRotateFromInterfaceOrientation
I can see that the top boundary of greenView
doesn't follow what autolayout says it should (again, removing the call to setupCollisions
fixes this).
The autolayout boundaries on greenView
are:
height = 200
trailing space to Superview = 0
leading space to Superview = 0
bottom space to Superview = 0
La solution
Autres conseils
Dynamic animator is changing frames of involved views. As a result any animation would be disturbed by a call to -[UIView setNeedsLayout]
(views would be put to constraint driven positions regardless on dynamic animation state.
My observation is that is you use auto-generated layout constraints the dynamic animator removes them from any view involved in the animation.
If you add your own layout constraints - they persist - but can disturb your animation when view is asked to recalculate layout.
Please double check your auto layout constraints.
I had a very similar problem:
In my case, I have a subview, MyView, which had a set of constraints: V:|-(0)-[MyView], V:[MyView]-(0)-|, H:[MyView:(==300)], and it works good with out UIDynamics. But after adding UIDynamics to MyView, the width changed during rotation, which is very similar to your problem.
I fixed it by adding one more constraint: H:|-(0)-[MyView]