Reputation: 3767
I am trying to make a view like the top and bottom bars on the iPhone Camera app. I can't get the top view and bottom view to stay in portrait.
When i use - (BOOL)shouldAutorotate
, and predictably the rotation notifications stop. I have tried updating constraints with setNeedsUpdateConstraints
but I still get the animation effect. I want the views to be locked and just the UIButtons to rotate.
How do you get just the buttons in a view to rotate and everything else to remain locked?
Upvotes: 2
Views: 1205
Reputation: 27373
In Swift 5, and using the transform
property to manually rotate.
override func viewDidLoad() {
super.viewDidLoad()
UIDevice.current.beginGeneratingDeviceOrientationNotifications()
NotificationCenter.default.addObserver(self, selector: #selector(deviceOrientationDidChange),
name: UIDevice.orientationDidChangeNotification, object: nil)
}
@objc private func deviceOrientationDidChange() {
let viewsToRotate = [button1, button2, labelXX, viewXX]
let rotation = UIDevice.current.orientation.rotationTransform
viewsToRotate.forEach {
$0.transform = rotation
}
}
extension UIDeviceOrientation {
var rotationTransform: CGAffineTransform {
switch self {
case .landscapeLeft: return CGAffineTransform(rotationAngle: .pi/2)
case .landscapeRight: return CGAffineTransform(rotationAngle: -.pi/2)
case .portraitUpsideDown: return CGAffineTransform(rotationAngle: .pi)
default: return .identity
}
}
}
I have the details in my blog post here: https://samwize.com/2019/08/06/how-to-rotate-selected-views-like-camera-app/
Upvotes: 1
Reputation: 8741
I have a UIViewController that only rotates some of it subviews when the device is rotated. (This works fine under iOS7 but breaks under iOS8.) You need to use CGAffineTransform to "hand rotate" your views.
Here's some code:
@interface VVViewController ()
@property (weak, nonatomic) IBOutlet UIView *pinnedControls;
@property (nonatomic, strong) NSMutableArray *pinnedViews;
@end
@implementation VVViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.pinnedViews = [NSMutableArray array];
[self.pinnedViews addObject:self.pinnedControls];
}
-(void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
[UIViewController rotatePinnedViews:self.pinnedViews forOrientation:self.interfaceOrientation];
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation) && UIInterfaceOrientationIsLandscape(self.interfaceOrientation)) {
[UIViewController rotatePinnedViews:self.pinnedViews forOrientation:toInterfaceOrientation];
}
}
@end
We've made a category on UIViewController to handle this behavior. Here's the pertinent code:
@implementation UIViewController (VVSupport)
+ (void)rotatePinnedViews:(NSArray *)views forOrientation:(UIInterfaceOrientation)orientation {
const CGAffineTransform t1 = [UIViewController pinnedViewTansformForOrientation:orientation counter:YES];
const CGAffineTransform t2 = [UIViewController pinnedViewTansformForOrientation:orientation counter:NO];
[views enumerateObjectsUsingBlock:^(UIView *view, NSUInteger idx, BOOL *stop) {
// Rotate the view controller
view.transform = t1;
[view.subviews enumerateObjectsUsingBlock:^(UIView *counterView, NSUInteger idx, BOOL *stop) {
// Counter-rotate the controlsUIin the view controller
counterView.transform = t2;
}];
}];
}
+ (CGAffineTransform)pinnedViewTansformForOrientation:(UIInterfaceOrientation)orientation counter:(BOOL)counter {
CGAffineTransform t;
switch ( orientation ) {
case UIInterfaceOrientationPortrait:
case UIInterfaceOrientationPortraitUpsideDown:
t = CGAffineTransformIdentity;
break;
case UIInterfaceOrientationLandscapeLeft:
t = CGAffineTransformMakeRotation(counter ? M_PI_2 : -M_PI_2);
break;
case UIInterfaceOrientationLandscapeRight:
t = CGAffineTransformMakeRotation(counter ? -M_PI_2 : M_PI_2);
break;
}
return t;
}
@end
Now, this doesn't work perfectly under iOS8, See UIView not resizing when rotated with a CGAffineTransform under iOS8 for my question.
Upvotes: 2