Ios 以编程方式定位UIToolbar(带或不带UIToolBarDeleteGate)的最佳方法?
我在PlayGo中实现了导航栏下面的分段控件 这似乎是一个经典问题,有人问:Ios 以编程方式定位UIToolbar(带或不带UIToolBarDeleteGate)的最佳方法?,ios,swift,cocoa-touch,uitoolbar,uitoolbarposition,Ios,Swift,Cocoa Touch,Uitoolbar,Uitoolbarposition,我在PlayGo中实现了导航栏下面的分段控件 这似乎是一个经典问题,有人问: 在的文件中,它说 UINavigationBarDelegate、UISearchBarDelegate和 UIToolbarDelegate协议扩展此协议以允许 在屏幕上定位这些条 在以下文件中: 箱盖 指定条形图位于其包含视图的顶部 在以下文件中: 当工具栏由管理员管理时,不能设置委托 导航控制器。默认值为零 我目前的解决方案如下(注释掉的代码保留以供参考和方便): 如您所见,这不使用UIToolbarDe
UIToolbarDelegate
UIToolbarDelegate
(提供位置(for:)
)在这种情况下如何发挥作用?既然我们总是可以定位自己(手动或使用自动布局),那么UIToolbarDelegate
的用例是什么
@利奥·纳坦(Leo Natan)在《UIToolbarDelegate》中的回答提到了,但工具栏似乎放在了Interface Builder中
此外,如果我们不在这里使用UIToolbarDelegate
,为什么我们不使用普通的UIView
而不是UIToolbar
?试试这个
UIView *containerVw = [[UIView alloc] initWithFrame:CGRectMake(0, 64, 320, 60)];
containerVw.backgroundColor = UIColorFromRGB(0xffffff);
[self.view addSubview:containerVw];
UIView *bottomView = [[UIView alloc] initWithFrame:CGRectMake(0, 124, 320, 1)];
bottomView.backgroundColor = [UIColor grayColor];
[self.view addSubview:bottomView];
UISegmentedControl *sg = [[UISegmentedControl alloc] initWithItems:@[@"Good", @"Bad"]];
sg.frame = CGRectMake(10, 10, 300, 40);
[view addSubview:sg];
for (UIView *view in self.navigationController.navigationBar.subviews) {
for (UIView *subView in view.subviews) {
[subView isKindOfClass:[UIImageView class]];
subView.hidden = YES;
}
}
通过设置工具栏的委托,并让委托方法返回
.top
,可以在工具栏底部获得正常阴影。如果同时将工具栏框调整高一点,它将覆盖导航栏的阴影,最终结果将是添加分段控件的更高导航栏
class ViewController : UIViewController, UIToolbarDelegate
{
lazy var toolbar: UIToolbar = {
let ret = UIToolbar()
ret.delegate = self
let segmented = UISegmentedControl(items: ["Good", "Bad"])
let barItem = UIBarButtonItem(customView: segmented)
ret.setItems([barItem], animated: false)
return ret
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(toolbar)
toolbar.delegate = self
}
override func viewDidLayoutSubviews() {
toolbar.frame = CGRect(
x: 0,
y: navigationController?.navigationBar.frame.height - 1 ?? 0,
width: navigationController?.navigationBar.frame.width ?? 0,
height: toolbar.frame.height
)
}
func position(for bar: UIBarPositioning) -> UIBarPosition {
return .top
}
}
UIToolbarDelegate(为:)提供职位)在这种情况下如何发挥作用?由于我们总是可以定位自己(手动或使用自动布局),UIToolbarDelegate的用例是什么
我真的不知道UIToolbarDelegate
是如何发挥作用的,如果您更改UINavigationController.toolbar
,它将崩溃“您无法手动设置UINavigationController管理的UIToolbar委托”,此外,如果尝试更改工具栏的约束或其translatesAutoResizengMaskintoConstraints
属性,也会发生同样的情况
此外,如果我们在这里不使用UIToolbarDelegate,为什么我们不使用普通的UIView而不是UIToolbar呢
这似乎是一个合理的问题。我想答案是你有一个UIView
子类,它已经有了UIToolbar
的行为,那么我们为什么要创建另一个类,比如UIToolbar
,除非你只想在导航栏下面看到一些视图
我知道有两种选择
1) 有关
当您必须在由NavigationController
管理的其他ViewController
中显示工具栏时,第一种方法可能会有所帮助
设置值时,可以将UINavigationController
子类化,并更改工具栏的Y轴位置
导入UIKit
私有变量上下文=0
类NavigationController:UINavigationController{
私有变量inToolbarFrameChange=false
var observerBag:[NSKeyValueObservation]=[]
重写func awakeFromNib(){
super.awakeFromNib()
self.inToolbarFrameChange=false
}
重写func viewDidLoad(){
super.viewDidLoad()
observerBag.append(
观察(\.center,选项:。新建){toolbar,\在
如果!self.inToolbarFrameChange{
self.inToolbarFrameChange=true
toolbar.frame=CGRect(
x:0,,
y:self.navigationBar.frame.height+UIApplication.shared.statusBarFrame.height,
宽度:toolbar.frame.width,
高度:toolbar.frame.height
)
self.inToolbarFrameChange=false
}
}
)
}
覆盖函数setToolbarHidden(hidden:Bool,动画:Bool){
super.setToolbarHidden(隐藏,动画:false)
var rectTB=self.toolbar.frame
rectTB=.0
}
}
2) 您可以创建自己的UIToolbar
,并将其添加到UIViewController
的视图中。然后,将约束添加到安全区域的前导、尾随和顶部
导入UIKit
最终类ViewController:UIViewController{
私有let toolbar=UIToolbar()
私有let segmentedControl:UISegmentedControl={
let control=UISegmentedControl(项:[“Op 1”、“Op 2”])
control.isEnabled=false
返回控制
}()
重写func loadView(){
super.loadView()
setupToolbar()
}
覆盖函数视图将出现(uo动画:Bool){
超级。视图将显示(动画)
导航控制器?.navigationBar.hideBorderLine()
}
专用函数设置工具栏(){
让barItem=UIBarButtonim(customView:segmentedControl)
toolbar.setItems([barItem],动画:false)
toolbar.isTranslucent=false
toolbar.isOpaque=false
view.addSubview(工具栏)
toolbar.translatesAutoResizengMaskintoConstraints=false
toolbar.leadingAnchor.constraint(equalTo:view.leadingAnchor).isActive=true
toolbar.trailingAnchor.constraint(equalTo:view.trailingAnchor).isActive=true
toolbar.topAnchor.constraint(equalTo:view.safeAreaLayoutGuide.topAnchor).isActive=true
}
}
专用扩展UINavigationBar{
func showBorderLine(){
findBorderLine().isHidden=false
}
func hideBorderLine(){
findBorderLine().isHidden=true
}
普里瓦特
class ViewController : UIViewController, UIToolbarDelegate
{
lazy var toolbar: UIToolbar = {
let ret = UIToolbar()
ret.delegate = self
let segmented = UISegmentedControl(items: ["Good", "Bad"])
let barItem = UIBarButtonItem(customView: segmented)
ret.setItems([barItem], animated: false)
return ret
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(toolbar)
toolbar.delegate = self
}
override func viewDidLayoutSubviews() {
toolbar.frame = CGRect(
x: 0,
y: navigationController?.navigationBar.frame.height - 1 ?? 0,
width: navigationController?.navigationBar.frame.width ?? 0,
height: toolbar.frame.height
)
}
func position(for bar: UIBarPositioning) -> UIBarPosition {
return .top
}
}