ios 分段控件更改时更改视图控制器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11422845/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Changing view controller when Segmented Control changes
提问by Ricardo Macario
This problem is driving me crazy. I'm trying to change the viewController
when the user changes the selected "tab" of the segmented control. I've spent a couple hours researching and haven't been able to find an answer that works or is done through storyboard.
这个问题让我发疯。我正在尝试更改viewController
用户更改分段控件的选定“选项卡”的时间。我花了几个小时进行研究,但无法找到有效的答案或通过故事板完成的答案。
It really bother me since setting a tab application is so easy, but trying to use the segmented control like the tab application is just not working. I already know how to detect which index is selected in the segmented control. How can I achieve this?
这真的很困扰我,因为设置选项卡应用程序是如此简单,但是尝试像选项卡应用程序一样使用分段控件是行不通的。我已经知道如何检测分段控件中选择了哪个索引。我怎样才能做到这一点?
Thank you very much.
非常感谢。
采纳答案by 8vius
I'd say it's much simpler to change subviews within a UIViewController
, you can set up your subviews in your storyboards and hook them up with IBOulets
in your controller you can set the hidden
property of your views to YES or NO depending on the control that was clicked.
我会说在 a 中更改子视图要简单得多UIViewController
,您可以在故事板中设置子视图并将它们与IBOulets
控制器连接起来,您可以hidden
根据单击的控件将视图的属性设置为 YES 或 NO。
Now, if you use @Robotic Cat's approach which is also a good solution you can have a little more modularity in how your app works, considering you'd have to place all your logic in one controller using the solution I presented.
现在,如果您使用 @Robotic Cat 的方法(这也是一个很好的解决方案),您可以在应用程序的工作方式上有更多的模块化,考虑到您必须使用我提供的解决方案将所有逻辑放在一个控制器中。
回答by Robotic Cat
NOTE: Answer updated with view controller containment code for iOS 5+ including @interface section
注意:答案更新为 iOS 5+ 的视图控制器包含代码,包括 @interface 部分
In an app of mine, I have a view controller with a Segment Control in the Navigation Bar and clicking on the "tabs" switches view controllers. The basic idea is to have an array of view controllers and switch between them using the Segment Index (and the indexDidChangeForSegmentedControl IBAction.
在我的一个应用程序中,我在导航栏中有一个带有段控件的视图控制器,单击“选项卡”可切换视图控制器。基本思想是拥有一组视图控制器并使用 Segment Index(和 indexDidChangeForSegmentedControl IBAction.
Example code (iOS 5 or later) from my app (this is for 2 view controllers but it's trivially extended to multiple view controllers); the code is slightly longer than for iOS 4 but will keep the object graph intact. Also, it uses ARC:
来自我的应用程序的示例代码(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 (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
Original example (iOS 4 or before):
原始示例(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];
}
}
回答by mtnBarreto
Take a look at this pod: https://github.com/xmartlabs/XLMailBoxContainer. It makes the UI animation among the view controllers. These view controller can extend UITableViewController or any other view controller.
看看这个 pod:https: //github.com/xmartlabs/XLMailBoxContainer。它在视图控制器之间制作 UI 动画。这些视图控制器可以扩展 UITableViewController 或任何其他视图控制器。
I hope this help you!
我希望这对你有帮助!
回答by jwj
UISegmentedControl is a little different in that it doesn't have a delegate protocol, you have to use the "add target" style. In your case what you want to do is add a target to be notified when the UISegmentedControl changes (which is likely the parent view controller), and then that target can deal with the tab switching.
UISegmentedControl 有点不同,因为它没有委托协议,您必须使用“添加目标”样式。在您的情况下,您想要做的是在 UISegmentedControl 更改时添加一个要通知的目标(这可能是父视图控制器),然后该目标可以处理选项卡切换。
For example:
例如:
[self.mainSegmentedControl addTarget:self action:@selector(changedSegmentedControl:) forControlEvents:UIControlEventValueChanged];
In this example, the code is being invoked from some view/controller that has access to the variable for the segmented control. We add ourself to get the changedSegmentedControl: method invoked.
在这个例子中,代码是从一些视图/控制器调用的,这些视图/控制器可以访问分段控件的变量。我们添加自己来调用 changedSegmentedControl: 方法。
Then you would have another method like so:
然后你会有另一种方法:
- (void)changedSegmentedControl:(id)sender
{
UISegmentedControl *ctl = sender;
NSLog(@"Changed value of segmented control to %d", ctl.selectedSegmentIndex);
// Code to change View Controller goes here
}
Note: this is untested code written from memory -- please consult the docs accordingly.
注意:这是从内存中编写的未经测试的代码——请相应地查阅文档。