2014-12-14 18 views
5

Tôi nhận thấy rằng didRotateFromInterfaceOrientation không còn được dùng trong iOS 8; tuy nhiên, tôi có một ứng dụng cần duy trì tương thích với iOS7. Vấn đề tôi gặp phải là khi thiết bị được xoay (iPad trong trường hợp này), phương thức này được gọi hai lần. Điều này xảy ra trên một thiết bị thực tế cũng như với trình mô phỏng. Tôi đã chỉ cần đặt một NSLog trong phương pháp để hiển thị này.didRotateFromInterfaceOrientation firing Hai lần khi xoay

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 
{ 

     NSLog(@"didRotateCalled"); 
} 

Tôi cũng đã kiểm tra willRotateToInterfaceOrientation nhưng thao tác đó chỉ hoạt động chính xác khi được gọi một lần.

Bất kỳ suy nghĩ nào tại sao phương pháp didRotateFromInterfaceOrientation sẽ được kích hoạt hai lần mỗi lần quay?

Để cập nhật nhanh. Tôi đặt một breakpoint trong đó tiết lộ một cái gì đó thú vị. Chế độ xem này là UISplitviewcontroller và có vẻ như phương pháp này được gọi là đầu tiên cho số UISplitviewcontroller và sau đó là UIViewController. Không chắc chắn lý do tại sao ...

Một số thông tin bổ sung. Tôi đang sử dụng Storyboards một cho iPhone và iPad khác. IPhone không sử dụng splitViewController. Các cơ sở mã được chia sẻ như vậy trong prepareForSegue Tôi làm như sau:

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) 
{ 
      UISplitViewController *splitViewController = (UISplitViewController *)self.view.window.rootViewController; 
      splitViewController.delegate = segue.destinationViewController; 
} 
+0

In 'theInterfaceOrientation'. Bạn được những gì? –

+1

liệt kê các lớp ViewController bạn đang sử dụng và nơi bạn đã triển khai 'didRotateFromInterfaceOrientation'.Nó có thể là phương pháp của bạn được gọi là từ các trường hợp khác nhau hoặc từ mã trong lớp và siêu lớp. – Christian

+0

Phân chia chính là UITableViewController và phần chi tiết là UIViewController. Khi một ô được chọn ở bên chủ, chi tiết được "thay thế" bằng nội dung thích hợp. Bạn có thể thấy trong mã của tôi ở trên thiết lập cho điều đó trong preareForSegue. – C6Silver

Trả lời

3

Tôi có câu trả lời của mình. Tôi vừa tải xuống các trình mô phỏng cho iOS 7.1 để sử dụng trong Xcode mới nhất. Tôi thấy rằng phương pháp viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator KHÔNG được gọi khi chạy trong iOS 7.1. Tuy nhiên, tôi cũng thấy rằng vấn đề tôi mô tả với việc luân phiên bắn hai lần không xảy ra với phương pháp willRotateToInterfaceOrientation trong iOS7 nhưng một lần nữa nó làm trong iOS 8. Đây là một lỗi rõ ràng tại Apple.

Có vẻ như tôi sẽ cần phát hiện phiên bản hệ điều hành mà khách hàng đang chạy và nếu iOS 8 trở lên, tôi sẽ không thực thi bất kỳ mã nào theo phương thức willRotateToInterfaceOrientation. Tuy nhiên, tôi có thể thoát khỏi phương thức viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator trong thiết bị iOS 8 vì phương pháp này sẽ chỉ bị iOS bỏ qua 7.

Tôi không biết đây có phải là vấn đề đối với các trình điều khiển splitview hay cho tất cả các phương pháp xem bằng cách sử dụng xoay giữa iOS 7 và 8. Nếu ứng dụng của bạn không ghi đè phương pháp này hơn là bạn không bao giờ biết. Nếu đó là bạn sẽ phải đối mặt với những gì tôi đã làm ở trên. Không tốt.

Đây là mã tôi đang sử dụng để kiểm tra phiên bản:

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 
{ 
    if (NSFoundationVersionNumber == NSFoundationVersionNumber_iOS_7_1) // use this only for iOS7 devices as otherwise this fires twice under iOS8 
    { 
     ... 
    } 
} 

tôi đã để lại -(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator phương pháp như thế này sẽ chỉ đơn giản là bỏ qua bởi iOS 7 thiết bị nhưng sẽ được gọi bằng iOS 8.x và có lẽ trên .

1

Tôi có cùng một vấn đề (mặc dù trong trường hợp của tôi willRotate cũng được thực thi hai lần trên iOS 8). Tôi đã sử dụng giải pháp sau:

BOOL _willRotate; // iVar for the state 

// Methods that should be called from willRotate/didRotate (can be inline) 
- (BOOL)workaroundIOS8RotationMethodsCalledTwice_forWillRotate_shouldExecute 
{ 
    if(_willRotate) { 
     return NO; 
    } 
    _willRotate = YES; 
    return YES; 
} 

- (BOOL)workaroundIOS8RotationMethodsCalledTwice_forDidRotate_shouldExecute 
{ 
    if(_willRotate) { 
     _willRotate = NO; 
     return YES; 
    } 
    return NO; 
} 

// Inside willRotate (return if shouldn't execute): 
if(![self workaroundIOS8RotationMethodsCalledTwice_forWillRotate_shouldExecute]) { 
    return; 
} 

// Inside didRotate (return if shouldn't execute): 
if(![self workaroundIOS8RotationMethodsCalledTwice_forDidRotate_shouldExecute]) { 
    return; 
} 
0

Tôi đã tìm thấy viewWillTransition được gọi hai lần đối với các trường hợp UIViewController khác nhau. Trong lần gọi đầu tiên, bản thân là bản sao hợp lệ. Nhưng trong lần gọi thứ hai, bản thân không hợp lệ. viewDidLoad() không được gọi trên phiên bản không hợp lệ này. Tôi thêm thành viên và giá trị được đặt trên viewDidLoad, sau đó kiểm tra xem bản thân có hợp lệ hay không.

class MyViewControler: UIViewController { 
    var last_width:CGFloat? 

    override func viewDidLoad() { 
    super.viewDidLoad() 
    print(" viewDidLoad self \(self) has address: \(Unmanaged.passUnretained(self).toOpaque())") 
    last_width = self.view.bounds.width 
    } 

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { 
    print(" viewWillTransition self \(self) has address: \(Unmanaged.passUnretained(self).toOpaque())") 
    // Bug? viewWillTransition called twice with diffent self instance, ignore second call 
    if (last_width == nil || last_width == size.width) { 
     return 
    } 
    last_width = size.width 
    } 
} 
Các vấn đề liên quan