在 UIViewController 的子视图上初始化 xib

Initializing a xib on a UIViewController's subview

当 UITableView 中没有可显示的内容时,我正在使用 DZNEmptySet 进行加载。它适用于 DZNEmptySet 的方法,如 titleForEmptyDataSetimageForEmptyDataSet,但不适用于我想要使用的方法(即 customViewForEmptyDataSet)。

当我尝试将 xib 加载到 scrollView.frame 时,Xcode 的内存开始以 30 MB 的增量膨胀并且应用程序挂起。我知道我错了,但我不知道我在搞什么。

我在这里查看了很多答案和其他网站上的教程,但找不到适用于这种情况的解决方案(我认为这很简单)。非常感谢有关这方面的任何反馈。

customViewForEmptyDataSetMyViewController

// App hangs on this and memory bloats in 30 megabyte increments.
func customViewForEmptyDataSet(scrollView: UIScrollView!) -> UIView! {
    return EmptySetView(frame: scrollView.frame)
}

这是我要初始化的 EmptySetView 的 class:

import UIKit

class EmptySetView: UIView {
    var view: UIView!
    // These are connected to a xib
    @IBOutlet weak var backgroundImageView: UIImageView!
    @IBOutlet weak var viewLabel: UILabel!
    @IBOutlet weak var viewTextView: UITextView!

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

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

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

    func loadViewFromNib() -> UIView {
        let bundle = NSBundle(forClass:self.dynamicType)
        let nib = UINib(nibName: "EmptySetView", bundle: bundle)
        let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView

        return view
    }
}

更新

,我调查了我遇到的递归并发现了问题的根源。

您没有在 View 上为您的 xib 指定 UIView class。相反,您单击标题为 File's Owner 的黄色立方体并在此处指定 UIView,将 View[=53] 上的 class 字段留空=] 在文档大纲面板中。

清理缓存并重建后,我可以使用在 MyViewController:

上调用的代码获取要在层次结构中加载的视图
func customViewForEmptyDataSet(scrollView: UIScrollView!) -> UIView! {
    let emptySetView = EmptySetView(frame: scrollView.frame)
    return emptySetView
}

EmptySetView xib 和 MyViewController 在加载 xib 之前不知道彼此,因此您需要处理布局约束。

我的猜测是,在您正在加载的 nib 中,顶级视图本身就是一个 EmptySetView。这导致了递归。您首先在代码中实例化 EmptySetView:

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

setup() 中加载笔尖。但这会导致从笔尖再次实例化 EmptySetView。这一次,另一个初始化器被调用:

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

但是 setup() 加载了 nib,所以我们现在在兜圈子,试图像俄罗斯套娃一样将无限数量的 nib 加载视图嵌套在一起。