使用按钮在iOS中以编程方式更改方向

16

我有一个视图控制器,希望它能有以下功能。在这个视图控制器中,我有一个按钮,当点击它时,强制将方向旋转到横向右侧。

在“部署信息 - 设备方向”中,我启用了“横向右侧”和“纵向”。

需要说明的是,在我的设备上,我启用了“纵向方向锁定”,因此我需要使用以下代码通过编程方式旋转方向。

let rotateButton: UIButton = {
    let btn = UIButton(type: .system)
    btn.setTitle("Rotate", for: .normal)
    btn.setTitleColor(.red, for: .normal)
    btn.addTarget(self, action: #selector(rotateTapped), for: .touchUpInside)
    return btn
}()

@objc func rotateTapped() {
    let value = UIInterfaceOrientation.landscapeRight.rawValue
    UIDevice.current.setValue(value, forKey: "orientation")
}
因此,上述代码正常工作,屏幕正在旋转。 虽然我希望当用户回到纵向时,屏幕可以再次自动旋转到纵向,而无需按任何按钮。 当“锁定纵向方向”开启时,屏幕不会旋转回纵向。
我尝试过以下代码,但没有成功。
1)
    NotificationCenter.default.addObserver(self, selector: #selector(rotated), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)


@objc func rotated() {
    if UIDevice.current.orientation.isLandscape {
        print("Landscape") //when the user taps the button this is being printed.
    } else {
        print("Portrait") //when the user rotates back to portrait this is NOT being printed.
    }
}

并且2)

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    if UIDevice.current.orientation == .landscapeRight {
        let value = UIInterfaceOrientation.portrait.rawValue
        UIDevice.current.setValue(value, forKey: "orientation")
    }
}

当用户再次旋转手机时,有没有任何想法可以使其更改回纵向?

3个回答

23

我没有Swift代码。下面是我的Objective C代码,它对我有效。您可以根据需要将其转换为Swift。

Objective C

UIInterfaceOrientation currentOrientation = [UIApplication sharedApplication].statusBarOrientation;
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];    
[UIViewController attemptRotationToDeviceOrientation];

更新

Swift 4.0

var value  = UIInterfaceOrientation.landscapeRight.rawValue
if UIApplication.shared.statusBarOrientation == .landscapeLeft || UIApplication.shared.statusBarOrientation == .landscapeRight{
   value = UIInterfaceOrientation.portrait.rawValue
}

UIDevice.current.setValue(value, forKey: "orientation")
UIViewController.attemptRotationToDeviceOrientation()

上述代码已经由我测试过,运行良好。如果以上代码对您无效,那么可以使用performSelector稍微延迟一下执行。

更新于2023年2月9日(iOS 16)

class OrientationManager {
    static var landscapeSupported: Bool = false
}

AppDelegate.swift

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
  if OrientationManager.landscapeSupported {
      return .landscape
   }
   return .portrait    
}

当您想要在按钮单击时更改方向

@IBAction func btnChangeClick(){
        DispatchQueue.main.async {
            OrientationManager.landscapeSupported = !OrientationManager.landscapeSupported
            let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene
            windowScene?.requestGeometryUpdate(.iOS(interfaceOrientations: OrientationManager.landscapeSupported ? .landscape : .portrait))
            self.setNeedsUpdateOfSupportedInterfaceOrientations()
        }
    }

上面的代码,据我理解,是当用户按下一个按钮(或其他什么)并希望通过编程将屏幕旋转到横向模式时使用的,对吗? - Konstantinos Natsios
iOS 13怎么样? - EvGeniy Ilyin
我没有在iOS 13上检查以上代码。如果您发现任何问题,请告诉我。 - Hitesh Surani
@HiteshSurani - 有没有关于在SwiftUI上实现这个的想法? - undefined
抱歉伙计们,我从未尝试过SwiftUI。 - undefined

3
var currentOrientation: UIInterfaceOrientation = UIApplication.shared.statusBarOrientation
var value = .landscapeRight
UIDevice.current.setValue(value, forKey: "orientation")
UIViewController.attemptRotationToDeviceOrientation()

4
请在解释代码含义的同时改善您的回答,使其更加通俗易懂,但不要改变原意。请勿在回答中包含任何其他信息。 - ricardopereira

0
 @property (nonatomic) UIDeviceOrientation m_CurrentOrientation ;

/* 你需要在你的ViewDidload或者ViewWillAppear中声明这些代码 */
- (void)viewDidLoad

   {

   [super viewDidLoad];

   [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

   [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(deviceOrientationDidChange:) name: UIDeviceOrientationDidChangeNotification object: nil];
}

现在我们的设备在改变方向时会发出通知,这样你就可以根据当前方向来控制你的代码或程序。
- (void)deviceOrientationDidChange:(NSNotification *)notification

 {

 //Obtaining the current device orientation

 /* Where self.m_CurrentOrientation is member variable in my class of type UIDeviceOrientation */

 self.m_CurrentOrientation = [[UIDevice currentDevice] orientation];

    // Do your Code using the current Orienation 

 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接