【问题标题】:How to replace container view via toolbar buttons?如何通过工具栏按钮替换容器视图?
【发布时间】:2014-04-04 17:58:16
【问题描述】:

我想创建一个 UI,其中有一个导航栏及其按钮,其下方有一个工具栏,两者始终可见。然后,我希望底部有一个工具栏,当您点击按钮时,它将替换屏幕中间可见的内容。我会使用UITabBarController,但我不想要下面的文本标签,也不想要图标的图像 - 按钮将是一个 unicode 字符。它们应该是灰色的,然后在选择一个时用浅色填充。我在想这样做的方法是在点击按钮时应用色调,但由于条形按钮没有粘性“选定状态”,我不知道该怎么做。

我也不确定如何替换中间的内容。我在想我应该创建一个容器,然后从每个将performSegueWithIdentifier 的按钮创建一个操作方法到一个包含不同内容的不同容器。但是只能嵌入一个视图控制器——我不能从容器中创建多个 segue。我基本上是在尝试用较小的按钮模拟一个标签栏控制器,没有标签,并且屏幕上的整个内容不会在点击按钮时被替换。

我该怎么做呢?我想在 Interface Builder 中完成基本布局,但当然需要一些代码。谢谢!

这基本上是我想要实现的目标:

【问题讨论】:

  • 请使用xcode标签仅用于与IDE相关的问题。

标签: ios objective-c uitabbarcontroller uitoolbar


【解决方案1】:

这是我过去的做法。代码位于自定义容器控制器中,该控制器是嵌入在故事板的容器视图中的控制器。因此,在 viewDidAppear: 中,我将第一个控制器添加为子级,并在单击按钮时调用 switchToNewView:。

@implementation ContainerController


- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    UIViewController *initial = [self.storyboard instantiateViewControllerWithIdentifier:@"InitialVC"];
    [self addChildViewController:initial];
    [self.view addSubview:initial.view];
    self.currentController = initial;
    [self constrainViewEqual:self.currentController];
}

-(IBAction)switchToNewView {
    UIViewController *sub = [self.storyboard instantiateViewControllerWithIdentifier:@"SubstituteVC"];
    [self addChildViewController:sub];
    sub.view.frame = self.view.bounds;
    [self moveToNewController:sub];
}

-(void)moveToNewController:(UIViewController *) newController {
    [self.currentController willMoveToParentViewController:nil];
    [self transitionFromViewController:self.currentController toViewController:newController duration:.6 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{}
         completion:^(BOOL finished) {
             [self.currentController removeFromParentViewController];
             [newController didMoveToParentViewController:self];
             self.currentController = newController;
             [self constrainViewEqual:self.currentController];
         }];
}

constrainViewEqual 是我为控制器视图添加约束的类别方法。看起来是这样的,

-(void)constrainViewEqual:(UIViewController *) vc {
    [vc.view setTranslatesAutoresizingMaskIntoConstraints:NO];
    NSLayoutConstraint *con1 = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeCenterX relatedBy:0 toItem:vc.view attribute:NSLayoutAttributeCenterX multiplier:1 constant:0];
    NSLayoutConstraint *con2 = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeCenterY relatedBy:0 toItem:vc.view attribute:NSLayoutAttributeCenterY multiplier:1 constant:0];
    NSLayoutConstraint *con3 = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeWidth relatedBy:0 toItem:vc.view attribute:NSLayoutAttributeWidth multiplier:1 constant:0];
    NSLayoutConstraint *con4 = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeHeight relatedBy:0 toItem:vc.view attribute:NSLayoutAttributeHeight multiplier:1 constant:0];
    NSArray *constraints = @[con1,con2,con3,con4];
    [self.view addConstraints:constraints];
}

【讨论】:

  • 这看起来是个不错的解决方案。我决定采取不同的方法,所以我没有尝试,否则我会选择这个作为答案。 ;)
【解决方案2】:

我已经实现了我想要的行为。

这不是一个特别干净的解决方案,但它确实提供了一个额外的好处:能够在底部的选项卡之间滑动。

基本上:

  1. 我创建了一个填充整个屏幕的容器视图,其中包含一个页面视图控制器
  2. 我删除了页面控件(没有实现委托方法,所以您看不到点)
  3. 页面是来自可重用视图控制器的 5 个集合视图
  4. 我实现了在页面完全转换时调用的委托方法,然后在循环其他按钮将色调重置为灰色之后,我更改了底部相应栏按钮的色调颜色(默认为灰色) .
  5. 如果用户点击条形按钮而不是滑动,我会为页面视图控制器设置视图控制器,然后更新色调。

这运行良好,但代码不是很好。

我可能会做的另一件事是覆盖栏按钮突出显示状态。
当用户突出显示一个标签栏按钮时,标签栏按钮不应变亮。

有趣的是,不允许在页面之间滑动很容易,只需删除页面视图控制器数据源方法即可。然后它的行为就像一个真正的选项卡式界面。不过,我非常喜欢滑动和点击的灵活性。

【讨论】:

    【解决方案3】:

    这不是一个完整的答案,只是我目前可以提供的一点帮助


    您可以将UIButton 用作UIBarButtonItem 对象的customView,然后利用UIButton 对象的highlighted 和/或selected 状态。
    另外...如果您打算使用 Unicode 而不是图像,那么 tintColor 并不重要。
    您不妨简单地更改按钮titleLabeltextColor取决于UIControlStateNormal

    示例:

    - (void)testMethod
    {    
        UIToolbar *tbTest = [[UIToolbar alloc] init];
        [tbTest setFrame:CGRectMake(0, 100, 320, 44)];
        [self.view addSubview:tbTest];
    
        UIButton *btnTest = [UIButton buttonWithType:UIButtonTypeSystem];
        [btnTest setFrame:CGRectMake(0, 0, 100, 44)];
        [btnTest setTintColor:[UIColor blueColor]];
    
        [btnTest setTitle:@"Normal" forState:UIControlStateNormal];
        [btnTest setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
    
        [btnTest setTitle:@"Highlighted" forState:UIControlStateHighlighted];
        [btnTest setTitleColor:[UIColor orangeColor] forState:UIControlStateHighlighted];
    
        [btnTest setTitle:@"Selected" forState:UIControlStateSelected];
        [btnTest setTitleColor:[UIColor purpleColor] forState:UIControlStateSelected];
    
        [btnTest addTarget:self action:@selector(doSomething:) forControlEvents:UIControlEventTouchUpInside];
    
        UIBarButtonItem *btn2Test = [[UIBarButtonItem alloc] initWithCustomView:btnTest];
    
        [tbTest setItems:@[btn2Test]];
    }
    
    -(void)doSomething:(UIButton *)sender
    {
        [sender setSelected:!sender.selected];
    }
    

    关于重新创建tabBar,我只能这样想:

    1. 将类似UITabBar 的视图固定到底部
    2. 用空的UIView 对象填充顶部空间
    3. 将标签viewControllers 作为childViewControllers 添加到此UIView

    此外,您可以查看我最近开始在 github 上创作的一个有点相似的组件:
    https://github.com/staticVoidMan/SVMSlidingTabBar
    1. 非故事板(但不太难移植)
    2. 目前仅支持标签按钮的图像(但感谢您的想法

    【讨论】:

    • 我决定采用不同的方法,但你让我想到了突出的色调等。 :)
    • @Joey :太好了,只要它做你想做的事 :)
    猜你喜欢
    • 2019-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-15
    • 1970-01-01
    相关资源
    最近更新 更多