Изменение содержимого контейнера с вкладками в iOS - программирование
Подтвердить что ты не робот

Изменение содержимого контейнера с вкладками в iOS

Я пытаюсь сделать форму, которая охватывает три вкладки. Вы можете увидеть на скриншоте ниже, где будут отображаться вкладки. Когда пользователь отбирает вкладку, Container View должен обновлять и отображать определенный контроллер представления, который у меня есть.

view controller

Вкладка 1 = Контроллер просмотра 1

Вкладка 2 = Контроллер просмотра 2

Вкладка 3 = Контроллер просмотра 3

Контроллер представления, показанный выше, имеет класс PPAddEntryViewController.m. Я создал выход для контейнера в этом классе и теперь имеет свойство Container View:

@property (weak, nonatomic) IBOutlet UIView *container;

У меня также есть мои IBActions для моих вкладок:

- (IBAction)tab1:(id)sender {
  //...
}
- (IBAction)tab2:(id)sender {
  //...
}
- (IBAction)tab3:(id)sender {
  //...
}

Как настроить контейнер в этих IBActions для изменения контроллера представления, который имеет вид контейнера?

Среди нескольких других вещей, вот что я пробовал:

UIViewController *viewController1 = [self.storyboard instantiateViewControllerWithIdentifier:@"vc1"];
_container.view = viewController1;

... но это не работает. Спасибо заранее.

4b9b3361

Ответ 1

Недавно я нашел пример кода совершенный для того, что я пытался сделать. Он включает в себя реализацию раскадровки и все соответствующие сегменты и код. Это было действительно полезно.

https://github.com/mhaddl/MHCustomTabBarController

Ответ 2

Переключение с помощью раскадровки, автоматическая компоновка или нет, кнопка какого-то типа и серия контроллеров детского просмотра

Вы хотите добавить представление контейнера в свое представление и когда нажаты кнопки, которые "переключают" контроллеры детского просмотра, сбрасывают соответствующий сегмент и выполняют правильную работу по настройке.

В раскадровке вы можете подключить только один Embed Segue к представлению контейнера. Таким образом, вы создаете контроллер промежуточной обработки. Сделайте встраивание segue и дайте ему идентификатор, например EmbededSegueIdentifier.

В своем родительском представлении контроллер подключается к кнопке или независимо от того, что вы хотите и сохраняете, ссылаясь на ваш контроллер детского вида в подготовительном сеансе. Как только контроллер родительского представления загрузит сегрегацию, будет запущен.

Контроллер родительского контроля

@property (weak, nonatomic) MyContainerViewController *myContainerViewController;

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"EmbeddedSegueIdentifier"]) {
        self.myContainerViewController = segue.destinationViewController;
    }
}

Вам должно быть довольно легко делегировать ваш контроллер контейнера, который нажимает кнопка.

Контейнерный контроллер

Этот следующий бит кода был частично заимствован из нескольких источников, но ключевое изменение заключается в том, что используется автоматический макет в отличие от явных фреймов. Ничто не мешает вам просто менять строки [self addConstraintsForViewController:] для viewController.view.frame = self.view.bounds. В раскадровке этот контроллер просмотра контейнера не делает ничего больше, чем для целевых дочерних контроллеров представления.

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSLog(@"%s", __PRETTY_FUNCTION__);

    [self performSegueWithIdentifier:@"FirstViewControllerSegue" sender:nil];
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    UIViewController *destinationViewController = segue.destinationViewController;

    if ([self.childViewControllers count] > 0) {
        UIViewController *fromViewController = [self.childViewControllers firstObject];
        [self swapFromViewController:fromViewController toViewController:destinationViewController];
    } else {
        [self initializeChildViewController:destinationViewController];
    }
}

- (void)initializeChildViewController:(UIViewController *)viewController
{
    [self addChildViewController:viewController];
    [self.view addSubview:viewController.view];
    [self addConstraintsForViewController:viewController];

    [viewController didMoveToParentViewController:self];
}

- (void)swapFromViewController:(UIViewController *)fromViewController toViewController:(UIViewController *)toViewController
{
    [fromViewController willMoveToParentViewController:nil];
    [self addChildViewController:toViewController];
    [self transitionFromViewController:fromViewController toViewController:toViewController duration:0.2f options:UIViewAnimationOptionTransitionCrossDissolve animations:nil completion:^(BOOL finished) {
        [self addConstraintsForViewController:toViewController];
        [fromViewController removeFromParentViewController];
        [toViewController didMoveToParentViewController:self];
    }];
}

- (void)addConstraintsForViewController:(UIViewController *)viewController
{
    UIView *containerView = self.view;
    UIView *childView = viewController.view;
    [childView setTranslatesAutoresizingMaskIntoConstraints:NO];
    [containerView addSubview:childView];

    NSDictionary *views = NSDictionaryOfVariableBindings(childView);
    [containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[childView]|"
                                                                          options:0
                                                                          metrics:nil
                                                                            views:views]];
    [containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[childView]|"
                                                                          options:0
                                                                          metrics:nil
                                                                            views:views]];
}



#pragma mark - Setters

- (void)setSelectedControl:(ViewControllerSelectionType)selectedControl
{
    _selectedControl = selectedControl;

    switch (self.selectedControl) {
        case kFirstViewController:
            [self performSegueWithIdentifier:@"FirstViewControllerSegue" sender:nil];
            break;
        case kSecondViewController:
            [self performSegueWithIdentifier:@"SecondViewControllerSegue" sender:nil];
            break;
        default:
            break;
    }
}

Пользовательские сегменты

Последнее, что вам нужно, это настраиваемый segue, который ничего не делает, и отправляется в каждый пункт назначения с соответствующим идентификатором segue, который вызывается из контроллера контейнера. Если вы не поместите пустой метод, приложение будет аварийно завершено. Обычно вы можете сделать некоторую настраиваемую анимацию перехода здесь.

@implementation SHCDummySegue

@interface SHCDummySegue : UIStoryboardSegue

@end

- (void)perform
{
    // This space intentionally left blank
}

@end

Ответ 3

Обновить: UITabBarController - это рекомендуемый способ, как вы узнали ранее. Если вы хотите иметь настраиваемую высоту, вот хороший старт: Мой способ настройки вкладки UITabBarController - ответ на стоп-запрос

Начиная с iOS 5+ у вас есть доступ к настройке внешнего вида через этот API; Ссылка на протокол UIAppearance. Вот хороший учебник для этого: Как настроить фон вкладки и внешний вид

Самый очевидный способ добиться того, что вы ищете, - просто управлять 3-мя различными контейнерами (это простые UIViews) и реализовать каждый из них для хранения любого содержимого, необходимого для каждой вкладки (используйте скрытое свойство контейнеры).

Вот пример того, что можно достичь с помощью разных контейнеров:

Embed View Controllers

Эти контейнеры "подкачки" могут быть анимированы, конечно. О вашем самоответстве вы, вероятно, выбрали правильный способ сделать это.

Ответ 4

имеет переменную-член для хранения viewController:

UIViewController *selectedViewController;

теперь в IBActions, переключите это AND view. например.

- (IBAction)tab1:(id)sender {
     UIViewController *viewController1 = [self.storyboard instantiateViewControllerWithIdentifier:@"vc1"];

     _container.view = viewController1.view;
     selectedViewController = viewController1;
}

чтобы показать огонь, и назыв removeChildViewController, didMoveToParent, addChildViewController, didMoveToParent

Ответ 5

Я получил это для работы с помощью UITabBarController. Чтобы использовать пользовательские вкладки, мне пришлось подклассифицировать TabBarController и добавить кнопки в контроллер в коде. Затем я слушаю события кратковременного нажатия на кнопки и устанавливаю selectedIndex для каждой вкладки.

Это было довольно прямолинейно, но в моей раскадровке много мусора для чего-то простого, как 3 вкладки.