更改容器视图内容与标签iOS中(Change Container View Content with

2019-09-01 16:26发布

我试图做一个跨越三个选项卡的形式。 您可以在以下地方的标签将看到的截图。 当用户点击一个标签,容器应查看更新和显示特定视图控制器我有。

标签1 =视图控制器1

标签2 =视图控制器2

标签3 =视图控制器3

上面示出的视图控制器具有类PPAddEntryViewController.m。 我创建了这个类中的容器视图的出口,并且现在有一个容器视图属性:

@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;

...但它不工作。 提前致谢。

Answer 1:

开关电源采用故事板,自动布局与否,某种形式的按钮,以及一系列子视图控制器

你想容器视图添加到您的视图,当按钮“开关”子视图控制器被压断火合适SEGUE和执行正确的设置工作。

在故事板,你可以一个嵌入Segue公司只能连接到容器视图。 所以,你创建一个中间处理控制器。 使嵌入SEGUE,并给它的识别符,例如EmbededSegueIdentifier。

在你父视图控制器线向上按钮或者你想和保持是参考你的孩子视图控制器在准备SEGUE什么。 只要父视图控制器负载SEGUE将被解雇。

父视图控制器

@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 。 在故事板这种容器视图控制器没有做任何更多的SEGUE到目的地子视图控制器。

- (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标识每个目的地。 如果你不能把一个空不执行方法的应用程序会崩溃。 通常情况下,你可以在这里做一些定制的过渡动画。

@implementation SHCDummySegue

@interface SHCDummySegue : UIStoryboardSegue

@end

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

@end


Answer 2:

我最近发现了什么,我试图做的完美示例代码。 它包括故事板实现和所有相关的塞格斯和代码。 这是真的很有帮助。

https://github.com/mhaddl/MHCustomTabBarController



Answer 3:

更新 :是的UITabBarController推荐的路要走,因为你发现了前面。 如果你想有一个自定义的高度,这里是一个良好的开端: 我定制的UITabBarController的TabBar的方式-回答#1

由于iOS版的5 +您可以访问自定义通过该API的出现; UIAppearance协议参考 。 这里是一个很好的教程是: 如何自定义标签栏的背景和外观

实现你在找什么,最明显的方法就是管理3个不同的容器(它们是简单UIViews),并实现每个人抱着你需要为每个标签任何内容视图(使用容器的隐藏属性)。

这里是什么是可能实现与不同的容器的例子

这些容器“交换”可以是动画课程。 关于你的自我的答案,你可能选择做正确的方式。



Answer 4:

有一个成员变量来保存的viewController:

UIViewController *selectedViewController;

现在在IBActions,交换机和视图。 例如

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

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

火观点确实出现和东西通话removeChildViewController,didMoveToParent,addChildViewController,didMoveToParent



Answer 5:

我得到这个用的UITabBarController工作。 为了使用自定义选项卡,我只好子类TabBarController和按钮添加到控制器中的代码。 后来我听上的按钮点击事件,并设置selectedIndex为每个标签。

这是非常简单的,但它在我的故事板有很多的垃圾如3个选项卡一样简单。



文章来源: Change Container View Content with Tabs in iOS