2012-07-10 44 views
11

Vấn đề này khiến tôi phát điên. Tôi đang cố gắng thay đổi viewController khi người dùng thay đổi "tab" đã chọn của điều khiển được phân đoạn. Tôi đã dành một vài giờ nghiên cứu và không thể tìm thấy câu trả lời hoạt động hoặc được thực hiện thông qua bảng phân cảnh.Thay đổi bộ điều khiển xem khi Điều khiển phân đoạn thay đổi

Điều này thực sự làm phiền tôi vì việc đặt ứng dụng tab rất dễ dàng, nhưng việc cố gắng sử dụng điều khiển được phân đoạn như ứng dụng tab không hoạt động. Tôi đã biết cách phát hiện chỉ mục nào được chọn trong điều khiển phân đoạn. Làm thế nào tôi có thể đạt được điều này?

Cảm ơn bạn rất nhiều.

+0

Bạn đang cố gắng hoán đổi bộ điều khiển _view_ hoặc _view_? Chúng là hai thứ khác nhau. Nếu sau này, tôi khuyên bạn nên cuộn mọi thứ vào một bộ điều khiển chế độ xem và hiển thị hoặc ẩn các bản xem phụ khi cần. –

+0

Tôi thực sự mới trong iOS, điều đơn giản nhất đến với tâm trí của tôi là thay đổi viewController giống như một ứng dụng theo thẻ. Bạn có đề xuất đưa ra các chế độ xem khác nhau và quản lý chúng bằng cùng một bộ điều khiển chế độ xem không? Nếu có, tôi có thể làm như thế nào? Cảm ơn bạn rất nhiều –

Trả lời

4

Tôi muốn nói rằng đó là nhiều sim pler để thay đổi subviews trong một UIViewController, bạn có thể thiết lập subviews của bạn trong storyboards của bạn và hook chúng với IBOulets trong controller của bạn, bạn có thể thiết lập thuộc tính hidden của view của bạn thành YES hoặc NO tùy thuộc vào điều khiển đã được click.

Bây giờ, nếu bạn sử dụng cách tiếp cận của @Robotic Cat, đây là giải pháp tốt, bạn có thể có nhiều mô đun hơn trong cách ứng dụng hoạt động, xem xét bạn phải đặt tất cả logic của mình vào một bộ điều khiển. .

+0

Tôi thích bạn gợi ý chỉ cần thử nó trên xcode và có vẻ tốt và dễ thực hiện. Mối quan tâm duy nhất của tôi là nó không hiệu quả để có quan điểm ẩn trong nền? –

+1

Tôi chưa đọc bất cứ điều gì trong tài liệu dành cho nhà phát triển mà chống lại điều này, mặc dù bạn phải xem xét rằng nếu bạn thêm nhiều yếu tố trực quan, nó sẽ chiếm bộ nhớ, vì vậy hãy làm điều đó một cách khôn ngoan. Để tránh điều này, bạn có thể tạo ra mọi thứ bạn cần trên bay, mặc dù tôi tin rằng chi phí của việc có tất cả các yếu tố đã được thiết lập là tối thiểu. Ví dụ, tôi chỉ có 4 lần xem phụ với mỗi trường có 1 hoặc 2 trường văn bản. – 8vius

+1

Trong một trong các ứng dụng iPad của tôi, tôi có một bộ điều khiển xem có 7 chế độ xem con có thể được hiển thị hoặc ẩn, mỗi bộ điều khiển riêng của nó. Trong tất cả, có khoảng 60 lượt xem và subvies (nhãn, nút, vv). Tôi không nhận thấy bất kỳ sự chậm chạp hay do dự nào, và Profier không tiết lộ bất kỳ đột biến lớn nào trong bộ nhớ hoặc CPU. Rõ ràng, bạn nên kiểm tra kỹ lưỡng giải pháp của riêng bạn, nhưng tôi nghi ngờ bạn sẽ có một vấn đề. –

0

UISegmentedControl hơi khác một chút ở chỗ nó không có giao thức đại biểu, bạn phải sử dụng kiểu "thêm mục tiêu". Trong trường hợp của bạn những gì bạn muốn làm là thêm một mục tiêu để được thông báo khi UISegmentedControl thay đổi (có khả năng là bộ điều khiển xem cha mẹ), và sau đó mục tiêu đó có thể đối phó với việc chuyển đổi tab.

Ví dụ:

[self.mainSegmentedControl addTarget:self action:@selector(changedSegmentedControl:) forControlEvents:UIControlEventValueChanged]; 

Trong ví dụ này, các mã được gọi từ một số quan điểm/điều khiển có quyền truy cập vào biến cho điều khiển phân đoạn. Chúng tôi thêm ourself để có được changesSegmentedControl: phương thức được gọi.

Sau đó, bạn sẽ có một phương pháp khác như vậy:

- (void)changedSegmentedControl:(id)sender 
{ 
    UISegmentedControl *ctl = sender; 
    NSLog(@"Changed value of segmented control to %d", ctl.selectedSegmentIndex); 
    // Code to change View Controller goes here 
} 

Lưu ý: đây là mã chưa được kiểm tra bằng văn bản từ bộ nhớ - hãy tham khảo các tài liệu cho phù hợp.

42

Chú ý: trả lời được cập nhật với mã ngăn chặn quan điểm điều khiển dành cho iOS 5 + bao gồm cả phần @ interface

Trong một ứng dụng của tôi, tôi có một bộ điều khiển vùng đang xem với một Control Segment trong Navigation Bar và nhấp vào công tắc "tab" xem bộ điều khiển. Ý tưởng cơ bản là có một loạt các bộ điều khiển xem và chuyển đổi giữa chúng bằng cách sử dụng chỉ mục phân đoạn (và indexDidChangeForSegmentedControl IBAction)

Mã ví dụ (iOS 5 hoặc mới hơn) từ ứng dụng của tôi (điều này là dành cho 2 bộ điều khiển xem) . mở rộng đến nhiều bộ điều khiển xem); mã là hơi dài hơn dành cho iOS 4 nhưng sẽ giữ cho đồ thị đối tượng còn nguyên vẹn nữa, nó sử dụng ARC:

@interface MyViewController() 
// Segmented control to switch view controllers 
@property (weak, nonatomic) IBOutlet UISegmentedControl *switchViewControllers; 

// Array of view controllers to switch between 
@property (nonatomic, copy) NSArray *allViewControllers; 

// Currently selected view controller 
@property (nonatomic, strong) UIViewController *currentViewController; 
@end 

@implementation UpdateScoreViewController 
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib. 
- (void)viewDidLoad { 
    [super viewDidLoad]; 

    // Create the score view controller 
    ViewControllerA *vcA = [self.storyboard instantiateViewControllerWithIdentifier:@"ViewControllerA"]; 

    // Create the penalty view controller 
    ViewControllerB *vcB = [self.storyboard instantiateViewControllerWithIdentifier:@"ViewControllerB"]; 

    // Add A and B view controllers to the array 
    self.allViewControllers = [[NSArray alloc] initWithObjects:vcA, vcB, nil]; 

    // Ensure a view controller is loaded 
    self.switchViewControllers.selectedSegmentIndex = 0; 
    [self cycleFromViewController:self.currentViewController toViewController:[self.allViewControllers objectAtIndex:self.switchViewControllers.selectedSegmentIndex]]; 
} 

#pragma mark - View controller switching and saving 

- (void)cycleFromViewController:(UIViewController*)oldVC toViewController:(UIViewController*)newVC { 

    // Do nothing if we are attempting to swap to the same view controller 
    if (newVC == oldVC) return; 

    // Check the newVC is non-nil otherwise expect a crash: NSInvalidArgumentException 
    if (newVC) { 

     // Set the new view controller frame (in this case to be the size of the available screen bounds) 
     // Calulate any other frame animations here (e.g. for the oldVC) 
     newVC.view.frame = CGRectMake(CGRectGetMinX(self.view.bounds), CGRectGetMinY(self.view.bounds), CGRectGetWidth(self.view.bounds), CGRectGetHeight(self.view.bounds)); 

     // Check the oldVC is non-nil otherwise expect a crash: NSInvalidArgumentException 
     if (oldVC) { 

      // Start both the view controller transitions 
      [oldVC willMoveToParentViewController:nil]; 
      [self addChildViewController:newVC]; 

      // Swap the view controllers 
      // No frame animations in this code but these would go in the animations block 
      [self transitionFromViewController:oldVC 
           toViewController:newVC 
             duration:0.25 
             options:UIViewAnimationOptionLayoutSubviews 
            animations:^{} 
            completion:^(BOOL finished) { 
             // Finish both the view controller transitions 
             [oldVC removeFromParentViewController]; 
             [newVC didMoveToParentViewController:self]; 
             // Store a reference to the current controller 
             self.currentViewController = newVC; 
            }]; 

     } else { 

      // Otherwise we are adding a view controller for the first time 
      // Start the view controller transition 
      [self addChildViewController:newVC]; 

      // Add the new view controller view to the ciew hierarchy 
      [self.view addSubview:newVC.view]; 

      // End the view controller transition 
      [newVC didMoveToParentViewController:self]; 

      // Store a reference to the current controller 
      self.currentViewController = newVC; 
     } 
    } 
} 

- (IBAction)indexDidChangeForSegmentedControl:(UISegmentedControl *)sender { 

    NSUInteger index = sender.selectedSegmentIndex; 

    if (UISegmentedControlNoSegment != index) { 
     UIViewController *incomingViewController = [self.allViewControllers objectAtIndex:index]; 
     [self cycleFromViewController:self.currentViewController toViewController:incomingViewController]; 
    } 

} 
@end 

gốc ví dụ (iOS 4 hoặc trước đó):

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib. 
- (void)viewDidLoad { 
    [super viewDidLoad]; 

    // Create the score view controller 
    AddHandScoreViewController *score = [self.storyboard instantiateViewControllerWithIdentifier:@"AddHandScore"]; 

    // Create the penalty view controller 
    AddHandPenaltyViewController *penalty = [self.storyboard instantiateViewControllerWithIdentifier:@"AddHandPenalty"]; 

    // Add Score and Penalty view controllers to the array 
    self.allViewControllers = [[NSArray alloc] initWithObjects:score, penalty, nil]; 

    // Ensure the Score controller is loaded 
    self.switchViewControllers.selectedSegmentIndex = 0; 
    [self switchToController:[self.allViewControllers objectAtIndex:self.switchViewControllers.selectedSegmentIndex]]; 
} 

#pragma mark - View controller switching and saving 

- (void)switchToController:(UIViewController *)newVC 
{ 
    if (newVC) { 
     // Do nothing if we are in the same controller 
     if (newVC == self.currentViewController) return; 

     // Remove the current controller if we are loaded and shown 
     if([self.currentViewController isViewLoaded]) [self.currentViewController.view removeFromSuperview]; 

     // Resize the new view controller 
     newVC.view.frame = CGRectMake(CGRectGetMinX(self.view.bounds), CGRectGetMinY(self.view.bounds), CGRectGetWidth(self.view.bounds), CGRectGetHeight(self.view.bounds)); 

     // Add the new controller 
     [self.view addSubview:newVC.view]; 

     // Store a reference to the current controller 
     self.currentViewController = newVC; 
    } 
} 

- (IBAction)indexDidChangeForSegmentedControl:(UISegmentedControl *)sender { 

    NSUInteger index = sender.selectedSegmentIndex; 

    if (UISegmentedControlNoSegment != index) { 
     UIViewController *incomingViewController = [self.allViewControllers objectAtIndex:index]; 
     [self switchToController:incomingViewController]; 
    } 

} 
+0

Giải pháp thực sự tốt đẹp. Cảm ơn bạn đã chia sẻ điều này. – Mike

+0

@Robotic Cat: Tôi hơi bối rối vì sao bạn đặt khung của bộ điều khiển xem con là giống như bộ điều khiển chế độ xem gốc. Bộ điều khiển xem này có chứa UISegmentedControl không? Nếu vậy, bộ điều khiển xem trẻ em có bị che khuất không? – Marplesoft

+0

@Marplesoft: Thông thường, 'UISegmentedControl' nằm trong Thanh Điều hướng. Rõ ràng, nếu 'UISegmentedControl' của bạn nằm trong bộ điều khiển khung nhìn, bạn nên đặt các ràng buộc hoặc khung hình tự động của bạn thành các giá trị chính xác cho ứng dụng của bạn. –

0

Hãy xem vỏ này: https://github.com/xmartlabs/XLMailBoxContainer. Nó làm cho hoạt hình giao diện người dùng giữa các bộ điều khiển chế độ xem. Các bộ điều khiển xem có thể mở rộng UITableViewController hoặc bất kỳ bộ điều khiển xem khác.

Tôi hy vọng điều này sẽ giúp bạn!

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