Closed mikee179 closed 12 years ago
Thank you very much for your detailed bug report. I was modifying the transforms and the frames of rotated views simultaneously, which is never a good idea.
This issue has been fixed in develop (commit 17571fbdbd68b6ff25d9bac5058f162e0d1d62fd)
If you rotate multiple times the underlying views of an HLSStackController will no longer transition correctly during a pop animation for pushfrom transition styles.
Repro steps on iPad: Implement an HLSStackController 1) Push a viewcontroller 2) Rotate 3) Pop viewcontroller 4) Push viewcontroller 5) Rotate 6) Pop viewcontroller
This last pop will place the underlying view in the wrong place.
Can also repro by push, rotate, [rotate ..], pop.
The problem is that the root view's transform property is not adjusted properly when handling the frame adjustment for the rotation.
In HLSContainerContent's rotationAnimationForContainerContentStack:containerView:withDuration:
e.g., case HLSTransitionStylePushFromRight: { CGFloat offset = CGRectGetWidth(fixedFrame) + -->> belowView.transform.tx <<-- ; viewAnimationStep.transform = CATransform3DMakeTranslation(-offset, 0.f, 0.f); break; }
The view's transform property is used as part of the offset calculation for the rotation adjustment animation.
However, In HLSAnimation's playStep:animated: method to apply the transform:
view.frame = CGRectApplyAffineTransform(view.frame, convTransform);
The transform is used to create a new frame for the view, but the views transform is left alone.
Thus, consider a view that has a portrait width of 650, and a landscape width of 900.
In portrait mode, you push a new view controller using the HLSStackController.
The root view now has a transform with a tx of -650 and an origin.x of -650
Now, the orientation is changed to landscape.
The root view's width is now 900. So, offset = 900 + (-650) = 250 in rotationAnimationForContainerContentStack:containerView:withDuration:
In playStep:animated:, this creates a new frame with an origin of -900 for the root view, which is correct. However, the root view's transform tx is still -650.
So if you rotate again to portrait, the view width is back to 650. Thus, the offset calculation is now offset = 650 + (-650) = 0. So in playStep:animated: no adjust will be performed on the frame and it will still be at -900. But since we're in portrait mode, when the top view is popped, the root view will only be brought in by 650, thus incorrectly positioning it.
I was able to fix the problem by changing view.frame = CGRectApplyAffineTransform(view.frame, convTransform);
to
view.transform = CGAffineTransformConcat(view.transform, convTransform);
in playStep:animated:
This had the affect of both changing the frame and correctly updating the view's transform property so no matter how many times you rotate, the offset calculation will be correct.