Swift를 사용하여 하나의 View 컨트롤러에 가로 모드 적용
응용 프로그램에서 가로 모드로 하나의 보기만 강제로 설정하려고 합니다. 호출합니다.
override func shouldAutorotate() -> Bool {
print("shouldAutorotate")
return false
}
override func supportedInterfaceOrientations() -> Int {
print("supportedInterfaceOrientations")
return Int(UIInterfaceOrientationMask.LandscapeLeft.rawValue)
}
override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
return UIInterfaceOrientation.LandscapeLeft
}
보기가 세로 모드로 시작되고 장치 방향을 변경하면 계속 회전합니다.shouldAutorotate()
메서드가 호출되지 않습니다.
어떤 도움이라도 주시면 감사하겠습니다.
다른 사용자에게 유용할 수 있습니다. 보기를 가로 모드로 강제 실행하는 방법을 찾았습니다.
DidLoad() 보기에 저장합니다.
let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
그리고.
override var shouldAutorotate: Bool {
return true
}
스위프트 4
override func viewDidLoad() {
super.viewDidLoad()
let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .landscapeLeft
}
override var shouldAutorotate: Bool {
return true
}
보기가 탐색 컨트롤러에 내장된 경우 위의 항목만 사용할 수 없습니다.클래스 정의 후 다음 확장자까지 단계적으로 진행해야 합니다.
extension UINavigationController {
override open var shouldAutorotate: Bool {
get {
if let visibleVC = visibleViewController {
return visibleVC.shouldAutorotate
}
return super.shouldAutorotate
}
}
override open var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation{
get {
if let visibleVC = visibleViewController {
return visibleVC.preferredInterfaceOrientationForPresentation
}
return super.preferredInterfaceOrientationForPresentation
}
}
override open var supportedInterfaceOrientations: UIInterfaceOrientationMask{
get {
if let visibleVC = visibleViewController {
return visibleVC.supportedInterfaceOrientations
}
return super.supportedInterfaceOrientations
}
}}
스위프트 3
override func viewDidLoad() {
super.viewDidLoad()
let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
}
private func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.landscapeLeft
}
private func shouldAutorotate() -> Bool {
return true
}
Swift 4, iOS 11에서 테스트 완료
projectTarget -> General -> DeploymentInfo (Device Orientation) -> Portrait (가로좌측 및 가로우측은 선택사항)에서 방향을 지정할 수 있습니다.
앱 대표자
var myOrientation: UIInterfaceOrientationMask = .portrait
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return myOrientation
}
LandScpae 뷰 컨트롤러
override func viewDidLoad() {
super.viewDidLoad()
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.myOrientation = .landscape
}
온 디스미스버튼탭
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.myOrientation = .portrait
바로 그거야.:)
Swift 2.2 사용
시도:
let value = UIInterfaceOrientation.LandscapeLeft.rawValue
UIDevice.currentDevice().setValue(value, forKey: "orientation")
다음 사용자:
UIViewController.attemptRotationToDeviceOrientation()
Apple의 UIView 컨트롤러 클래스 참조:
일부 뷰 컨트롤러는 앱별 조건을 사용하여 지원되는 인터페이스 방향을 결정할 수 있습니다.보기 컨트롤러에서 이 작업을 수행하는 경우 이러한 조건이 변경되면 앱에서 이 클래스 메소드를 호출해야 합니다.시스템이 즉시 새 방향으로 회전을 시도합니다.
그런 다음 다른 사용자가 제안한 대로 다음 방법을 적절히 재정의합니다.
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.LandscapeLeft
}
override func shouldAutorotate() -> Bool {
return true
}
시그니처 뷰와 비슷한 문제를 겪고 있었는데 이것으로 해결되었습니다.
AppDelegate에서 다음을 추가합니다.
//Orientation Variables
var myOrientation: UIInterfaceOrientationMask = .portrait
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return myOrientation
}
방향을 변경하려는 viewController에 다음을 추가합니다.
override func viewDidLoad() {
super.viewDidLoad()
self.rotateToLandsScapeDevice()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.rotateToPotraitScapeDevice()
}
func rotateToLandsScapeDevice(){
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.myOrientation = .landscapeLeft
UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")
UIView.setAnimationsEnabled(true)
}
func rotateToPotraitScapeDevice(){
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.myOrientation = .portrait
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
UIView.setAnimationsEnabled(true)
}
저는 Zeesha의 답변과 Sazz의 답변을 종합한 결과가 가장 좋았습니다.
AppDelegate.swift에 다음 행을 추가합니다.
var orientationLock = UIInterfaceOrientationMask.portrait
var myOrientation: UIInterfaceOrientationMask = .portrait
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return myOrientation
}
다음 행을 뷰 컨트롤러 클래스에 추가합니다.
let appDel = UIApplication.shared.delegate as! AppDelegate
행을 뷰 의 보다행컨에추에 합니다.viewDidLoad()
:
appDel.myOrientation = .landscape
UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")
(선택사항) 해제 기능에 다음 행을 추가합니다.
appDel.myOrientation = .portrait
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
이러한 코드 라인이 수행하는 작업은 기본 방향을 세로로 설정하고 뷰 컨트롤러가 로드될 때 가로로 회전한 다음 뷰 컨트롤러가 닫히면 세로로 다시 재설정하는 것입니다.
덮어쓰기(ViewController에서):
override public var shouldAutorotate: Bool {
return false
}
override public var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .landscapeRight
}
override public var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
return .landscapeRight
}
IOS 13에 대한 힌트.13 는 IOS 13과 다른 VC를 가지고 .modalPresentationStyle
~하듯이.automatic
및 장치는 전체 화면 VC 대신 모달 뷰를 제공합니다.이 문제를 해결하려면 설정해야 합니다.modalPresentationStyle
.fullScreen
예:
let viewController = YourViewController()
viewController.modalPresentationStyle = .fullScreen
컨트롤러 하나를 세로 방향으로 강제 배치해야 했습니다.이것을 추가하는 것은 저에게 효과가 있었습니다.
iOS 11을 사용하는 swift 4
override var supportedInterfaceOrientations : UIInterfaceOrientationMask{
return .portrait
}
저는 제 프로젝트에서 비슷한 문제에 직면했습니다.초상화만 지원됩니다.ViewController 구조는 Navigation에 컨트롤러(A라고 함)와 긴 ScrollView가 포함되어 있다는 것입니다.저는 B(가로 오른쪽)에게 A(세로 오른쪽)를 선물해야 합니다.
처음에는 아래의 방법을 시도해 보았는데 효과가 있는 것 같았지만 결국 버그를 발견했습니다.
스위프트 5 & iOS12
// In B controller just override three properties
override var shouldAutorotate: Bool {
return false
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.landscapeRight
}
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
return .landscapeRight
}
그리고는 뭔가 이상해집니다.컨트롤러 B가 컨트롤러 A로 해제될 때.컨트롤러 A의 ScrollView가 슬라이드되었습니다.
그래서 저는 다른 방법을 사용해서 화면을 돌립니다.viewWillAppear
당신은 아래의 코드를 볼 수 있습니다.
// In controller B
// not need override shouldAutorotate , supportedInterfaceOrientations , preferredInterfaceOrientationForPresentation
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let appDel = UIApplication.shared.delegate as! AppDelegate
appDel.currentOrientation = .landscapeRight
UIDevice.current.setValue( UIInterfaceOrientation.landscapeRight.rawValue, forKey: "orientation")
UIViewController.attemptRotationToDeviceOrientation()
}
//in viewWillDisappear rotate to portrait can not fix the bug
override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
let appDel = UIApplication.shared.delegate as! AppDelegate
appDel.currentOrientation = .portrait
UIDevice.current.setValue( UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
UIViewController.attemptRotationToDeviceOrientation() //must call
super.dismiss(animated: true, completion: nil)
}
// in AppDelegate
// the info plist is only supported portrait also, No need to change it
var currentOrientation : UIInterfaceOrientationMask = .portrait
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return self.currentOrientation
}
Swift 2.2에서 작동
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
if self.window?.rootViewController?.presentedViewController is SignatureViewController {
let secondController = self.window!.rootViewController!.presentedViewController as! SignatureViewController
if secondController.isPresented {
return UIInterfaceOrientationMask.LandscapeLeft;
} else {
return UIInterfaceOrientationMask.Portrait;
}
} else {
return UIInterfaceOrientationMask.Portrait;
}
}
스위프트 3.이렇게 하면 사용자가 앱을 다시 열 때마다 방향이 잠깁니다.
class MyViewController: UIViewController {
...
override func viewDidLoad() {
super.viewDidLoad()
// Receive notification when app is brought to foreground
NotificationCenter.default.addObserver(self, selector: #selector(self.onDidBecomeActive), name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil)
}
// Handle notification
func onDidBecomeActive() {
setOrientationLandscape()
}
// Change orientation to landscape
private func setOrientationLandscape() {
if !UIDevice.current.orientation.isLandscape {
let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey:"orientation")
UIViewController.attemptRotationToDeviceOrientation()
}
}
// Only allow landscape left
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.landscapeLeft
}
/*
// Allow rotation - this seems unnecessary
private func shouldAutoRotate() -> Bool {
return true
}
*/
...
}
스위프트 4
오리엔테이션을 유지하려고 노력하는 것 외에는 아무 것도 효과가 없었습니다.
...
override func viewDidLoad() {
super.viewDidLoad()
forcelandscapeRight()
let notificationCenter = NotificationCenter.default
notificationCenter.addObserver(self, selector: #selector(forcelandscapeRight), name: Notification.Name.UIDeviceOrientationDidChange, object: nil)
}
@objc func forcelandscapeRight() {
let value = UIInterfaceOrientation.landscapeRight.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
}
....
ViewController의 ViewDidLoad 메서드에서 아래 함수를 호출합니다.
func rotateDevice(){
UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")
UIView.setAnimationsEnabled(true) // while rotating device it will perform the rotation animation
}`
앱 위임 파일 아래에 함수 및 변수 추가
//Orientation Variables
var orientationLock = UIInterfaceOrientationMask.portrait
var myOrientation: UIInterfaceOrientationMask = .portrait
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { return .landscape }
지원되는 문서에 따라인터페이스 방향shouldAutorotate
는 메드가반야합니다어되를 .true
또는YES
에서 목-C서, 그가 되도록 .supportedInterfaceOrientations
고려됩니다.
iOS 16+:requestGeometryUpdate(_:errorHandler:)
API
트위터에서 @simonbs가 언급한 바와 같이, iOS 16은 현재 인터페이스 방향을 업데이트하기 위한 새로운 API를 도입합니다.대부분의 경우에는 다른 기존 방법이 작업을 수행하지만, 일부 에지의 경우에는 작동하지 않습니다(이 답변에서 제안한 대로 개인 API를 사용하도록 강제함).여기서 새로운 공개 API가 도움이 됩니다.
API는 다음과 같이 작동합니다.
windowScene.requestGeometryUpdate(.iOS(interfaceOrientations: .portrait))
오류를 처리하기 위해 선택적으로 폐쇄를 통과할 수도 있습니다(오류가 발생할 수 있는 상황에 대한 경험은 없지만).
windowScene.requestGeometryUpdate(.iOS(interfaceOrientations: .portrait)) { error in
// Handle error...
}
나의 해결책은
방금 AppDelegate에서 아래 코드를 추가했습니다.
enum PossibleOrientations {
case portrait
case landscape
func o() -> UIInterfaceOrientationMask {
switch self {
case .portrait:
return .portrait
case .landscape:
return .landscapeRight
}
}
}
var orientation: UIInterfaceOrientationMask = .portrait
func switchOrientation(to: PossibleOrientations) {
let keyOrientation = "orientation"
if to == .portrait && UIDevice.current.orientation.isPortrait {
return
} else if to == .landscape && UIDevice.current.orientation.isLandscape {
return
}
switch to {
case .portrait:
orientation = .portrait
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: keyOrientation)
case .landscape:
orientation = .landscapeRight
UIDevice.current.setValue(UIInterfaceOrientation.landscapeRight.rawValue, forKey: keyOrientation)
}
}
변경하려면 아래 코드로 전화하십시오.
override func viewDidLoad() {
super.viewDidLoad()
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
appDelegate.switchOrientation(to: .landscape)
}
}
또는 아래와 같이
@IBAction func actBack() {
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
appDelegate.switchOrientation(to: .portrait)
}
self.navigationController?.popViewController(animated: true)
}
// below code put in view controller
// you can change landscapeLeft or portrait
override func viewWillAppear(_ animated: Bool) {
UIDevice.current.setValue(UIInterfaceOrientation.landscapeRight.rawValue, forKey: "orientation")
}
override var shouldAutorotate: Bool {
return true
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .landscapeRight
}
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
return .landscapeRight
}
아래의 많은 답변을 시도해 보았지만 효과가 없었습니다.특히 앱에서 네비게이션 바와 탭 바도 구현되는 경우에는 더욱 그렇습니다.저에게 효과가 있었던 해결책은 Sunny Lee가 여기 게시물에 제공했습니다: Sunny Lee, 중간 게시물
다음은 이 게시물의 업데이트입니다.원해
게시물의 솔루션을 구현할 때 변경한 것은 .But UpsideDown을 제외한 나머지 부분을 .landscape left로 변경한 것뿐입니다.
스위프트 5가 탑재된 Xcode 11에서 나는 다음을 구현했습니다.그러나 프로젝트 대상에 대한 장치 방향이 모든 방향을 포함하지 않는 경우에만 작동합니다.Upside Down 확인을 비활성화했습니다.이 이후에는 다음 코드가 작동합니다.모든 확인란이 활성화된 경우 코드가 호출되지 않습니다.
class MyController : UINavigationController {
override var shouldAutorotate: Bool {
return true
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .landscape
}
}
IOS 13 ~ 16.4에서 테스트됨
먼저 회전식 보기 컨트롤러에 대한 프로토콜을 만듭니다.
protocol Rotatable:UIViewController{}
그 다음 아래 코드를 추가합니다.AppDelegate
:
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
guard let topVC = UIApplication.getTopViewController(base: window?.rootViewController) as? Rotatable else {
return .portrait
}
guard !topVC.isModal else {
//Use isBeingDismissed to prevent rotation glitches when changing the top view controller.
return topVC.isBeingDismissed ? .portrait : topVC.supportedInterfaceOrientations
}
return topVC.supportedInterfaceOrientations
}
다음 확장자도 필요합니다.
extension UIApplication {
static func getTopViewController(base: UIViewController? = rootViewController) -> UIViewController? {
if let nav = base as? UINavigationController {
return getTopViewController(base: nav.visibleViewController)
}
if let tab = base as? UITabBarController {
if let selected = tab.selectedViewController {
return getTopViewController(base: selected)
}
}
if let presented = base?.presentedViewController {
return getTopViewController(base: presented)
}
return base
}
static var rootViewController:UIViewController?{
return UIApplication
.shared
.connectedScenes
.flatMap { ($0 as? UIWindowScene)?.windows ?? [] }
.last { $0.isKeyWindow }?.rootViewController
}
}
extension UIViewController{
var isModal: Bool {
let presentingIsModal = presentingViewController != nil
let presentingIsNavigation = navigationController?.presentingViewController?.presentedViewController == navigationController
let presentingIsTabBar = tabBarController?.presentingViewController is UITabBarController
return presentingIsModal || presentingIsNavigation || presentingIsTabBar
}
}
그런 다음 뷰 컨트롤러에서 다음 변수를 재정의하면 됩니다.
class MyViewController: UIViewController,Rotatable {
override var shouldAutorotate: Bool {
return true
}
override public var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .landscape
}
}
class CustomUIViewController : UIViewController{
override var supportedInterfaceOrientations : UIInterfaceOrientationMask{
return .landscapeLeft
}
}
class ViewController: CustomUIViewController {
.
.
.
}
언급URL : https://stackoverflow.com/questions/27037839/force-landscape-mode-in-one-viewcontroller-using-swift
'source' 카테고리의 다른 글
사용자 지정 개체의 각 Note Property를 반복 실행 (0) | 2023.09.06 |
---|---|
관찰 가능한 RXJ의 .pipe() 메서드와 .subscribe() 메서드 간의 차이 (0) | 2023.09.01 |
오라클 pl/sql 배열 (0) | 2023.09.01 |
Scaleed Bitmap을 생성하기 위한 필터 매개 변수는 무엇을 합니까? (0) | 2023.09.01 |
phpmyadmin sql 탭이 제대로 작동하지 않습니다. (0) | 2023.09.01 |