【问题标题】:Thread 1 EXC_BAD_ACCESS when loading custom UIView from .xib file从 .xib 文件加载自定义 UIView 时的线程 1 EXC_BAD_ACCESS
【发布时间】:2019-11-26 04:59:03
【问题描述】:

我正在尝试将 .xib 文件中的一些自定义 UIView 加载到 UIScrollView 中,但我不断收到“线程 1:EXC_BAD_ACCESS”。

因为这是我第一次真正尝试加载自定义 UIView(对 UICollectionView 和 UITableView 单元格做了很多次),所以我一直在关注这个tutorial

class PreSignupDataQuestionView : NibView
{
    @IBOutlet weak var vMainContainer: UIView!
    @IBOutlet weak var vQuestionViewContainer: UIView!
    @IBOutlet weak var ivQuestionViewImage: UIImageView!
    @IBOutlet weak var lblQuestion: UILabel!
}

class NibView : UIView
{
    var view: UIView!

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

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

private extension NibView
{
    func xibSetup()
    {
        backgroundColor = UIColor.clear
        view = loadNib()
        view.frame = bounds
        addSubview(view)

        view.translatesAutoresizingMaskIntoConstraints = false
        addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[childView]|",
                                                      options: [],
                                                      metrics: nil,
                                                      views: ["childView": view!]))
        addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[childView]|",
                                                      options: [],
                                                      metrics: nil,
                                                      views: ["childView": view!]))
    }
}

extension UIView
{
    func loadNib() -> UIView
    {
        let bundle = Bundle(for: type(of: self))
        let nibName = type(of: self).description().components(separatedBy: ".").last!
        let nib = UINib(nibName: nibName, bundle: bundle)

        // Error pops here
        return nib.instantiate(withOwner: self, options: nil).first as! UIView
    }
}

在我的 UIViewController 中,我有一个设置 UIScrollView 的函数,它可以正常工作,直到我尝试加载自定义 UIView。

for index in 0..<self.screenData.count
{
    let xCoordinate = (CGFloat(index) * (width)) + firstSpace
    let viewFrame = CGRect(x: xCoordinate, y: 0, width: width - spaceBetweenView, height: height)

    let childView = PreSignupDataQuestionView().loadNib() as! PreSignupDataQuestionView

    childView.frame = viewFrame
    childView.tag = index
    childView.isUserInteractionEnabled = true

    childView.ivQuestionViewImage.image = UIImage(named: "PlaceholderImage")
    childView.lblQuestion.text = "Lorep Ipsum"
    self.svQuestions.addSubview(childView)
}

但是,如果不涉及 .xib,我加载 UIView 没有问题:

let xCoordinate = (CGFloat(index) * (width)) + firstSpace + lastSpace
let viewFrame = CGRect(x: xCoordinate, y: 0, width: width - spaceBetweenView, height: height)
let childView = UIView()
childView.tag = index
childView.isUserInteractionEnabled = true

if index % 2 == 0 { childView.backgroundColor = .red }
else { childView.backgroundColor = .green }

childView.frame = viewFrame
self.scrollView.addSubview(childView)

有什么想法吗?一段时间以来,我一直在尝试将自定义 UIView 加载到 UIScrollView 中,但似乎无法弄清楚。 我知道这是一个常见问题,但到目前为止对我没有任何帮助。

【问题讨论】:

  • 哪一行给你错误?如果不确定,请设置断点并在调试中单步执行,直到找到为止。
  • 扩展中的loadNib函数返回:return nib.instantiate(withOwner: self, options: nil).first as!界面视图
  • 分配给nibName的值是否正确?
  • 是的,它是:PreSignupDataQuestionView(无扩展)

标签: swift uiview uiscrollview xib nib


【解决方案1】:

那个教程不太对...

在加载自定义视图时 - 您的 PreSignupDataQuestionView - 通过代码,更改此行:

let childView = PreSignupDataQuestionView().loadNib() as! PreSignupDataQuestionView

简单地说:

let childView = PreSignupDataQuestionView()

这应该会解决它。


编辑:

在新的视图控制器中尝试此操作,以排除任何其他可能的问题:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let childView = PreSignupDataQuestionView()

        childView.translatesAutoresizingMaskIntoConstraints = false

        view.addSubview(childView)

        NSLayoutConstraint.activate([
            childView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 100),
            childView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 50),
            childView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -50),

            childView.heightAnchor.constraint(equalToConstant: 300),

            ])

    }

}

编辑 2:

我在https://github.com/DonMag/XIBLoadExtension发布了一个完整的示例项目

看看这是否适合你。如果是这样,请与您所拥有的进行比较,看看有什么不同。

【讨论】:

  • 谢谢。但是我已经尝试过了,我得到了同样的错误。
  • 嗯...为我修好了。请参阅我编辑的答案。
  • 在一个新的 VC 中试过了,我还是一样的错误,在同一行。
  • 添加了一个示例项目 - 请参阅我的回答中的 EDIT 2。
  • 谢谢。似乎我在 File's Owner 中有一些不好的插座引用。不敢相信我错过了。我必须进行一些更改以使其适合 UIScrollView 并调整其大小,但您的示例效果很好。
猜你喜欢
  • 2017-10-01
  • 1970-01-01
  • 2015-02-03
  • 2013-10-21
  • 2016-10-31
  • 2020-05-16
  • 2016-07-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多