UICollectionView 崩溃并出现错误:线程 1:EXC_BAD_ACCESS
Posted
技术标签:
【中文标题】UICollectionView 崩溃并出现错误:线程 1:EXC_BAD_ACCESS【英文标题】:UICollectionView Crashes with Error : Thread 1: EXC_BAD_ACCESS 【发布时间】:2018-06-11 11:14:16 【问题描述】:本来我的CollectionView工作正常,但是我想根据CollectionView中TextLabel的宽度来调整CollectionView中item的宽度,所以我加了一些代码,然后程序初始化的时候就崩溃了:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "OnedaySubTodoCell", for: indexPath) as! SubCell
let width = 28 + cell.subNameLabel.bounds.size.width
print("Width: \(width)")
return CGSize(width: width, height: 20)
这是一个错误报告,它显示在class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate
:
线程 1:EXC_BAD_ACCESS(代码=1,地址=0x7a00b0018)
这是输出:
宽度:88.0 (lldb)
我的班级继承了UICollectionViewDelegateFlowLayout
,我想知道问题出在哪里。
【问题讨论】:
您不应访问 .sizeForItemAt
方法
@PrashantTukadiya那么如何动态调整宽度?
标签没有被初始化,所以你不能访问它。检查这个***.com/questions/28409390/…
在let cell...
之后立即调用cell.awakeFromNib()
可能会有所帮助。
永远不要在cellForItemAt
之外使用dequeueReusableCell
。
【参考方案1】:
正如@rmaddy 和@Prashant 指出的那样,
您不应该在
sizeForItemAT
中使用cellForItemAt
,因为sizeForItemAt
在初始化单元格之前被调用cellForItemAt
这很可能就是您崩溃的原因。走向解决方案。
我遇到了类似的问题(必须动态管理高度),我所做的是类似
根据文本计算标签的估计宽度。使用以下字符串扩展名
//calculates the required width of label based on text. needs height and font of label
extension String
func width(withConstrainedHeight height: CGFloat, font: UIFont) -> CGFloat
let constraintRect = CGSize(width: .greatestFiniteMagnitude, height: height)
let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [.font: font], context: nil)
return ceil(boundingBox.width)
现在,在sizeForItemAt
里面
//put actual lblHeight here
let lblHeight = Put_actual_label_height_here // e.g 30
//put actual label font here
let lblFont = Put_actual_label_font_here //e.g UIFont.boldSystemFont(ofSize: 20)
//calculate required label width
let lblRequiredWidth = yourLabel's_Text_String.width(withConstrainedHeight: lblHeight, font: lblFont)
//you may want to return size now
let height = yourItemsHeight
return CGSize(width: lblRequiredWidth, height: height)
现在您已经获得了所需的标签宽度,您可以根据标签的宽度调整项目的大小。
希望对您有所帮助。如果您需要任何帮助,请告诉我。谢谢
【讨论】:
title 是标签的文本字符串。查看更新的答案 如果不使用cellForItemAt
或dequeueReusableCell
,如何获取标签?
你是怎么设计的?故事板还是以编程方式?
故事板中的设计。
好吧,我需要查看设计和约束才能完美回答。你只需要标签height
和font
。你已经设置了约束,所以你知道高度是什么,它的字体是什么。使用此信息以上是关于UICollectionView 崩溃并出现错误:线程 1:EXC_BAD_ACCESS的主要内容,如果未能解决你的问题,请参考以下文章
UICollectionView 中的 viewForSupplementaryElementOfKind 返回 nil 并使用 swift 使应用程序崩溃