Контроллеры представлений: как переключаться между представлениями программно?
короче говоря: я хочу иметь два полноэкранных вида, где я могу переключаться между видом A и видом B. Я знаю, что могу просто использовать контроллер панели вкладок, но я не хочу. Я хочу посмотреть, как это делается вручную, чтобы узнать, что происходит под капотом.
у меня есть UIViewController, который действует как корневой контроллер:
@interface MyRootController : UIViewController {
IBOutlet UIView *contentView;
}
@property(nonatomic, retain) UIView *contentView;
@end
contentView подключается к UIView, который я добавил в качестве подвида к "виду" пера. Это имеет зеленый цвет, и я вижу его полноэкранный. Работать отлично.
затем я создал два других контроллера вида почти таким же образом. ViewControllerA и ViewControllerB. ViewControllerA имеет синий фон, ViewControllerB имеет черный фон. Просто чтобы увидеть, какой из них активен.
Итак, в реализации myRootController я делаю следующее:
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
ViewControllerA *vcA = [[ViewControllerA alloc] initWithNib];
[self.contentView addSubview:vcA.view];
[cvA release];
}
кстати, метод-initWithNib выглядит так:
- (id)initWithNib { // Load the view nib
if (self = [super initWithNibName:@"ViewA" bundle:nil]) {
// do ivar initialization here, if needed
}
return self;
}
это работает. Я вижу вид из ViewControllerA, когда я запустите приложение. Но теперь большой вопрос: контроллер вида обычно имеет все эти методы, такие как:
- (void)viewWillAppear: (BOOL)анимированный;
- (void)viewDidDisappear: (BOOL)анимированный;
- (void)viewDidLoad;
...и так далее. Кто или что, или как эти методы будут вызваны, если я сделаю это "по-своему" без контроллера панели вкладок? Я имею в виду: если я выделяю класс ViewController и видимость представления get, мне нужно будет взять заботитесь о вызове этих методов? Откуда он знает, что viewWillAppear, viewDidDisappear или viewDidLoad? Я считаю, что контроллер панели вкладок имеет всю эту "умность" под капотом. Или я ошибаюсь?
обновление: я проверил его. Если я отпущу контроллер вида (например: ViewControllerA), я не получу никакого сообщения журнала на viewDidDisappear. Только при выделении и инициализации ViewControllerA, я получаю viewDidLoad. Но это все. Таким образом, все признаки означают умность UITabBarController теперь ;) и я должен выяснить, как это повторить, верно?
4 ответов:
вы можете начать с самого простого removeFromSuperview / insertSubview и постепенно добавлять в него код.
//SwitchViewController.h #import @class BlueViewController; @class YellowViewController; @interface SwitchViewController : UIViewController { IBOutlet BlueViewController *blueViewController; IBOutlet YellowViewController *yellowViewController; } - (IBAction)switchViews:(id)sender; @property (nonatomic, retain) BlueViewController *blueViewController; @property (nonatomic, retain) YellowViewController *yellowViewController; @end//1. remove yellow view and insert blue view - (IBAction)switchViews:(id)sender { if(self.blueViewController.view.superview == nil) { [yellowViewController.view removeFromSuperview]; [self.view insertSubview:blueViewController.view atIndex:0]; } } //2. appear=insert, disappear=remove if(blueViewController.view.superview == nil) { [blueViewController viewWillAppear:YES]; [yellowViewController viewWillDisappear:YES]; [yellowViewController.view removeFromSuperview]; [self.view insertSubview:self.blueViewController.view atIndex:0]; [yellowViewController viewDidDisappear:YES]; [blueViewController viewDidAppear:YES]; } //3. now add animation [UIView beginAnimations:@"View Flip" context:nil]; [UIView setAnimationDuration:1.25]; [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; //blue view will appear by flipping from right if(blueViewController.view.superview == nil) { [UIView setAnimationTransition: UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES]; [blueViewController viewWillAppear:YES]; [yellowViewController viewWillDisappear:YES]; [yellowViewController.view removeFromSuperview]; [self.view insertSubview:self.blueViewController.view atIndex:0]; [yellowViewController viewDidDisappear:YES]; [blueViewController viewDidAppear:YES]; } [UIView commitAnimations];
есть хороший пример переключения представлений в главе 6 начала разработки iPhone. Вы можете увидеть исходный код здесь: http://iphonedevbook.com/
SwitchViewController имеет код для изменения представлений программно.
- (IBAction)switchViews:(id)sender { if (self.yellowViewController == nil) { YellowViewController *yellowController = [[YellowViewController alloc] initWithNibName:@"YellowView" bundle:nil]; self.yellowViewController = yellowController; [yellowController release]; } [UIView beginAnimations:@"View Flip" context:nil]; [UIView setAnimationDuration:1.25]; [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; UIViewController *coming = nil; UIViewController *going = nil; UIViewAnimationTransition transition; if (self.blueViewController.view.superview == nil) { coming = blueViewController; going = yellowViewController; transition = UIViewAnimationTransitionFlipFromLeft; } else { coming = yellowViewController; going = blueViewController; transition = UIViewAnimationTransitionFlipFromRight; } [UIView setAnimationTransition: transition forView:self.view cache:YES]; [coming viewWillAppear:YES]; [going viewWillDisappear:YES]; [going.view removeFromSuperview]; [self.view insertSubview: coming.view atIndex:0]; [going viewDidDisappear:YES]; [coming viewDidAppear:YES]; [UIView commitAnimations]; }
Если я правильно понимаю, что вы пытаетесь сделать это довольно просто.
просто добавьте UINavigationController в делегат приложения и выполните:
[navigationController pushView:vcA];делегаты будут называться соответственно:
- (void)viewWillAppear: (BOOL)анимированный;
- (void)viewDidDisappear: (BOOL)анимированный;
- (void)viewDidLoad;
и когда вы хотите посмотреть и нажимаем еще один:
[navigationController popViewControllerAnimated:true]; [navigationController pushView:vcB];Если вы не хотите, чтобы navigationController показывал просто использовать:
[navigationBar setHidden:YES];где navigationBar-это UINavigationBar, соответствующий вашему UINavigationController.
это может быть старая проблема, но я недавно столкнулся с той же проблемой и было трудно найти что-то, что работает. Я хотел переключаться между двумя дополнительными контроллерами вида, но я хотел, чтобы переключатель был анимирован (встроенные анимации работают нормально), и я хотел, чтобы он был совместим с раскадровками, если это возможно.
для использования встроенного перехода, UIView
+transitionFromView:toView:duration:options:completion:метод работает прекрасно. Но, это только переходы между видами, а не вид контроллеров.для перехода между всеми контроллерами вида, а не только видами, создавая пользовательский
UIStoryboardSegue- это путь. Независимо от того, используете ли вы раскадровки, этот подход позволяет инкапсулировать весь переход и управлять передачей соответствующей информации от одного контроллера вида к другому. Это только включает в себя подклассыUIStoryboardSegueи переопределить один метод,-perform.для справочной реализации см.
RAFlipReplaceSegue, в точный пользовательский сегмент я собрал, используя этот подход. В качестве бонуса он также заменяет старый контроллер вида на новый, если он находится вUINavigationControllerстек.
Comments