2011-11-29 21 views
16

Tôi sử dụng phương pháp performSegueWithIdentifier:sender: để mở ViewController mới từ tệp bảng phân cảnh theo chương trình. Công việc này như một cái duyên vậy.Có thể sử dụng một ViewController hiện có với PerformSegueWithIdentifier không?

Nhưng mỗi khi phương pháp này được gọi, một ViewController mới sẽ được tạo. Có thể sử dụng ViewController hiện tại, nếu nó tồn tại không? Tôi không tìm thấy bất cứ điều gì về vấn đề này (apple-doc, Stack Overflow, ...).

Vấn đề là: Trên tạo ViewController người dùng thiết lập một số hình thức-Elements và nếu ViewController sẽ được gọi là một lần nữa, hình thức-yếu tố có các thiết lập ban đầu :(

Bất kỳ trợ giúp sẽ được đánh giá

.

Edit: tôi đánh giá cao những phản ứng nhiều trong khi đó, tôi không quen thuộc với dự án và không thể kiểm tra câu trả lời của bạn

+1

Theo mẫu MVC, bạn nên lưu giá trị người dùng trong bất kỳ đối tượng được chia sẻ nào hoặc trong NSUserDefaults. Vì vậy, câu hỏi của bạn không hoàn toàn đúng –

+0

Bạn đã đúng, tính năng này hiện tại không được triển khai và sẽ đến trong tương lai! Điều này sẽ giải quyết vấn đề của tôi, nhưng câu hỏi vẫn là như nhau, nếu một ViewController có thể được tái sử dụng với phương pháp này? Tôi không thể tưởng tượng rằng điều này là không thể. – matzino

Trả lời

0

Tạo một tài sản cho bộ điều khiển

...
@property (nonatomic, weak) MyController controller; 

Và sử dụng một số loại khởi tạo lười biếng trong performSegueWithIdentifier:sender

if (self.controller == nil) 
{ 
self.controller = [MyController alloc] init] 
... 
} 

Trong trường hợp này, nếu bộ điều khiển đã được tạo ra, nó sẽ được tái sử dụng.

+0

Cảm ơn, tôi đã kiểm tra điều này nhưng nó không hoạt động cho tôi. Tôi không biết làm thế nào khởi tạo lười biếng hoạt động trong bối cảnh từ phương pháp thực hiện? – matzino

0

Tôi đã gặp sự cố này hôm nay và những gì tôi đã làm là tạo bộ điều khiển chế độ xem theo cách thủ công và lưu trữ tham chiếu của nó. Sau đó, mỗi lần tôi cần bộ điều khiển, hãy kiểm tra trước nếu có. Một cái gì đó như thế này:

MyController *controller = [storedControllers valueForKey:@"controllerName"]; 

if (!controller) 
{ 
    controller = [[UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:NULL] instantiateViewControllerWithIdentifier:@"MyControllerIdentifierOnTheStoryboard"]; 

    [storedControllers setValue:controller forKey:@"controllerName"]; 
} 

[self.navigationController pushViewController:controller animated:YES]; 

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

+0

Cảm ơn lời khuyên của bạn, có vẻ như giải pháp này sẽ hoạt động. Tôi đã giải quyết được vấn đề của mình bằng cách lưu đầu vào của người dùng như d.lebedev được đề cập. Bạn đẩy viewcontroller với sự trợ giúp của navigationController, thay vào đó bạn có thể sử dụng phương thức performSegueWithIdentifier không? – matzino

7

Để tái sử dụng trường hợp UIViewController hiện tại với khoảng cách tạo ra khoảng cách từ đầu và cung cấp đích (hiện tại) của riêng bạn (UIViewController). Đừng quên gọi prepareForSegue: nếu cần.

Ví dụ:

UIStoryboardSegue* aSegue = [[UIStoryboardSegue alloc] initWithIdentifier:@"yourSegueIdentifier" source:self destination:self.existingViewController] 
[self prepareForSegue:aSegue sender:self]; 
[aSegue perform]; 
+0

Các thuộc tính khác của segue đến từ đâu với cách tiếp cận này, chẳng hạn như kiểu trình bày? – Benjohn

2

Tiếp theo mã làm cho bộ điều khiển xem singleton. Thêm chúng vào bộ thực hiện bộ điều khiển xem đích của bạn, sau đó segue sẽ sử dụng lại cùng vc.

static id s_singleton = nil; 
+ (id) alloc { 
    if(s_singleton != nil) 
     return s_singleton; 
    return [super alloc]; 
} 
- (id) initWithCoder:(NSCoder *)aDecoder { 
    if(s_singleton != nil) 
     return s_singleton; 
    self = [super initWithCoder:aDecoder]; 
    if(self) { 
     s_singleton = self; 
    } 
    return self; 
} 
+0

Bạn xử lý 'didReceiveMemoryWarning' bằng cách tiếp cận này như thế nào? – expert

+0

s_singleton = nil; ? –

+0

Bạn đã lưu tôi! Cảm ơn :) – KiNG

-1

Bạn cần phải biến Viewcontroller thành một lớp đơn.

12

Sử dụng shouldPerforSegueWithIdentifier để cho phép segue thực hiện hoặc hủy segue và thêm ViewController theo cách thủ công. Giữ lại con trỏ trong số prepareForSegue.

... tiêu đề

@property (strong, nonatomic) MyViewController *myVC; 

...thực hiện

-(BOOL) shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender{ 
    if([identifier isEqualToString:@"MySegueIdentifier"]){ 
     if(self.myVC){ 
      // push on the viewController 
      [self.navigationController pushViewController:self.myVC animated:YES]; 
      // cancel segue 
      return NO; 
     } 
    } 
    // allow the segue to perform 
    return YES; 
} 


-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    if([segue.identifier isEqualToString:@"MySegueIdentifier"]){ 
     // this will only be called the first time the segue fires for this identifier 
     // retian a pointer to the view controller 
     self.myVC = segue.destinationViewController; 
    } 
} 
0

Nếu đó là một ứng dụng phổ biến tiêu chuẩn master-chi tiết (trong đó sử dụng một UISplitViewController) sau đó nó có thể này có thể đạt được bằng cách thiết lập viewControllers tài sản trên bộ điều khiển chuyển hướng mới với bộ điều khiển chi tiết trước đó, như dưới đây. Nếu không nó có thể được thực hiện nhưng một bước bổ sung là cần thiết để đặt bộ điều khiển bạn muốn sử dụng lại bên trong một bộ điều khiển điều hướng trong bảng câu chuyện.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 
    if ([[segue identifier] isEqualToString:@"showDetail"]) { 
     NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; 
     NSManagedObject *object = [[self fetchedResultsController] objectAtIndexPath:indexPath]; 
     UINavigationController* navigationController = (UINavigationController*)[segue destinationViewController]; 

     // retrieve previous detail controller. 
     DetailViewController* controller = self.detailViewController; 

     if(controller){ 
      // if we have an existing detail controller then set it on the navigation controller. 
      navigationController.viewControllers = @[controller]; 
     } 
     else{ 
      // this must be the first time, so store the detail view controller for next time, and we don't need to modify the navigation controller in this case. 
      controller = (DetailViewController *)[navigationController topViewController]; 
      self.detailViewController = controller; 
     } 

     // update the detail controller as normal. 
     [controller setDetailItem:object]; 
     controller.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem; 
     controller.navigationItem.leftItemsSupplementBackButton = YES; 
    } 
} 

Có phí mà bộ điều khiển chi tiết không bị lưu trữ khỏi bảng phân cảnh mọi lúc, và tiếc là chế độ xem của nó cũng được tải. Tuy nhiên nó ngay lập tức bị dealloced, và trong mẫu Apples, hành vi mặc định là một bộ điều khiển chi tiết được tải và vứt đi vì vậy nếu chúng không bị làm phiền về nó thì có lẽ nó an toàn để thực hiện theo cách đó.

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