iOS-使按钮在静态视图中旋转,如相机应用程序



我正在尝试制作一个类似iPhone Camera应用程序上的顶部和底部栏的视图。我无法获得俯视图和仰视图来保持肖像。

当我使用- (BOOL)shouldAutorotate时,可以预见,旋转通知会停止。我已经尝试过用setNeedsUpdateConstraints更新约束,但仍然得到了动画效果。我希望视图被锁定,只希望UI按钮旋转。

如何使视图中的按钮旋转,而使其他所有按钮保持锁定?

我有一个UIViewController,当设备旋转时,它只旋转其中的一些子视图。(这在iOS7下运行良好,但在iOS8下会中断。)您需要使用CGAffineTransform来"手动旋转"视图。

这里有一些代码:

@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

我们在UIViewController上创建了一个类别来处理这种行为。以下是相关代码:

@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

现在,这在iOS8下并不完美,我的问题请参阅iOS8中使用CGAffineTransform旋转时UIView不调整大小。

Swift 5中,并使用transform属性手动旋转。

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
        }
    }
}

我在这里的博客文章中有详细信息:https://samwize.com/2019/08/06/how-to-rotate-selected-views-like-camera-app/

最新更新