如何通过工具栏按钮替换容器视图?
Posted
技术标签:
【中文标题】如何通过工具栏按钮替换容器视图?【英文标题】:How to replace container view via toolbar buttons? 【发布时间】:2014-04-04 17:58:16 【问题描述】:我想创建一个 UI,其中有一个导航栏及其按钮,其下方有一个工具栏,两者始终可见。然后,我希望底部有一个工具栏,当您点击按钮时,它将替换屏幕中间可见的内容。我会使用UITabBarController
,但我不想要下面的文本标签,也不想要图标的图像 - 按钮将是一个 unicode 字符。它们应该是灰色的,然后在选择一个时用浅色填充。我在想这样做的方法是在点击按钮时应用色调,但由于条形按钮没有粘性“选定状态”,我不知道该怎么做。
我也不确定如何替换中间的内容。我在想我应该创建一个容器,然后从每个将performSegueWithIdentifier
的按钮创建一个操作方法到一个包含不同内容的不同容器。但是只能嵌入一个视图控制器——我不能从容器中创建多个 segue。我基本上是在尝试用较小的按钮模拟一个标签栏控制器,没有标签,并且屏幕上的整个内容不会在点击按钮时被替换。
我该怎么做呢?我想在 Interface Builder 中完成基本布局,但当然需要一些代码。谢谢!
这基本上是我想要实现的目标:
【问题讨论】:
请使用xcode
标签仅用于与IDE相关的问题。
【参考方案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】:我已经实现了我想要的行为。
这不是一个特别干净的解决方案,但它确实提供了一个额外的好处:能够在底部的选项卡之间滑动。
基本上:
-
我创建了一个填充整个屏幕的容器视图,其中包含一个页面视图控制器
我删除了页面控件(没有实现委托方法,所以您看不到点)
页面是来自可重用视图控制器的 5 个集合视图
我实现了在页面完全转换时调用的委托方法,然后在循环其他按钮将色调重置为灰色之后,我更改了底部相应栏按钮的色调颜色(默认为灰色) .
如果用户点击条形按钮而不是滑动,我会为页面视图控制器设置视图控制器,然后更新色调。
这运行良好,但代码不是很好。
我可能会做的另一件事是覆盖栏按钮突出显示状态。 当用户突出显示一个标签栏按钮时,标签栏按钮不应变亮。
有趣的是,不允许在页面之间滑动很容易,只需删除页面视图控制器数据源方法即可。然后它的行为就像一个真正的选项卡式界面。不过,我非常喜欢滑动和点击的灵活性。
【讨论】:
【参考方案3】:这不是一个完整的答案,只是我目前可以提供的一点帮助
您可以将UIButton
用作UIBarButtonItem
对象的customView
,然后利用UIButton
对象的highlighted
和/或selected
状态。
另外...如果您打算使用 Unicode 而不是图像,那么 tintColor
并不重要。
您不妨简单地更改按钮titleLabel
的textColor
(取决于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,我只能这样想:
-
将类似
UITabBar
的视图固定到底部
用空的UIView
对象填充顶部空间
将标签viewControllers
作为childViewControllers
添加到此UIView
此外,您可以查看我最近开始在 github 上创作的一个有点相似的组件:https://github.com/staticVoidMan/SVMSlidingTabBar
1. 非故事板(但不太难移植)
2. 目前仅支持标签按钮的图像(但感谢您的想法)
【讨论】:
我决定采用不同的方法,但你让我想到了突出的色调等。 :) @Joey :太好了,只要它做你想做的事 :)以上是关于如何通过工具栏按钮替换容器视图?的主要内容,如果未能解决你的问题,请参考以下文章