source

iOS 8에서 뷰 컨트롤러 방향을 강제로 설정하는 방법은 무엇입니까?

ittop 2023. 5. 2. 22:56
반응형

iOS 8에서 뷰 컨트롤러 방향을 강제로 설정하는 방법은 무엇입니까?

iOS 8 이전에는 지원되는 코드와 함께 아래 코드를 사용했습니다.인터페이스 방향자동 회전 위임 메서드를 사용하여 앱 방향을 특정 방향으로 강제 지정합니다.아래 코드 스니펫을 사용하여 프로그램을 원하는 방향으로 회전시켰습니다.먼저 상태 표시줄 방향을 변경합니다.그런 다음 모달 보기를 표시하고 즉시 해제하면 보기가 원하는 방향으로 회전합니다.

[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:YES];
UIViewController *c = [[UIViewController alloc]init];
[self presentViewController:vc animated:NO completion:nil];
[self dismissViewControllerAnimated:NO completion:nil];

하지만 iOS 8에서는 이것이 실패하고 있습니다. 또한, 저는 스택 오버플로에서 사람들이 iOS 8 이후부터는 항상 이러한 접근 방식을 피해야 한다고 제안하는 몇 가지 답변을 보았습니다.

좀 더 구체적으로 말하면, 제 애플리케이션은 보편적인 유형의 애플리케이션입니다.컨트롤러는 총 3개입니다.

  1. First View 컨트롤러 - iPad에서는 모든 방향을 지원하고 iPhone에서는 세로(홈 버튼 아래)만 지원해야 합니다.

  2. Second View 컨트롤러 - 모든 조건에서 올바른 가로 방향만 지원해야 합니다.

  3. Third View 컨트롤러 - 모든 조건에서 올바른 가로 방향만 지원해야 합니다.

우리는 페이지 탐색을 위해 탐색 컨트롤러를 사용하고 있습니다.첫 번째 뷰 컨트롤러에서 버튼 클릭 동작으로 스택의 두 번째 뷰를 푸시합니다.따라서 두 번째 뷰 컨트롤러가 도착하면 장치 방향에 관계없이 앱은 가로 방향으로만 잠가야 합니다.

는 저의 아는나입니다.shouldAutorotate그리고.supportedInterfaceOrientations메서드가 두 번째 및 세 번째 보기 컨트롤러에 있습니다.

-(NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskLandscapeRight;
}

-(BOOL)shouldAutorotate {
    return NO;
}

iOS 8의 특정 방향에서 뷰 컨트롤러를 잠글 수 있는 더 나은 방법이 있습니까? 도와주세요!!

iOS 7 - 10의 경우:

목표-C:

[[UIDevice currentDevice] setValue:@(UIInterfaceOrientationLandscapeLeft) forKey:@"orientation"];
[UINavigationController attemptRotationToDeviceOrientation];

스위프트 3:

let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
UINavigationController.attemptRotationToDeviceOrientation()

그냥불세요주러로 요.- viewDidAppear:표시된 보기 컨트롤러의

만약 당신이 안에 있다면 방향 회전은 조금 더 복잡합니다.UINavigationController또는UITabBarController문제는 뷰 컨트롤러가 이러한 컨트롤러 중 하나에 포함된 경우 탐색 또는 탭 모음 컨트롤러가 우선 순위를 차지하고 자동 회전 및 지원되는 방향에 대한 결정을 내린다는 것입니다.

UINavigationController 및 UITabbarController에서 다음 2개의 확장 기능을 사용하여 이러한 컨트롤러 중 하나에 포함된 ViewController가 결정을 내릴 수 있도록 합니다.

View 컨트롤러에 강력한 기능 제공!

스위프트 2.3

extension UINavigationController {
    public override func supportedInterfaceOrientations() -> Int {
        return visibleViewController.supportedInterfaceOrientations()
    }
    public override func shouldAutorotate() -> Bool {
        return visibleViewController.shouldAutorotate()
    }
}

extension UITabBarController {
    public override func supportedInterfaceOrientations() -> Int {
        if let selected = selectedViewController {
            return selected.supportedInterfaceOrientations()
        }
        return super.supportedInterfaceOrientations()
    }
    public override func shouldAutorotate() -> Bool {
        if let selected = selectedViewController {
            return selected.shouldAutorotate()
        }
        return super.shouldAutorotate()
    }
}

스위프트 3

extension UINavigationController {
    open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return visibleViewController?.supportedInterfaceOrientations ?? super.supportedInterfaceOrientations
    }

    open override var shouldAutorotate: Bool {
        return visibleViewController?.shouldAutorotate ?? super.shouldAutorotate
    }
}

extension UITabBarController {
    open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        if let selected = selectedViewController {
            return selected.supportedInterfaceOrientations
        }
        return super.supportedInterfaceOrientations
    }

    open override var shouldAutorotate: Bool {
        if let selected = selectedViewController {
            return selected.shouldAutorotate
        }
        return super.shouldAutorotate
    }
}

이제 다음을 재정의할 수 있습니다.supportedInterfaceOrientations메서드 또는 사용자가 재정의할 수 있습니다.shouldAutoRotate잠금하려는 뷰 컨트롤러에서 잠금을 해제하지 않으면 앱의 플리스트에 지정된 기본 방향 동작을 상속하려는 다른 뷰 컨트롤러에서 재정의를 제외할 수 있습니다.

회전 사용 안 함

class ViewController: UIViewController {
    override func shouldAutorotate() -> Bool {
        return false
    }
}

특정 방향으로 잠금

class ViewController: UIViewController {
    override func supportedInterfaceOrientations() -> Int {
        return Int(UIInterfaceOrientationMask.Landscape.rawValue)
    }
}

이론적으로 이것은 모든 복잡한 뷰 컨트롤러 계층에 적용되어야 하지만, 저는 UITabBarController의 문제를 발견했습니다.어떤 이유로 기본 방향 값을 사용하려고 합니다.일부 문제를 해결하는 방법에 대해 알고 싶다면 다음 블로그 게시물을 참조하십시오.

화면 잠금 회전

이것이 저에게 도움이 되었습니다.

https://developer.apple.com/library/ /ios/documentation/UIKit/Reference/UIViewController_Class/index.html#//apple_ref/occ/clm/UIViewController/attemptRotationToDeviceOrientation

당신의 뷰에서 그것을 DidAppear: 메소드라고 부릅니다.

- (void) viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    [UIViewController attemptRotationToDeviceOrientation];
}

표시된 보기 컨트롤러인 경우 이를 무시할 수 있습니다.preferredInterfaceOrientationForPresentation

스위프트:

override func supportedInterfaceOrientations() -> Int {
  return Int(UIInterfaceOrientationMask.Landscape.rawValue)
}

override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
  return UIInterfaceOrientation.LandscapeLeft
}

override func shouldAutorotate() -> Bool {
  return false
}

Swift 2 iOS 8.x에서는 이러한 방식으로 작동합니다.

PS(이 방법은 모든 뷰 컨트롤러에서 자동 회전하는 것과 같은 방향 기능을 재정의할 필요가 없으며, AppDelegate에서는 한 가지 방법만 사용)

프로젝트 일반 정보에서 "전체 화면 필요"를 선택합니다.여기에 이미지 설명 입력

AppDelegate.swift에서 변수를 만듭니다.

var enableAllOrientation = false

다음 함수도 입력합니다.

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
        if (enableAllOrientation == true){
            return UIInterfaceOrientationMask.All
        }
        return UIInterfaceOrientationMask.Portrait
}

따라서 프로젝트의 모든 클래스에서 다음 변수를 viewWillAppear로 설정할 수 있습니다.

override func viewWillAppear(animated: Bool)
{
        super.viewWillAppear(animated)
        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        appDelegate.enableAllOrientation = true
}

장치 유형에 따라 선택해야 하는 경우 다음을 수행할 수 있습니다.

override func viewWillAppear(animated: Bool)
    {
        super.viewWillAppear(animated)
        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        switch UIDevice.currentDevice().userInterfaceIdiom {
        case .Phone:
        // It's an iPhone
           print(" - Only portrait mode to iPhone")
           appDelegate.enableAllOrientation = false
        case .Pad:
        // It's an iPad
           print(" - All orientation mode enabled on iPad")
           appDelegate.enableAllOrientation = true
        case .Unspecified:
        // Uh, oh! What could it be?
           appDelegate.enableAllOrientation = false
        }
    }

- 의 앱 않은 우선 - 일으로앱에문처제아있가텍만는지생것좋이각않은지은키적반▁first,만,지▁architect▁but생이각않▁wrong,▁is우▁going은▁appure▁a,,sh..t happens만약 그렇다면, 당신은 아래와 같은 것을 만들어 볼 수 있습니다:

final class OrientationController {

    static private (set) var allowedOrientation:UIInterfaceOrientationMask = [.all]

    // MARK: - Public

    class func lockOrientation(_ orientationIdiom: UIInterfaceOrientationMask) {
        OrientationController.allowedOrientation = [orientationIdiom]
    }

    class func forceLockOrientation(_ orientation: UIInterfaceOrientation) {
        var mask:UIInterfaceOrientationMask = []
        switch orientation {
            case .unknown:
                mask = [.all]
            case .portrait:
                mask = [.portrait]
            case .portraitUpsideDown:
                mask = [.portraitUpsideDown]
            case .landscapeLeft:
                mask = [.landscapeLeft]
            case .landscapeRight:
                mask = [.landscapeRight]
        }

        OrientationController.lockOrientation(mask)

        UIDevice.current.setValue(orientation.rawValue, forKey: "orientation")
    }
}

탄에서, 인AppDelegate

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // do stuff
    OrientationController.lockOrientation(.portrait)
    return true
}

// MARK: - Orientation

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
    return OrientationController.allowedOrientation
}

방향을 변경하려면 다음을 수행합니다.

OrientationController.forceLockOrientation(.landscapeRight)

참고: 경우에 따라 해당 통화에서 장치가 업데이트되지 않을 수 있으므로 다음과 같이 해야 할 수 있습니다.

OrientationController.forceLockOrientation(.portrait)
OrientationController.forceLockOrientation(.landscapeRight)

이상입니다

다음을 사용하여 애니메이션을 비활성화하는 방법에 대한 Sid Shah의 답변에 대한 의견에 대한 피드백입니다.

[UIView setAnimationsEnabled:enabled];

코드:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:NO];
    [UIView setAnimationsEnabled:NO];

    // Stackoverflow #26357162 to force orientation
    NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
    [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:NO];
    [UIView setAnimationsEnabled:YES];
}

Subclass iOS 6 Subclass iOS 8에서 테스트해봤어요. 서브클래스UINavigationController 다음합니다.

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationLandscapeRight;
}

- (BOOL)shouldAutorotate {
    return NO;
}

또는 가시적인 보기 컨트롤러에 문의합니다.

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return self.visibleViewController.preferredInterfaceOrientationForPresentation;
}

- (BOOL)shouldAutorotate {
    return self.visibleViewController.shouldAutorotate;
}

거기서 방법을 실행합니다.

navigationViewController를 사용하는 경우 이에 대한 자체 수퍼 클래스를 생성하고 다음을 재정의해야 합니다.

- (BOOL)shouldAutorotate {
  id currentViewController = self.topViewController;

  if ([currentViewController isKindOfClass:[SecondViewController class]])
    return NO;

  return YES;
}

그러면 SecondViewController에서 회전이 비활성화되지만 장치가 세로 방향일 때 SecondViewController를 누르면 SecondViewController가 세로 모드로 나타납니다.

스토리보드를 사용하고 있다고 가정합니다.수동 segue(사용 방법)를 "onClick" 방법으로 만들어야 합니다.

- (IBAction)onPlayButtonClicked:(UIBarButtonItem *)sender {
  NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
  [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
  [self performSegueWithIdentifier:@"PushPlayerViewController" sender:self];
}

이렇게 하면 슈퍼 클래스가 자동 회전 기능을 비활성화하기 전에 가로 방향이 강제로 지정됩니다.

Xcode 8과 같은 작업이 합니다.Swift:

override public var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.portrait
}

override public var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
    return UIInterfaceOrientation.portrait
}

override public var shouldAutorotate: Bool {
    return true
}

많은 솔루션을 시도해 보았지만 효과가 있었던 솔루션은 다음과 같습니다.

편집할 .info.plist과 9ios 8과 9 사이에.

- (BOOL) shouldAutorotate {
    return NO;
}   

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return (UIInterfaceOrientationPortrait | UIInterfaceOrientationPortraitUpsideDown);
}

Apple 설명서에서 가능한 방향:

UI 인터페이스 방향알 수 없는

장치의 방향을 결정할 수 없습니다.

UI 인터페이스 방향 초상화

장치는 세로 모드이며 장치는 수직으로 유지되고 홈 버튼은 하단에 있습니다.

UI 인터페이스 방향 반전 초상화

장치는 세로 모드에 있지만 거꾸로 되어 있으며 장치는 수직으로 유지되고 홈 버튼은 맨 위에 있습니다.

UI 인터페이스 방향 풍경 왼쪽

장치는 가로 모드에 있으며 장치는 수직으로 유지되고 홈 버튼은 왼쪽에 있습니다.

UI 인터페이스 방향 풍경 권한

장치는 가로 모드에 있으며 장치는 수직으로 유지되고 홈 버튼은 오른쪽에 있습니다.

[iOS9+] 위 솔루션 중 하나도 작동하지 않아 여기까지 끌고 온 사람이 있다면, 그리고 만약 당신이 segue로 방향을 바꾸고 싶은 관점을 제시한다면, 당신은 이것을 확인하고 싶을 것입니다.

segue의 프레젠테이션 유형을 확인합니다.제가 쓴 것은 '현재 상황과 동떨어진' 것이었습니다.제가 풀스크린으로 바꿨을 때 작동했습니다.

@GabLeRoux 덕분에 이 솔루션을 찾았습니다.

  • 이 변경 사항은 위의 솔루션과 결합된 경우에만 작동합니다.

Sids와 Koreys 답변의 조합이 저에게 효과가 있었습니다.

내비게이션 컨트롤러 확장:

extension UINavigationController {
    public override func shouldAutorotate() -> Bool {
        return visibleViewController.shouldAutorotate()
    }
}

그런 다음 단일 보기에서 회전 사용 안 함

class ViewController: UIViewController {
    override func shouldAutorotate() -> Bool {
        return false
    }
}

그리고 세그 전에 적절한 방향으로 회전합니다.

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if (segue.identifier == "SomeSegue")
    {
        let value = UIInterfaceOrientation.Portrait.rawValue;
        UIDevice.currentDevice().setValue(value, forKey: "orientation")
    }
}

위의 주요 솔루션:

let value = UIInterfaceOrientation.LandscapeLeft.rawValue
UIDevice.currentDevice().setValue(value, forKey: "orientation")

뷰에서 호출했을 때 제가 작동하지 않았습니다. 제시된 뷰 컨트롤러가 나타났어요.그러나 presenting view controller에서 prepareForSegue를 호출했을 때는 효과가 있었습니다.

(죄송합니다. 해당 솔루션에 대해 언급할 평판 포인트가 부족하여 이렇게 추가해야 했습니다.)

나의 요구사항은

  1. 세로 모드에서 모든 뷰 잠금
  2. 사용하다AVPlayerViewController비디오를 재생합니다

비디오가 재생될 때 가로 방향인 경우 화면을 오른쪽으로 회전시키고 왼쪽으로 회전시킵니다.세로인 경우 보기를 세로 모드로만 잠급니다.

정의니다합먼저를 합니다.supportedInterfaceOrientationsForWindowAppDelegate.swift

var portrait = true
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
    if portrait {
        return .Portrait
    } else {
        return .Landscape
    }
}

둘째, 메인 뷰 컨트롤러에서 다음 기능을 정의합니다.

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    print("\(#function)")
    return .Portrait
}

override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
    return .Portrait
}

override func shouldAutorotate() -> Bool {
    return false
}

그런 다음, 당신은 하위 클래스가 필요합니다.AVPlayerViewController

class MyPlayerViewController: AVPlayerViewController {

    var size: CGSize?

    var supportedOrientationMask: UIInterfaceOrientationMask?
    var preferredOrientation: UIInterfaceOrientation?

    override func viewDidLoad() {
        super.viewDidLoad()

        if let size = size {
            if size.width > size.height {
                self.supportedOrientationMask =[.LandscapeLeft,.LandscapeRight]
                self.preferredOrientation =.LandscapeRight
            } else {
                self.supportedOrientationMask =.Portrait
                self.preferredOrientation =.Portrait
            }
        }
    }

세 을 재니다합기정의능을의가에서 합니다.MyPlayerViewController.swift

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return self.supportedOrientationMask!
}

override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
    return self.preferredOrientation!
}

사용자가 장치를 왼쪽 또는 오른쪽으로 회전할 수 있으므로 자동 회전을 참으로 설정해야 합니다.

override func shouldAutorotate() -> Bool {
    return true
}

막으생성로를 만듭니다.MyPlayerViewController보기 컨트롤러에서 인스턴스를 생성하고 속성 크기 값을 설정합니다.

let playerViewController = MyPlayerViewController()

// Get the thumbnail  
let thumbnail = MyAlbumFileManager.sharedManager().getThumbnailFromMyVideoMedia(......)

let size = thumbnail?.size
playerViewController.size = size

적한사시로 를 시작합니다.videoUrl그런 다음 플레이어를 에 할당합니다.playerViewController해피 코딩!

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [UIViewController attemptRotationToDeviceOrientation];
}

이 일을 어떻게 하면 가장 잘 해낼 수 있을지에 대한 논쟁이 아직 남아 있는 것 같아서 저는 제 (일하는) 접근법을 공유하려고 생각했습니다.다코드추다니에 다음 합니다.UIViewController구현:

- (void) viewWillAppear:(BOOL)animated
{
    [UIViewController attemptRotationToDeviceOrientation];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    return (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}

-(BOOL)shouldAutorotate
{
    return NO;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscapeLeft;
}

에서 허용된 을 ' Left "Landscape Left"에서).info.plist)이 아닌 강제로 만 하면 됩니다 만약 당신이 다른 것을 원한다면 당신이 강요하고 싶은 특정한 방향을 바꾸세요.LandscapeLeft.

내게 중요한 것은attemptRotationToDeviceOrientation을 불러들입니다viewWillAppear장치를 물리적으로 회전하지 않으면 보기가 제대로 회전하지 않습니다.

코레이 힌튼의 대답에 의하면

Swift 2.2:

extension UINavigationController {
    public override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        return visibleViewController!.supportedInterfaceOrientations()
    }
    public override func shouldAutorotate() -> Bool {
        return visibleViewController!.shouldAutorotate()
    }
}


extension UITabBarController {
    public override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        if let selected = selectedViewController {
            return selected.supportedInterfaceOrientations()
        }
        return super.supportedInterfaceOrientations()
    }
    public override func shouldAutorotate() -> Bool {
        if let selected = selectedViewController {
            return selected.shouldAutorotate()
        }
        return super.shouldAutorotate()
    }
}

회전 사용 안 함

override func shouldAutorotate() -> Bool {
    return false
}

특정 방향으로 잠금

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.Portrait
}

여기서 몇 가지 솔루션을 사용해 봤는데, 이해해야 할 중요한 것은 회전 여부를 결정하는 루트 뷰 컨트롤러입니다.

저는 다음과 같은 object-c 프로젝트 github.com/GabLeRoux/RotationLockInTabbedViewChild 를 만들었습니다.TabbedViewController여기서 한 하위 보기는 회전이 허용되고 다른 하위 보기는 세로로 잠깁니다.

▁views▁as▁such▁kind▁it▁work다합니▁for▁other▁should▁same▁the'▁and▁it▁idea▁of야▁but▁root어완과 같은 다른 종류의 루트 뷰에도 효과가 있어야 합니다.NavigationViewController. :)

자식 보기가 부모 방향을 잠급니다.

@sid-sha가 보여준 솔루션에 따르면 당신은 모든 것을 다음에 넣어야 합니다.viewDidAppear:방법, 그렇지 않으면 당신은 얻을 수 없습니다.didRotateFromInterfaceOrientation:해고되었으니 다음과 같은 것입니다.

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
    if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
        interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
        NSNumber *value = [NSNumber numberWithInt:interfaceOrientation];
        [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
    }
}

나의 해결책

AppDelegate:

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
    if let topController = UIViewController.topMostViewController() {
        if topController is XXViewController {
            return [.Portrait, .LandscapeLeft]
        }
    }
    return [.Portrait]
}

XXViewController가로 모드를 지원하려는 View 컨트롤러입니다.

그러면 Sunny Shah의 솔루션이 귀사에서 작동할 것입니다.XXViewController iOS 버전:

let value = UIInterfaceOrientation.LandscapeLeft.rawValue
UIDevice.currentDevice().setValue(value, forKey: "orientation")

최상위 뷰 컨트롤러를 찾기 위한 유틸리티 기능입니다.

extension UIViewController {

    /// Returns the current application's top most view controller.
    public class func topMostViewController() -> UIViewController? {
        let rootViewController = UIApplication.sharedApplication().windows.first?.rootViewController
        return self.topMostViewControllerOfViewController(rootViewController)
    }



    /// Returns the top most view controller from given view controller's stack.
    class func topMostViewControllerOfViewController(viewController: UIViewController?) -> UIViewController? {
        // UITabBarController
        if let tabBarController = viewController as? UITabBarController,
           let selectedViewController = tabBarController.selectedViewController {
            return self.topMostViewControllerOfViewController(selectedViewController)
        }

        // UINavigationController
        if let navigationController = viewController as? UINavigationController,
           let visibleViewController = navigationController.visibleViewController {
            return self.topMostViewControllerOfViewController(visibleViewController)
        }

        // presented view controller
        if let presentedViewController = viewController?.presentedViewController {
            return self.topMostViewControllerOfViewController(presentedViewController)
        }

        // child view controller
        for subview in viewController?.view?.subviews ?? [] {
            if let childViewController = subview.nextResponder() as? UIViewController {
                return self.topMostViewControllerOfViewController(childViewController)
            }
        }

        return viewController
    }

}

이를 통해 IOS 9에서 테스트된 보기 컨트롤러 방향을 잠급니다.

방향을 오른쪽 가로로 잠급니다.

-(UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscapeRight;
}

-(NSUInteger)navigationControllerSupportedInterfaceOrientations:(UINavigationController *)navigationController {
    return UIInterfaceOrientationMaskLandscapeRight;
}

저도 같은 문제를 안고 있고 그것을 위해 너무 많은 시간을 낭비합니다.그래서 이제 해결책이 생겼습니다.내 앱 설정은 단지 초상화 지원뿐입니다.하지만 내 앱에 있는 일부 화면에는 가로만 있으면 됩니다.AppDelegate에서 ShouldRotate라는 변수를 사용하여 수정합니다.AppDelegate의 기능은 다음과 같습니다.

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> Int {
    if isShouldRotate == true {
        return Int(UIInterfaceOrientationMask.Landscape.rawValue)
    }
    return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}

마지막으로, View 컨트롤러 A에 가로 상태가 필요할 때입니다.이렇게 하면 됩니다. ViewControllerA푸시/프레시하기 할당ShouldRotate to true입니다.컨트롤러 할당이 ShouldRotate to false인 pop/dismiss는 viewWillDismap에서 false인 것을 잊지 마십시오.

저는 최상위 VC가 오리엔테이션 오버라이드를 구현해야 했습니다.상위 VC가 구현되지 않는 경우 VC의 다운을 사용해도 스택은 영향을 받지 않습니다.

VC-main
    |
    -> VC 2
        |
        -> VC 3

테스트에서는 VC-Main만 청취됩니다.

여기에 답이 너무 많은데도 아무도 나에게 충분하지 않았던 것 같습니다.로 방향을 잡고 , 강로방향지다정음다시장방돌싶만로었지아고가으향제치을한,▁i싶만▁orient었지돌.[UIViewController attemptRotationToDeviceOrientation];그냥 효과가 없었어요.또한 전체를 복잡하게 만든 것은 일부 답변을 기반으로 자동 회전을 거짓으로 추가해야 하며 모든 시나리오에서 올바르게 회전하기 위해 원하는 효과를 얻을 수 없다는 것입니다.

그래서 제가 한 일은 다음과 같습니다.

init 컨스트럭터에서 컨트롤러를 호출하기 전에 다음을 수행합니다.

_userOrientation = UIDevice.currentDevice.orientation;
[UIDevice.currentDevice setValue:@(UIInterfaceOrientationPortrait) forKey:@"orientation"];
[self addNotificationCenterObserver:@selector(rotated:)
                               name:UIDeviceOrientationDidChangeNotification];

그래서 마지막 장치 방향을 저장하고 방향 변경 이벤트에 등록합니다.방향 변경 이벤트는 간단합니다.

- (void)rotated:(NSNotification*)notification {
    _userOrientation = UIDevice.currentDevice.orientation;
}

그리고 보기에 따라 나는 userOrintion으로서 내가 가진 모든 방향으로 강제로 돌아갑니다.

- (void)onViewDismissing {
    super.onViewDismissing;
    [UIDevice.currentDevice setValue:@(_userOrientation) forKey:@"orientation"];
    [UIViewController attemptRotationToDeviceOrientation];
}

그리고 이것도 거기에 있어야 합니다.

- (BOOL)shouldAutorotate {
    return true;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

또한 내비게이션 컨트롤러는 자동 회전 및 지원 여부를 위임해야 합니다.인터페이스 방향, 하지만 대부분의 사람들이 이미 가지고 있다고 생각합니다.

PS: 죄송합니다. 저는 확장자와 기본 클래스를 사용하지만 이름은 꽤 의미가 있어서 개념을 이해할 수 있습니다. 지금은 너무 예쁘지 않기 때문에 훨씬 더 많은 확장자를 만들 것입니다.

언급URL : https://stackoverflow.com/questions/26357162/how-to-force-view-controller-orientation-in-ios-8

반응형