带有自定义 UIToolbar xib 的 Storyboard 中的 UINavigationController 失败

Posted

技术标签:

【中文标题】带有自定义 UIToolbar xib 的 Storyboard 中的 UINavigationController 失败【英文标题】:UINavigationController in Storyboard with custom UIToolbar xib fails 【发布时间】:2016-02-25 05:22:14 【问题描述】:

我正在尝试为带有单个标签的 UIToolbar 加载一个简单的自定义 xib,只是为了让事情正常工作,而我的 init?(coder aDecoder: NSCoder) 方法在尝试修改标签的文本时失败,因为它尚未实例化。

致命错误:在展开可选值时意外发现 nil

我在这里使用 UIView 代替 UIToolbar,因为它更易于使用,这可能是问题所在。如果我在我的 xib 文档中使用 UIToolbar,它会强制我放置在 UIToolbar 上的所有内容都成为 UIBarButtonItem,而不幸的尺寸效应是这会产生不希望的填充。请注意在此处将 UIViews 添加到图像中的 UIToolbar 时可以看到的红色条色调(看看红色有多难看!????):

我相信我已经在 Xcode 的 Inspector 面板中设置了所有必要的设置和 IBOutlets。并具有简单的居中 x,y 布局约束。

更新 1:

如果我将 UIView 添加到 UIToolbar,我将遇到 UIToolbar > UIBarButtonItem > UIView 的视图层次结构。选择 UIView 并读取 Xcode 右侧面板上的 Size Inspector,您将看到类似于以下内容:

这具有一组不可用的点(UIView 左侧 16 点和顶部 6 点)的不幸副作用。尽管 UIView 足够大,顶部的 6 个点可以重新获得,但左侧的 16 个点不能。再次注意顶部图像中的红色边距。

更新 2:

任何 16 点的 UIView 偏移现在都可以使用下面我的新解决方案进行修复。

【问题讨论】:

【参考方案1】:

我找到了您的问题。

你的问题,你用 .XIB 中的 UIView 代替了 UIToolbar

按照以下步骤操作。

1) 您需要从 XIB 文件中删除 UIView 。并添加 UIToolbar 代替 UIVIew。

2) 将标识分配给 XIB CustomToolbar.swift

3) 现在在 CustomToolbar.swift

中将 IBOutlet 设置为 Item

4) 在您的 Viewdidload 中放入以下代码,

let toolBar = UINib(nibName: "CustomToolbar", bundle: nil).instantiateWithOwner(nil, options: nil).first as! CustomToolbar

        self.navigationController!.view.addSubview(toolBar)
        self.navigationController!.toolbarItems = toolBar.items

5) 在你的所有视图控制器 viewdidload 中添加

self.toolbarItems = self.navigationController!.toolbarItems

编辑:-您可以在 UIToolbar 中添加 UIView 并根据您的要求添加控件。

希望这些信息对您有所帮助。

【讨论】:

您好,感谢您的回复。我知道我的 UIView 是很好的问题 #1。我对向 UIToolbar 添加按钮不感兴趣,但我想自定义工具栏,因为我想要任何其他 UIView... 您可以在我的问题中看到我已经尝试将 UIToolbar 添加到我的 xib 中,但它具有在按钮周围填充的副作用。我想让视图封装整个空间。 检查已编辑的答案。 还有一件事你说 UIToolbar 所以,我用 UIToolbar 给出答案。如果你想在 All 控制器中使用 UIView,那么你可以将 Normal .XIB 与 UIView 一起使用。并且只需在所有视图控制器中添加Subview 作为 XIB。 你知道在 UIToolbar 上设置 UIView 的 X 和 Y 坐标的方法吗?尺寸检查器锁定 X = 16 和 Y = 6...我的目标是到达 UIToolbar 视图的边缘。我会用这个更新我的问题。【参考方案2】:

您的 xib 参考丢失。这就是你得到致命错误的原因。

调试时,你会得到 'UILabel' 为 nil。

不使用.xib,可以使用我下面的代码。

    import Foundation
    import UIKit

    class CustomToolbar: UIToolbar 
       var label: UILabel!

        required convenience init(coder aDecoder: NSCoder) 
            self.init(aDecoder)
            self.initialize()
        

        init(_ coder: NSCoder? = nil) 
            if let coder = coder 
                super.init(coder: coder)!
            
            else 
                super.init(frame: CGRectZero)
            
        

        // Initial the toolbar based on the frame.
        override init(frame:CGRect) 
            super.init(frame:frame)
            self.initialize()
        

        // Initialize the label.
        func initialize() 
            self.label = UILabel.init();
            self.label.textColor = UIColor.redColor();
            self.label.font = UIFont.systemFontOfSize(18);
            self.label.frame = CGRectMake(0, 0, UIScreen.mainScreen().bounds.width, 21);
            self.addSubview(self.label);
            label.text = "Some text assigned programmatically" // Success
        
    

【讨论】:

谢谢,是的。没有 xib,您的代码就可以工作!但我真的很想使用 xib。【参考方案3】:

@BadalShah 是正确的,尽管他在 UINavigationController 子类或 UIViewController 中处理添加子视图的实现并不是很理想 - 它应该在 CustomToolbar 类中处理,如此处所述。

@VigneshKumar 几乎是正确的!我需要在我的 CustomToolbar 类中加载笔尖。之前,我将 CustomToolbar 类名应用于错误的 UIView。我只需要将它分配给文件的所有者。为 xib 赋予与我的自定义类不同的文件名也有帮助,因为我不再对哪个视图需要分配什么类名感到困惑。

let nibName = "MyView"

func setup() 
    view = loadViewFromNib()
    view.frame = bounds
    view.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
    addSubview(view)


func loadViewFromNib() -> UIView 
    let bundle = NSBundle(forClass: self.dynamicType)
    let nib = UINib(nibName: nibName, bundle: bundle)
    let view = nib.instantiateWithOwner(self, options: nil).first as! UIView
    return view


override init(frame: CGRect) 
    super.init(frame: frame)
    setup()


required init?(coder aDecoder: NSCoder) 
    super.init(coder: aDecoder)
    setup()

    // label should already be initialized. Let's try changing the text!
    label.text = "Some new data!" // Works! ?

【讨论】:

以上是关于带有自定义 UIToolbar xib 的 Storyboard 中的 UINavigationController 失败的主要内容,如果未能解决你的问题,请参考以下文章

自定义 UIToolbar 按钮不起作用

带有文本快捷方式的自定义 UIToolbar 的行为与带有 UIButtons 和 UITableViewControllers 的键盘完全不同

如何使用包含彩色图像的按钮自定义 UIToolbar?

带有自定义 xib 的 TableCellView 未加载

水平居中 UIToolbar 中的所有项目,包括使用 UILabel 的自定义视图

UIToolBar:如何设置自定义文本/背景颜色