分段控制更改时更改视图控制器

这个问题让我疯狂。 我试图改变viewController当用户更改分段控制选定的“选项卡”。 我花了几个小时的研究,一直没有find一个可行的答案或通过故事板完成。

这真的很麻烦,因为设置一个标签应用程序是如此简单,但试图使用分页控制像标签应用程序只是不工作。 我已经知道如何检测在分段控制中select哪个索引。 我怎样才能做到这一点?

非常感谢你。

我想说在UIViewController更改子视图要简单得多,你可以在你的故事板中设置你的子视图,并在你的控制器IBOulets它们与IBOulets连接起来,你可以将视图的hidden属性设置为YES或NO,这取决于控制被点击。

现在,如果您使用@Robotic Cat的方法,这也是一个很好的解决scheme,考虑到您必须使用我提供的解决scheme将所有的逻辑放在一个控制器中,您可以在应用程序的工作方式上多一点模块化。

注意:更新的视图控制器遏制代码的iOS 5 +包括@接口部分的答案

在我的一个应用程序中,我有一个视图控制器与导航栏中的段控件,然后单击“选项卡”切换视图控制器。 基本的想法是有一个视图控制器的数组,并使用段索引(和indexDidChangeForSegmentedControl IBAction)在它们之间切换。

示例代码(iOS 5或更高版本)从我的应用程序(这是2视图控制器,但它平凡扩展到多个视图控制器); 代码比iOS 4稍长一些,但会保持对象图的完整。 另外,它使用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 (eg 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 

原始示例(iOS 4或之前):

 // 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]; } } 

UISegmentedControl有点不同,它没有委托协议,你必须使用“添加目标”样式。 在你的情况下,你想要做的就是添加一个目标,当UISegmentedControl改变(这可能是父视图控制器),然后该目标可以处理标签切换通知。

例如:

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

在这个例子中,代码是从一些可以访问分段控制的variables的视图/控制器中调用的。 我们添加自己得到changedSegmentedControl:方法被调用。

那么你会有另一种方法如下所示:

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

注意:这是从内存写入的未经testing的代码 – 请参阅相应的文档。

看看这个窗口: https : //github.com/xmartlabs/XLMailBoxContainer 。 它使视图控制器之间的UIanimation。 这些视图控制器可以扩展UITableViewController或任何其他视图控制器。

我希望这可以帮助你!