从 .xib 文件加载自定义 UIView 时线程 1 EXC_BAD_ACCESS
Thread 1 EXC_BAD_ACCESS when loading custom UIView from .xib file
我正在尝试将一些自定义 UIView 从 .xib 文件加载到 UIScrollView 中,但我不断收到 "Thread 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 中,但似乎无法弄清楚这一点。
我知道这是一个常见问题,但到目前为止对我没有任何帮助。
该教程不太正确...
加载自定义视图时 - 您的 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
发布了一个完整的示例项目
看看这是否适合您。如果是这样,然后与您所拥有的进行比较,看看有什么不同。
我正在尝试将一些自定义 UIView 从 .xib 文件加载到 UIScrollView 中,但我不断收到 "Thread 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 中,但似乎无法弄清楚这一点。 我知道这是一个常见问题,但到目前为止对我没有任何帮助。
该教程不太正确...
加载自定义视图时 - 您的 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
发布了一个完整的示例项目看看这是否适合您。如果是这样,然后与您所拥有的进行比较,看看有什么不同。