Контроллеры представлений: как переключаться между представлениями программно?



короче говоря: я хочу иметь два полноэкранных вида, где я могу переключаться между видом 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 теперь ;) и я должен выяснить, как это повторить, верно?

616   4  

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

    Ничего не найдено.