2013-07-23 26 views
5

Tôi có một ứng dụng iOS có kết nối với máy chủ. Nếu chúng tôi bị ngắt kết nối, tôi muốn có thể loại bỏ các bộ điều khiển chế độ xem hàng đầu để quay lại bộ điều khiển chế độ xem "kết nối với máy chủ". Vấn đề là một sự ngắt kết nối có thể xảy ra bất cứ lúc nào, kể cả trong quá trình chuyển đổi giữa các bộ điều khiển xem.Làm cách nào để loại bỏ trình điều khiển chế độ xem bất kỳ lúc nào (ngay cả trong quá trình chuyển đổi) hoặc khi nào an toàn để loại bỏ trình điều khiển chế độ xem?

Quan điểm điều khiển hệ thống phân cấp là như vậy:

  1. ConnectingToServerViewController
  2. SignInViewController
  3. MainAppViewController
  4. điều khiển xem khác

Khi một ngắt được phát hiện tôi muốn hệ thống phân cấp nhằm thu gọn lại:

  1. ConnectingToServerViewController

Vì vậy, khi một ngắt được phát hiện, phương pháp này được gọi là trên ConnectingToServerViewController bỏ bất cứ điều gì mà nó đã trình bày và quay trở lại để cố gắng kết nối đến máy chủ:

- (void)restartSession 
{ 
    if (self.presentedViewController) { 
     [self dismissViewControllerAnimated:NO completion:nil]; 
    } 
} 

Tuy nhiên, nếu tôi cố gắng loại bỏ trong khi chuyển đổi chế độ xem đang xảy ra, tôi nhận được các lỗi như

*** Assertion failure in -[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:], /SourceCache/UIKit/UIKit-2380.17/UIWindowController.m:211 

attempt to dismiss modal view controller whose view does not currently appear. self = <YYYYYViewController: 0x2089c8a0> modalViewController = <XXXXXViewController: 0x208e6610> 
attempt to dismiss modal view controller whose view does not currently appear. self = <WWWWWWViewController: 0x1fd9e990> modalViewController = <YYYYYViewController: 0x2089c8a0> 

Việc đầu tiên trong số đó sẽ sụp đổ các ứng dụng, thứ hai sẽ không bỏ qua bất cứ điều gì và tiếp tục hiển thị bộ điều khiển xem trình bày hiện tại.

Suy nghĩ:

  1. chậm trễ sẽ không làm việc vì chúng ta không biết khi nào bắt đầu sự chậm trễ
  2. là có một cách để theo dõi khi xem hiệu ứng chuyển tiếp hoàn thành?
  3. tất cả chế độ xem sẽ ghi đè lên bộ điều khiển sẽAppear, didAppear và cảnh báo ứng dụng khi nó an toàn để loại bỏ?
  4. có lẽ thay vì bỏ qua, tôi chỉ nên đặt bộ điều khiển chế độ xem gốc mới?
  5. Tôi đã đảm bảo rằng tất cả chế độ xem bị ghi đè (sẽ | đã) (dis)? Các phương thức xuất hiện gọi phương thức siêu phù hợp.
  6. Bất kỳ giải pháp nào yêu cầu tất cả các bộ điều khiển chế độ xem ghi đè chế độ xem (đã làm) sẽ xuất hiện các phương pháp để theo dõi các âm thanh của nhà nước như nó có thể gây ra vấn đề nếu chúng ta quên đặt lớp cơ sở cho bộ điều khiển chế độ xem mới.
+0

nếu bạn có thể đặt bất kỳ biến cờ nào trong viewController và khi bạn bị ngắt kết nối khỏi máy chủ thì nếu chế độ xem không được tải thì bạn có thể thay đổi cờ từ phương thức restrtSesssion. để khi xem tải, nó sẽ tự động loại bỏ nó. bạn có thể sử dụng một số logic như thế ... hy vọng nó sẽ giúp .. –

+0

Tôi cảm động khi điều này gần cuối. Tôi muốn tránh các giải pháp yêu cầu tất cả các bộ điều khiển xem phải phân lớp một lớp viewcontroller đặc biệt chỉ để theo dõi trạng thái. –

+0

Điều gì về việc loại bỏ nó với một sự chậm trễ hoặc trên hàng đợi chính bằng cách đặt bỏ qua bên trong: NSOperationQueue.mainQueue(). AddOperationWithBlock {// dismiss} // swift code –

Trả lời

0

Dường như bạn đang cố gắng loại bỏ trình điều khiển chế độ xem khi hiện không hiển thị trên màn hình. Để kiểm tra xem nó có trên màn hình bạn có thể sử dụng:

if (self.presentedViewController.view.window) 
{ 
    [self dismissViewControllerAnimated:NO completion:nil]; 
} 
else 
{ 
    self.presentedViewController = nil; 
} 
+0

Nhưng tôi vẫn sẽ cần phải loại bỏ khi trình điều khiển xem được trình bày cuối cùng có thể nhìn thấy? –

+0

Sau đó, nếu nó không có trên màn hình, bạn có thể đặt cờ trong khung nhìn của bạnController để cho biết rằng chế độ xem yêu cầu loại bỏ. Sau đó, trong chế độ xemWillAppear của bạn: bạn có thể kiểm tra cờ và loại bỏ nó nếu cần. Không chắc chắn về nguyên nhân này tôi đã không bao giờ phải làm điều đó, nhưng chỉ là một ý tưởng. – Jamie

+0

Hrm, chúng tôi có thể phải đi theo cách đó nhưng tôi muốn tránh việc mọi bộ điều khiển xem phải kiểm tra xem nó có cần loại bỏ chính nó hay không. Có vẻ như chúng ta có thể quên làm điều này cho một bộ điều khiển xem mới. Thêm vào đó, chúng tôi có rất nhiều bộ điều khiển xem. –

0

Làm điều gì đó như thế này. Hãy thử điều này một lần,

UIViewController *controller = self.presentingViewController; //THIS LINE IS IMP 
[self dismissViewControllerAnimated:YES 
           completion:^{ 
            [controller presentViewController:adminViewController animated:YES completion:nil]; 
            adminViewController.view.superview.frame = CGRectMake(1024/2 - 400, 768/2 - 280, 800 , 560);//it's important to do this after 
            [adminViewController release]; 
           }]; 
+0

Xác nhận có thể xảy ra trước khi khối hoàn thành được gọi. –

+0

khi gọi dismissViewControllerAnimated: completion, xác nhận này xảy ra: *** Lỗi xác nhận trong - [Chuyển đổi UIWindowController: fromViewController: toViewController: target: didEndSelector:], /SourceCache/UIKit/UIKit-2380.17/UIWindowController.m: 211 trước khi khối hoàn thành được gọi. –

+0

Nếu bạn đang trình bày VC tiếp theo, chỉ cần kiểm tra một khi bạn có mã trong ViewDidAppear. –

0

Một cách đã làm việc cho tôi là gán bộ điều khiển chế độ xem mới cho bộ điều khiển chế độ xem gốc.Bằng cách đó, các khung nhìn trong hệ thống phân cấp cũ có thể tạo hiệu ứng động và chuyển đổi sang nội dung trái tim của chúng trong khi chúng ta có các bộ điều khiển mới.

ví dụ

- (void)restartSession 
{ 
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; 
    ConnectingToServerViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"ConnectingToServerViewController"]; 
    vc.modalPresentationStyle = UIModalPresentationFullScreen; 
    [UIApplication sharedApplication].delegate.window.rootViewController = vc; 
} 

Tôi không chắc chắn nếu tôi nhận thức của tất cả các nhược điểm để mặc dù điều này. Có lẽ các bộ điều khiển xem cũ sẽ không bao giờ được giải phóng vì một tham chiếu mạnh mẽ lơ lửng? Chúng tôi không còn sử dụng lại ConnectionToServerViewController nữa, chúng tôi phải tạo lại mỗi lần.

Tôi dựa trên mã tôi thấy trong số this answer for Managing and dismissing Multiple View Controllers in iOS.

0

Tôi sẽ trả lời theo thứ tự.

có cách nào để theo dõi khi quá trình chuyển đổi xem hoàn tất không?

Bạn có thể thử với số UINavigationControllerDelegate (nếu bạn đang sử dụng một trong số đó). Cách tiếp cận khác có thể được sử dụng một hoạt hình tùy chỉnh.

tất cả xem ghi đè bộ điều khiển sẽAppear, didAppear và cảnh báo ứng dụng khi nó an toàn để loại bỏ?

Đó là một tùy chọn. Bạn được tự do làm điều đó nếu bạn muốn. Một lựa chọn khác không phải là để làm điều đó. Tôi nghĩ rằng bộ điều khiển xem bộ chứa như bộ điều khiển điều hướng có cách tiếp cận tốt hơn.

Tôi chỉ cần đặt bộ điều khiển chế độ xem gốc mới?

Tôi khuyên bạn nên làm điều ngược lại. Tôi sẽ thiết lập các SignInViewController/MainAppViewController là dòng chảy gốc, và hiện tại ModulationToServerViewController theo yêu cầu. Theo tôi, đó là một cách tiếp cận lành mạnh hơn.

Hy vọng điều đó sẽ hữu ích.

Các vấn đề liên quan