Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/97.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 以编程方式定位UIToolbar(带或不带UIToolBarDeleteGate)的最佳方法?_Ios_Swift_Cocoa Touch_Uitoolbar_Uitoolbarposition - Fatal编程技术网

Ios 以编程方式定位UIToolbar(带或不带UIToolBarDeleteGate)的最佳方法?

Ios 以编程方式定位UIToolbar(带或不带UIToolBarDeleteGate)的最佳方法?,ios,swift,cocoa-touch,uitoolbar,uitoolbarposition,Ios,Swift,Cocoa Touch,Uitoolbar,Uitoolbarposition,我在PlayGo中实现了导航栏下面的分段控件 这似乎是一个经典问题,有人问: 在的文件中,它说 UINavigationBarDelegate、UISearchBarDelegate和 UIToolbarDelegate协议扩展此协议以允许 在屏幕上定位这些条 在以下文件中: 箱盖 指定条形图位于其包含视图的顶部 在以下文件中: 当工具栏由管理员管理时,不能设置委托 导航控制器。默认值为零 我目前的解决方案如下(注释掉的代码保留以供参考和方便): 如您所见,这不使用UIToolbarDe

我在PlayGo中实现了导航栏下面的分段控件

这似乎是一个经典问题,有人问:

在的文件中,它说

UINavigationBarDelegate、UISearchBarDelegate和 UIToolbarDelegate协议扩展此协议以允许 在屏幕上定位这些条

在以下文件中:

箱盖

指定条形图位于其包含视图的顶部

在以下文件中:

当工具栏由管理员管理时,不能设置委托 导航控制器。默认值为零

我目前的解决方案如下(注释掉的代码保留以供参考和方便):

如您所见,这不使用
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
    }
}