2011-12-22 10 views
8

Tôi hiện đang có một ứng dụng iPad với một UIToolbar chứa hai UIBarButtonItems, mỗi trong số đó được kết nối với một phân đoạn popover.UIBarButtonItem + popover segue tạo ra nhiều popovers

Khi người dùng chạm vào một trong các UIBarButtonItems, cửa sổ bật lên được tạo thay vì bật. Điều này tạo ra nhiều cửa sổ bật lên chồng lên nhau. Tôi đã có thể đóng cửa sổ bật lên đã tạo trước đó bằng cách sử dụng mã sau đây

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 
    // First close the preferences popover if it's open per Apple guidelines 
    if ([self.popoverA.popoverController isPopoverVisible]) { 
     [self.popoverA.popoverController dismissPopoverAnimated:YES]; 
    } 

    if ([self.popoverB.popoverController isPopoverVisible]) { 
     [self.popoverB.popoverController dismissPopoverAnimated:YES]; 
    } 
    ... code to manage segues ... 
} 

Tôi cũng có UIButtons tạo phân đoạn popover hoạt động bình thường. Do hành vi này của các popovers liên kết với UIBarButtonItems, ứng dụng của tôi đang bị từ chối. Có ai có bất cứ đề nghị hoặc bất kỳ mẫu mã của một UIToolbar với nhiều UIBarButtonItems hoạt động chính xác? Các cửa sổ bật lên sẽ loại bỏ khi người dùng chạm vào bên ngoài cửa sổ,

+0

Chỉ cần làm rõ vấn đề của tôi. Hành vi mong đợi là mỗi lần nút (UIBarButtonItem) được chạm vào, cửa sổ bật lên sẽ được bật hoặc đóng hơn là luôn mở. Tuy nhiên, segue dường như luôn tạo một cửa sổ bật lên khác thay vì loại bỏ một cửa sổ hiển thị hiện có. Khi được liên kết với một UIButton, các popovers được chuyển đổi một cách thích hợp. –

Trả lời

8

Khi bạn nhận được thông báo trong -prepareForSegue:sender:, đã quá muộn để hủy một khoảng cách.

Để làm điều này một cách hiệu quả, bạn nên tạo phân đoạn cho cửa sổ của bạn từ chính trình điều khiển chế độ xem thay vì các nút thanh để chúng vẫn có thể được thực hiện theo chương trình. Bây giờ dây UIBarButtonItem s lên đến một số phương pháp có điều kiện hiện tại hoặc loại bỏ cửa sổ bật lên.

- (IBAction)showPopoverA 
{ 
    if (self.popoverA.popoverController.popoverVisible) 
     [self.popoverA.popoverController dismissPopoverAnimated:YES]; 

    [self performSegueWithIdentifier:@"ShowPopoverA"]; 
} 
+0

Cảm ơn lời khuyên, tôi sẽ cố gắng! –

+1

Sau khi thử đề xuất đó, tôi nhận được lỗi sau: ** Chấm dứt ứng dụng do không ngoại lệ 'NSInternalInconsistencyException', lý do: 'UIStoryboardPopoverSegue phải được trình bày từ mục nút thanh hoặc chế độ xem. ** –

+0

'- (IBAction) showPopoverA: (id) người gửi { nếu ([self.popoverA.popoverController isPopoverVisible]) {[self.popoverA.popoverController dismissPopoverAnimated: YES]; } [self performSegueWithIdentifier: @ "showPopoverASegue" người gửi: người gửi]; } ' –

16

Đây là cách thích hợp để làm những gì bạn cần làm:

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender { 
    if ([identifier isEqualToString:@"SurveyListPopover"]) { 
     if (self.surveyListPopover == nil) { 
      return YES; 
     } 
     return NO; 
    } 
    return YES; 
} 

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 
    if ([segue.identifier isEqualToString:@"SurveyListPopover"]) { 
     // Assign popover instance so we can dismiss it later 
     self.surveyListPopover = [(UIStoryboardPopoverSegue *)segue popoverController]; 
    } 
} 

Điều này đảm bảo rằng segue sẽ bị hủy bỏ nếu một thể hiện của các popover đã được hiển thị. Bạn chỉ cần đảm bảo đối tượng bật lên của bạn có một số nhận dạng trong bảng phân cảnh.

+0

Nếu bạn đang nhắm mục tiêu 6.0+, đây là cách tiếp cận tốt nhất. –

+0

là nó chỉ cho tôi hoặc trong ios 5 shouldPerformSegueWithIdentifier là không nhận được gọi là ở tất cả? –

+0

https://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/shouldPerformSegueWithIdentifier:sender: Dường như nó đã được giới thiệu trong iOS 6.0 và lên – Brenden

1

Sự kết hợp của cả hai đã làm cho nó cho tôi

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    if ([segue.identifier isEqualToString:@"showPopover"]) { 
     self.tableOfContentsPopoverController = [(UIStoryboardPopoverSegue*)segue popoverController]; 
    } 
} 

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender { 
    if ([identifier isEqualToString:@"showPopover"]) { 
     if (!self.tableOfContentsPopoverController.popoverVisible) { 
      return YES; 
     } 
     return NO; 
    } 
    return YES; 
}