07/09/2018, 15:34

Orientation trong iOS

Hôm nay mình tiếp tục trình bày với các bạn những tìm hiểu của mình về orientation trong iOS. Trước tới giờ mình không phải làm app với landscape bao giờ và thế là mình chẳng phải cần quan tâm tới orientatino của nó nữa. Một hôm đùng một cái khách hàng yêu cầu support landscape cho một màn hình ...

Hôm nay mình tiếp tục trình bày với các bạn những tìm hiểu của mình về orientation trong iOS.
Trước tới giờ mình không phải làm app với landscape bao giờ và thế là mình chẳng phải cần quan tâm tới orientatino của nó nữa. Một hôm đùng một cái khách hàng yêu cầu support landscape cho một màn hình coi video. WTF?? nó là cái gì thế, thế là mình phải lọ mọ đi tìm hiểu xem làm nó thế nào. Bắt đầu thôi :D

Có 2 cách để app có thể support chuyện này:

  • Cách 1: Setting trên giao diện project
    alt
    lúc này file Plist sẽ có:
    alt

    • Cách 2: Dùng code. Các bạn vào AppDelegate implement function support Orientation Swift
  func  application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> Int {
        return Int(UIInterfaceOrientationMask.All.rawValue)
    }

Objective-C

    - (NSUInteger)application:(UIApplication *)application    supportedInterfaceOrientationsForWindow:(UIWindow *)window {
      return UIInterfaceOrientationMaskAll;
}

Lưu ý: nếu các bạn set ở 2 chỗ thì iOS sẽ ưu tiên hàm ở AppDelegate hơn.

Nếu các bạn ko muốn màn hình xoay các bạn có thể hiện thực 2 hàm:

  • Hàm 1:

Swift

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

Objective-C

- (BOOL)shouldAutorotate {
    return NO;
}

Sử dụng hàm này để xác định có cho phép view xoay hay không. Mặc định nó là YES(true)
*Hàm 2:
Swift

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

Objective-C

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskAll;
}

Hàm thứ 2 này sẽ force Viewcontroller đó support những kiểu màn hình nào portraint hay landscape.
Lưu ý:

  • 2 Hàm này các bạn muốn hiện thực hay không thì tuỳ. Nhưng có 1 lưu ý chỗ này: Khi các bạn present một view lên, nếu các bạn ko hiện thực hàm số 2 thì orientation của nó phụ thuộc orientation của thằng present ra nhé.

  • Khi ở landscpae thì ở iOS 8 mặc định statusbar sẽ ẩn đi, do đó nếu ko muốn vậy các bạn các bạn phải handle nó. Về statusBar các bạn có thể tham khảo Link

Để Hanlde việc View xoay các bạn cần hiện thực hàm này:
Swift

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

    coordinator.animateAlongsideTransition({ (UIViewControllerTransitionCoordinatorContext) -> Void in

        let orient = UIApplication.sharedApplication().statusBarOrientation

        switch orient {
        case .Portrait:
            println("Portrait")
            // Do something
        default:
            println("Anything But Portrait")
            // Do something else
        }

        }, completion: { (UIViewControllerTransitionCoordinatorContext) -> Void in
            println("rotation completed")
    })

    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
}

Objective-C

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context)
     {
         UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
         switch (orientation) {
             case UIInterfaceOrientationPortrait:
                 //do anything
                 break;
            case UIInterfaceOrientationLandscapeLeft:
                 //do anything
                 break;

             default:
                 break;
         }
     } completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
     {

     }];

    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
}

Quay trở lại vấn đề mình gặp phải ban đầu, app của mình trước giờ chỉ support portrait mà giờ set project support landscape nữa, mà vấn đề như trên mặc định shouldAutoRotate return YES. Chẳng lẽ giờ đi sửa toàn bộ ViewController thêm hàm đó vô và return NO. WTF??? Change nhiều quá. :D
May quá, mình có cái BaseViewController tất cả các viewcontroller khác đều thừa kế từ nó và giờ mình chỉ việc hiện thực 2 hàm phía trên trả về portraint hết và thằng support landscape mình sẽ cho nó xoay :D
Chi tiết các bạn có thể tham kháo: Github

0