Làm thế nào để phát hiện sự thay đổi định hướng?


148

Tôi đang sử dụng Swift và tôi muốn có thể tải UIViewControll khi tôi xoay sang ngang, có ai có thể chỉ cho tôi đi đúng hướng không?

Tôi không thể tìm thấy bất cứ điều gì trực tuyến và một chút bối rối bởi các tài liệu.


1
Tôi cho rằng API đã không thay đổi nên nó sẽ là "didRotateToOrientation" và "willRotateToOrientation", một cái gì đó tương tự, hãy xem tài liệu của Apple
David 'mArm' Ansermot

1
Xin chào @ mArm.ch, cảm ơn bạn đã trả lời nhanh chóng! Vì vậy, làm thế nào tôi sẽ thực hiện điều này? (Đây là ứng dụng đầu tiên của tôi ... Tôi rất mới với iOS) :)
David

Tôi đăng lại như câu trả lời, cho người khác. Bạn có thể chấp nhận nó nếu nó ổn cho bạn?
David 'mArm' Ansermot

Câu trả lời:


194

Đây là cách tôi làm cho nó hoạt động:

Trong AppDelegate.swiftbên trong didFinishLaunchingWithOptions chức năng tôi đặt:

NotificationCenter.default.addObserver(self, selector: #selector(AppDelegate.rotated), name: UIDevice.orientationDidChangeNotification, object: nil)

và sau đó bên trong lớp AppDelegate tôi đặt hàm sau:

func rotated() {
    if UIDeviceOrientationIsLandscape(UIDevice.current.orientation) {
        print("Landscape")
    }

    if UIDeviceOrientationIsPortrait(UIDevice.current.orientation) {
        print("Portrait")
    }
}

Hy vọng điều này sẽ giúp bất cứ ai khác!

Cảm ơn!


5
Tôi đã thử thêm addObserver trong AppDelegate nhưng vẫn nhận được SIGABRT trong CoreFoundation với bộ chọn không được nhận dạng. Tuy nhiên, khi tôi di chuyển addObserver sang viewDidLoad trong lần xem đầu tiên, nó hoạt động hoàn hảo. Chỉ cần thông tin nếu bất cứ ai gặp phải cùng một vấn đề.
FractalDoctor

1
Tôi mới sử dụng mã hóa nhưng không nên selectorcó định dạng chuỗi "rotated:"??
Tắc kè hoa

4
Tôi khá chắc chắn rằng chỉ khi bạn chấp nhận tranh luận ( rotated()không có)
David

26
Hãy cẩn thận vì UIDeviceOrientationcó gì đó khác với UIInterfaceOrientation.. Điều này là do UIDeviceOrientationcũng phát hiện hướng xuống và hướng lên trên có nghĩa là mã của bạn có thể nhảy ngẫu nhiên giữa dọc và ngang nếu thiết bị của bạn nằm trên một bề mặt gần như phẳng nhưng hơi không bằng phẳng (tức là rung lên trên phần nhô ra máy ảnh của 6/6)
liamnichols

4
Phương pháp này KHÔNG LÀM VIỆC nếu điện thoại bị tắt tự động xoay.
chengsam

178
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    if UIDevice.current.orientation.isLandscape {
        print("Landscape")
    }
    if UIDevice.current.orientation.isFlat {
        print("Flat")
    } else {
        print("Portrait")
    }
}

71
Điều này sẽ được gọi là TRƯỚC vòng quay. Nếu bạn cần, ví dụ kích thước khung hình sau khi xoay, giải pháp này sẽ không hoạt động.
Upvote

đã không làm việc trong phần mở rộng. phong cảnh hoặc chân dung vẫn in "portẳng"
TomSawyer

4
Phương pháp này KHÔNG LÀM VIỆC nếu điện thoại bị tắt tự động xoay.
chengsam

5
trên iPad, vì lớp kích thước là giống nhau thường xuyên cho cả phong cảnh và dọc, nên phương thức này không bao giờ được gọi.
Jacky

Điều này cũng sẽ thất bại nếu thiết bị trả về isFlat. developer.apple.com/documentation/uikit/uideviceorientation/
mài

57

Cần phát hiện xoay trong khi sử dụng máy ảnh AVFoundationvà thấy rằng các phương thức didRotate( hiện không dùng nữa ) willTransitionkhông đáng tin cậy cho nhu cầu của tôi. Sử dụng thông báo được đăng bởi David đã hoạt động, nhưng không có sẵn cho Swift 3.x / 4.x.

Swift 4.2 Tên thông báo đã được thay đổi.

Giá trị đóng vẫn giữ nguyên như Swift 4.0:

var didRotate: (Notification) -> Void = { notification in
        switch UIDevice.current.orientation {
        case .landscapeLeft, .landscapeRight:
            print("landscape")
        case .portrait, .portraitUpsideDown:
            print("Portrait")
        default:
            print("other")
        }
    }

Để thiết lập thông báo cho Swift 4.2 :

NotificationCenter.default.addObserver(forName: UIDevice.orientationDidChangeNotification,
                                       object: nil,
                                       queue: .main,
                                       using: didRotate)

Để phá bỏ thông báo cho Swift 4.2 :

NotificationCenter.default.removeObserver(self,
                                          name: UIDevice.orientationDidChangeNotification,
                                          object: nil)

Về tuyên bố phản đối , nhận xét ban đầu của tôi là sai lệch, vì vậy tôi muốn cập nhật điều đó. Như đã lưu ý, việc sử dụng @objcsuy luận đã không được chấp nhận, do đó cần phải sử dụng a #selector. Bằng cách sử dụng một bao đóng thay thế, điều này có thể tránh được và bây giờ bạn có một giải pháp để tránh sự cố do gọi một bộ chọn không hợp lệ.

Mọi thứ bên dưới ở đây đã lỗi thời kể từ XCode 10 & iOS 4.2

Swift 4.0 Với Swift 4.0, Apple đã khuyến khích chúng tôi tránh sử dụng #selector, vì vậy phương pháp này sử dụng một khối hoàn thành ngay bây giờ. Cách tiếp cận này cũng tương thích ngược với Swift 3.x & sẽ là cách tiếp cận được đề xuất trong tương lai.

Đây là cảnh báo trình biên dịch bạn sẽ nhận được trong dự án Swift 4.x nếu bạn sử dụng #selectorchức năng do không dùng nữa@objc suy luận:

nhập mô tả hình ảnh ở đây

Tham gia vào sự tiến hóa nhanh chóng về sự thay đổi này .

Thiết lập cuộc gọi lại:

// If you do not use the notification var in your callback, 
// you can safely replace it with _
    var didRotate: (Notification) -> Void = { notification in
        switch UIDevice.current.orientation {
        case .landscapeLeft, .landscapeRight:
            print("landscape")
        case .portrait, .portraitUpsideDown:
            print("Portrait")
        default:
            print("other")
        }
    }

Cài đặt thông báo:

NotificationCenter.default.addObserver(forName: .UIDeviceOrientationDidChange,
                                       object: nil,
                                       queue: .main,
                                       using: didRotate)

Rơi nước mắt:

NotificationCenter.default.removeObserver(self, name: .UIDeviceOrientationDidChange, object: nil)

4
Bạn có tham khảo nơi Apple nói về việc không khuyến khích sử dụng #selector trong Swift 4 không? Tôi muốn đọc lên lý do tại sao họ nói điều này.
jeffjv

@jeffjv Chắc chắn, tôi không có liên kết trực tiếp đến tài liệu của Apple, nhưng tôi đã bao gồm một ảnh chụp màn hình cảnh báo trình biên dịch mà XCode cung cấp nếu bạn sử dụng phương pháp trước đó.
CodeBender

1
Tôi đã thêm một liên kết đến sự tiến hóa nhanh chóng để thảo luận về sự thay đổi.
CodeBender

1
@CodeBender: Cảnh báo trình biên dịch không có nghĩa là những gì bạn đề xuất. #selector không được khấu hao, chỉ suy luận "@objc". Điều này có nghĩa là khi sử dụng hàm làm #selector, bạn phải đánh dấu rõ ràng để trình biên dịch sẽ tạo mã chính xác bổ sung vì trình biên dịch sẽ không còn cố gắng suy ra từ việc sử dụng của bạn. Do đó, nếu bạn thêm "@obj" vào func xoay () trong giải pháp Swift 3.0, mã sẽ biên dịch mà không có cảnh báo.
Mythlandia

Cảm ơn @Mythlandia, tôi đã cập nhật câu trả lời để giải quyết sự nhầm lẫn về tuyên bố ban đầu của mình.
CodeBender

19

Sử dụng -orientationthuộc tính của UIDevicelà không chính xác (ngay cả khi nó có thể hoạt động trong hầu hết các trường hợp) và có thể dẫn đến một số lỗi, ví dụ, UIDeviceOrientationcũng xem xét hướng của thiết bị nếu nó hướng lên hoặc xuống, không có cặp nào trực tiếp trong UIInterfaceOrientationenum các giá trị.
Hơn nữa, nếu bạn khóa ứng dụng của mình theo một số hướng cụ thể, UIDevice sẽ cung cấp cho bạn hướng thiết bị mà không tính đến điều đó.
Mặt khác, iOS8 đã phản đối interfaceOrientationtài sản trên UIViewControllerlớp.
Có 2 tùy chọn có sẵn để phát hiện hướng giao diện:

  • Sử dụng hướng thanh trạng thái
  • Sử dụng các lớp kích thước, trên iPhone nếu chúng không bị ghi đè, chúng có thể cung cấp cho bạn cách hiểu hướng giao diện hiện tại

Điều còn thiếu là một cách để hiểu hướng thay đổi hướng giao diện, điều này rất quan trọng trong các hình ảnh động.
Trong phiên WWDC 2014 "Xem tiến bộ điều khiển trong iOS8", người nói cũng cung cấp giải pháp cho vấn đề đó, sử dụng phương pháp thay thế -will/DidRotateToInterfaceOrientation.

Ở đây, giải pháp đề xuất được thực hiện một phần, thông tin thêm ở đây :

func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
        let orientation = orientationFromTransform(coordinator.targetTransform())
        let oldOrientation = UIApplication.sharedApplication().statusBarOrientation
        myWillRotateToInterfaceOrientation(orientation,duration: duration)
        coordinator.animateAlongsideTransition({ (ctx) in
            self.myWillAnimateRotationToInterfaceOrientation(orientation,
            duration:duration)
            }) { (ctx) in
                self.myDidAnimateFromInterfaceOrientation(oldOrientation)
        }
    }

11

Tôi biết câu hỏi này là dành cho Swift, nhưng vì đây là một trong những liên kết hàng đầu cho tìm kiếm Google và nếu bạn đang tìm kiếm cùng một mã trong Objective-C:

// add the observer
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(rotated:) name:UIDeviceOrientationDidChangeNotification object:nil];

// remove the observer
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];

// method signature
- (void)rotated:(NSNotification *)notification {
    // do stuff here
}

11

Thật dễ dàng, điều này hoạt động trong iOS8 và 9 / Swift 2 / Xcode7, chỉ cần đặt mã này bên trong viewcontroll.swift của bạn. Nó sẽ in kích thước màn hình với mỗi thay đổi hướng, thay vào đó bạn có thể đặt mã của riêng mình:

override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
        getScreenSize()
    }
    var screenWidth:CGFloat=0
    var screenHeight:CGFloat=0
    func getScreenSize(){
        screenWidth=UIScreen.mainScreen().bounds.width
        screenHeight=UIScreen.mainScreen().bounds.height
        print("SCREEN RESOLUTION: "+screenWidth.description+" x "+screenHeight.description)
    }

5
Hàm này không được dùng nữa, hãy sử dụng "viewWillTransitionToSize: withTransitionCoordinator:" thay vào đó
Masa S-AiYa

Bên cạnh việc bị phản đối, didRotateFromInterfaceOrientation()không làm việc đáng tin cậy. Nó bỏ lỡ một số vòng quay. iewWillTransitionToSize:withTransitionCoordinator:hoạt động tốt
Andrej

@Andrej Rất nhiều thứ hiện không được dùng nữa nhờ Swift 3
Josh


9

Tôi thích kiểm tra thông báo định hướng vì bạn có thể thêm tính năng này vào bất kỳ lớp nào, không cần phải là chế độ xem hoặc bộ điều khiển xem. Ngay cả trong đại biểu ứng dụng của bạn.

Chuyển 5:

    //ask the system to start notifying when interface change
    UIDevice.current.beginGeneratingDeviceOrientationNotifications()
    //add the observer
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(orientationChanged(notification:)),
        name: UIDevice.orientationDidChangeNotification,
        object: nil)

hơn bộ nhớ đệm thông báo

    @objc func orientationChanged(notification : NSNotification) {
        //your code there
    }

8

Trong mục tiêu C

-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator

Trong nhanh chóng

func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator)

Ghi đè phương thức này để phát hiện sự thay đổi định hướng.


8

Swift 3 | UIDeviceOrientationDidChange Thông báo được quan sát quá thường xuyên

Đoạn mã sau in "deviceDidRotate" mỗi khi thiết bị của bạn thay đổi hướng trong không gian 3D - bất kể thay đổi từ hướng dọc sang hướng ngang. Ví dụ: nếu bạn giữ điện thoại của mình theo hướng dọc và nghiêng điện thoại về phía trước và phía sau - deviceDidRotate () được gọi liên tục.

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(
        self, 
        selector:  #selector(deviceDidRotate), 
        name: .UIDeviceOrientationDidChange, 
        object: nil
    )
}

func deviceDidRotate() {
    print("deviceDidRotate")
}

Để khắc phục điều này, bạn có thể giữ hướng thiết bị trước đó và kiểm tra sự thay đổi trong deviceDidRotate ().

var previousDeviceOrientation: UIDeviceOrientation = UIDevice.current.orientation

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(
        self, 
        selector:  #selector(deviceDidRotate), 
        name: .UIDeviceOrientationDidChange, 
        object: nil
    )
}

func deviceDidRotate() {
    if UIDevice.current.orientation == previousDeviceOrientation { return }
    previousDeviceOrientation = UIDevice.current.orientation
    print("deviceDidRotate")
}

Hoặc bạn có thể sử dụng một thông báo khác chỉ được gọi khi thiết bị thay đổi từ ngang sang dọc. Trong trường hợp này, bạn muốn sử dụng UIApplicationDidChangeStatusBarOrientationthông báo.

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(
        self, 
        selector:  #selector(deviceDidRotate), 
        name: .UIApplicationDidChangeStatusBarOrientation, 
        object: nil
    )
}

func deviceDidRotate() {
    print("deviceDidRotate")
}

6

Thực hiện đầy đủ cách thực hiện cách phát hiện thay đổi định hướng trong Swift 3.0.

Tôi đã chọn sử dụng triển khai này vì định hướng điện thoại face upface downquan trọng đối với tôi và tôi muốn chế độ xem chỉ thay đổi khi tôi biết hướng ở vị trí đã chỉ định.

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        //1
        NotificationCenter.default.addObserver(self, selector: #selector(deviceOrientationDidChange), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)

    }

    deinit {
        //3
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
    }

    func deviceOrientationDidChange() {
        //2
        switch UIDevice.current.orientation {
        case .faceDown:
            print("Face down")
        case .faceUp:
            print("Face up")
        case .unknown:
            print("Unknown")
        case .landscapeLeft:
            print("Landscape left")
        case .landscapeRight:
            print("Landscape right")
        case .portrait:
            print("Portrait")
        case .portraitUpsideDown:
            print("Portrait upside down")
        }
    }

}

Những phần quan trọng cần lưu ý là:

  1. Bạn lắng nghe luồng thông báo DeviceOrientationDidChange và buộc nó vào chức năng deviceOrientationDidChange
  2. Sau đó, bạn bật hướng thiết bị, hãy chắc chắn để ý rằng đôi khi có một unknownhướng.
  3. Giống như bất kỳ thông báo nào, trước khi viewContoder bị khử cấp, hãy đảm bảo dừng quan sát luồng thông báo.

Hy vọng ai đó tìm thấy điều này hữu ích.


Cảm ơn bạn, tuyệt vời
Mohammad Razipour

Vì vậy, tôi bối rối, hiện tại tất cả các chế độ xem của tôi điều chỉnh dựa trên dọc sang ngang, nhưng nó không thay đổi nếu thiết bị ngửa mặt? Làm thế nào tôi có thể sử dụng mã trên của bạn để đạt được hiệu quả tương tự khi đối mặt với nó!?
Famic Tech

Bạn có thể cho thêm một chút bối cảnh? Tôi không chắc bạn đang đề cập đến hiệu ứng gì. Mã này hoạt động để đơn giản là phát hiện định hướng. Nếu bạn đang sử dụng nhiều phương pháp để phát hiện hướng, bạn có thể gặp rắc rối.
Rob Norback

6
override func didRotate(from fromInterfaceOrientation: UIInterfaceOrientation) {
    //swift 3
    getScreenSize()
}


func getScreenSize(){
   let screenWidth = UIScreen.main.bounds.width
   let  screenHeight = UIScreen.main.bounds.height
    print("SCREEN RESOLUTION: \(screenWidth.description) x \(screenHeight.description)")
}

Câu trả lời sạch nhất. Đã làm cho tôi.
Dorad

Điều này hiện không được chấp nhận
Aziz Javed

5

Nếu bạn muốn làm một cái gì đó SAU khi xoay xong, bạn có thể sử dụng UIViewControllerTransitionCoordinatortrình xử lý hoàn thành như thế này

public override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)

    // Hook in to the rotation animation completion handler
    coordinator.animate(alongsideTransition: nil) { (_) in
        // Updates to your UI...
        self.tableView.reloadData()
    }
}

5

Vì iOS 8, đây là cách chính xác để làm điều đó.

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)

    coordinator.animate(alongsideTransition: { context in
        // This is called during the animation
    }, completion: { context in
        // This is called after the rotation is finished. Equal to deprecated `didRotate`
    })
}

4

Kiểm tra xem xoay có thay đổi với: viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator)

Với coordinator.animateAlongsideTransition(nil) { (UIViewControllerTransitionCoordinatorContext) bạn có thể kiểm tra xem quá trình chuyển đổi đã kết thúc chưa.

Xem mã dưới đây:

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {

    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)

    coordinator.animateAlongsideTransition(nil) { (UIViewControllerTransitionCoordinatorContext) in
        // if you want to execute code after transition finished
        print("Transition finished")
    }

    if size.height < size.width {
        // Landscape
        print("Landscape")
    } else {
        // Portrait
        print("Portrait")
    }

}

4

Đây là một cách dễ dàng để phát hiện hướng thiết bị: ( Swift 3 )

override func willRotate(to toInterfaceOrientation: UIInterfaceOrientation, duration: TimeInterval) {
            handleViewRotaion(orientation: toInterfaceOrientation)
        }

    //MARK: - Rotation controls
    func handleViewRotaion(orientation:UIInterfaceOrientation) -> Void {
        switch orientation {
        case .portrait :
            print("portrait view")
            break
        case .portraitUpsideDown :
            print("portraitUpsideDown view")
            break
        case .landscapeLeft :
            print("landscapeLeft view")
            break
        case .landscapeRight :
            print("landscapeRight view")
            break
        case .unknown :
            break
        }
    }

2
willRotatebị phản đối bây giờ, sử dụng tốt hơn viewWillTransition.
trước

4

Swift 4:

override func viewWillAppear(_ animated: Bool) {
    NotificationCenter.default.addObserver(self, selector: #selector(deviceRotated), name: UIDevice.orientationDidChangeNotification, object: nil)
}

override func viewWillDisappear(_ animated: Bool) {
    NotificationCenter.default.removeObserver(self, name: UIDevice.orientationDidChangeNotification, object: nil)
}

@objc func deviceRotated(){
    if UIDevice.current.orientation.isLandscape {
        //Code here
    } else {
        //Code here
    }
}

Rất nhiều câu trả lời không giúp ích gì khi cần phát hiện trên nhiều bộ điều khiển xem khác nhau. Đây là một mẹo.


Bạn cũng cần kiểm tra xem thiết bị có bị xoay trong khi bộ điều khiển xem bị biến mất hay không (trong trường hợp bộ điều khiển xem khác được mở trên dòng điện). Trong thực tế, bạn có thể bỏ qua viewWillDisappearvà thêm addObservervào viewDidLoad. iOS hủy đăng ký bộ điều khiển xem tự động.
Alexander Volkov

bạn đã quênUIDevice.current.orientation.isFlat
user924

3

Cách tiếp cận của tôi tương tự như những gì bpedit thể hiện ở trên, nhưng với trọng tâm iOS 9+. Tôi muốn thay đổi phạm vi của FSCalWiki khi chế độ xem xoay.

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)

    coordinator.animateAlongsideTransition({ (context) in
        if size.height < size.width {
            self.calendar.setScope(.Week, animated: true)
            self.calendar.appearance.cellShape = .Rectangle
        }
        else {
            self.calendar.appearance.cellShape = .Circle
            self.calendar.setScope(.Month, animated: true)

        }

        }, completion: nil)
}

Điều này dưới đây đã làm việc, nhưng tôi cảm thấy ngượng ngùng về nó :)

coordinator.animateAlongsideTransition({ (context) in
        if size.height < size.width {
            self.calendar.scope = .Week
            self.calendar.appearance.cellShape = .Rectangle
        }
        }) { (context) in
            if size.height > size.width {
                self.calendar.scope = .Month
                self.calendar.appearance.cellShape = .Circle
            }
    }

2

Tôi sử dụng UIUserInterfaceSizeClassđể phát hiện một hướng thay đổi trong một UIViewControllerlớp giống như vậy:

override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {

    let isiPadLandscapePortrait = newCollection.horizontalSizeClass == .regular && newCollection.verticalSizeClass == .regular
    let isiPhonePlustLandscape = newCollection.horizontalSizeClass == .regular && newCollection.verticalSizeClass == .compact
    let isiPhonePortrait = newCollection.horizontalSizeClass == .compact && newCollection.verticalSizeClass == .regular
    let isiPhoneLandscape = newCollection.horizontalSizeClass == .compact && newCollection.verticalSizeClass == .compact

     if isiPhonePortrait {
         // do something...
     }
}

1

Dành cho Swift 3

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    if UIDevice.current.orientation.isLandscape {
        //Landscape
    }
    else if UIDevice.current.orientation.isFlat {
        //isFlat
    }
    else {
        //Portrait
    }
}

bạn đã quênUIDevice.current.orientation.isFlat
user924

1

Swift 5

Lớp thiết lập để nhận thông báo thay đổi hướng thiết bị:

class MyClass {

    ...

    init (...) {

        ...

        super.init(...)

        // subscribe to device orientation change notifications
        UIDevice.current.beginGeneratingDeviceOrientationNotifications()
        NotificationCenter.default.addObserver(self, selector: #selector(orientationChanged), name: UIDevice.orientationDidChangeNotification, object: nil)

        ...

    }

    ...

}

Thiết lập mã xử lý:

@objc extension MyClass {
    func orientationChanged(_ notification: NSNotification) {
        let device = notification.object as! UIDevice
        let deviceOrientation = device.orientation

        switch deviceOrientation {
        case .landscapeLeft:   //do something for landscape left
        case .landscapeRight:  //do something for landscape right
        case .portrait:        //do something for portrait
        case .portraitUpsideDown: //do something for portrait upside-down 
        case .faceDown:        //do something for face down
        case .faceUp:          //do something for face up
        case .unknown:         //handle unknown
        @unknown default:      //handle unknown default
        }
    }
}

0
- (void)viewDidLoad {
  [super viewDidLoad];
  [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(OrientationDidChange:) name:UIDeviceOrientationDidChangeNotification object:nil];
}

-(void)OrientationDidChange:(NSNotification*)notification {
  UIDeviceOrientation Orientation=[[UIDevice currentDevice]orientation];

  if(Orientation==UIDeviceOrientationLandscapeLeft || Orientation==UIDeviceOrientationLandscapeRight) {
    NSLog(@"Landscape");
  } else if(Orientation==UIDeviceOrientationPortrait) {
    NSLog(@"Potrait Mode");
  }
}

LƯU Ý: Chỉ cần sử dụng mã này để xác định UIViewControll theo hướng nào


Mã của bạn không hoạt động trong dự án. tôi có cần phải làm gì khác không?
Syed Ali Salman

0
override func viewDidLoad() {
    NotificationCenter.default.addObserver(self, selector: #selector(MyController.rotated), name: UIDevice.orientationDidChangeNotification, object: nil)
//...
}

@objc
private func rotated() {
    if UIDevice.current.orientation.isLandscape {

    } else if UIDevice.current.orientation.isPortrait {

    }

    //or you can check orientation separately UIDevice.current.orientation
    //portrait, portraitUpsideDown, landscapeLeft, landscapeRight... 

}

0

Với iOS 13.1.2, định hướng luôn trả về 0 cho đến khi thiết bị được xoay. Tôi cần gọi UIDevice.c hiện.beginGeneratingDeviceOrientationNotutions () để có được vòng quay thực tế trước khi bất kỳ sự kiện xoay vòng nào xảy ra.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.