基于 UILabel 的动态 UICollectionView 标头大小 [英] Dynamic UICollectionView header size based on UILabel
问题描述
我已经阅读了很多关于向 UICollectionView 添加标题的帖子.在 Swift 的 iOS 7+ 应用程序中,我试图添加一个带有 UILabel 的标题,其高度应根据 UILabel 的高度进行调整.UILabel 的行数 = 0.
I've read a bunch of posts on adding header to UICollectionView. In an iOS 7+ app in Swift, I'm trying to add a header with a UILabel in it whose height should adjust based on the height of UILabel. The UILabel has lines = 0.
我已经使用 AutoLayout 在 IB 中设置了标题
I've set up the header in IB with AutoLayout
ViewController 实现了UICollectionViewDelegate, UICollectionViewDataSource
.我没有为标题设置自定义类,而是使用了这两个函数:
The ViewController implements UICollectionViewDelegate, UICollectionViewDataSource
. I didn't set up a custom class for the header but am using these two functions:
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
//description is a String variable defined in the class
let size:CGSize = (description as NSString).boundingRectWithSize(CGSizeMake(CGRectGetWidth(collectionView.bounds) - 20.0, 180.0), options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName: UIFont(name: "Helvetica Neue", size: 16.0)], context: nil).size
return CGSizeMake(CGRectGetWidth(collectionView.bounds), ceil(size.height))
}
func collectionView(collectionView: UICollectionView!, viewForSupplementaryElementOfKind kind: String!, atIndexPath indexPath: NSIndexPath!) -> UICollectionReusableView! {
var reusableview:UICollectionReusableView = UICollectionReusableView()
if (kind == UICollectionElementKindSectionHeader) {
//listCollectionView is an @IBOutlet UICollectionView defined at class level, using collectionView crashes
reusableview = listCollectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionHeader, withReuseIdentifier: "ListHeader", forIndexPath: indexPath) as UICollectionReusableView
let label = reusableview.viewWithTag(200) as UILabel //the UILabel within the header is tagged with 200
label.text = description //description is a String variable defined in the class
}
}
return reusableview
}
文本显示似乎有效,但高度计算似乎无效(请参见下面的屏幕截图).此外,我认为我也无法通过 collectionView...referenceSizeForHeaderInSection
函数访问 UILabel.关于如何正确计算 CGSize 的任何建议?
The displaying of the text seems to be working but the height calculation doesn't seem to be working (see screenshot below). Also, I don't think I can access the UILabel via the collectionView...referenceSizeForHeaderInSection
function either. Any suggestions on how to calculate CGSize correctly?
推荐答案
我是这样做的:
let labels = [
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ac lorem enim. Curabitur rhoncus efficitur quam, et pretium ipsum. Nam eu magna at velit sollicitudin fringilla nec nec nisi. Quisque nec enim et ipsum feugiat pretium. Vestibulum hendrerit arcu ut ipsum gravida, ut tincidunt justo pellentesque. Etiam lacus ligula, aliquet at lorem vel, ullamcorper commodo turpis. Nullam commodo sollicitudin mauris eu faucibus.",
"Lorem ipsum dolor",
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ac lorem enim. Curabitur rhoncus efficitur quam, et pretium ipsum. Nam eu magna at velit sollicitudin fringilla nec nec nisi. Quisque nec enim et ipsum feugiat pretium."]
基本思想是创建一个与将在部分标题中显示的相同的 UILabel
.该标签将用于在 referenceSizeForHeaderInSection
方法中为标题设置所需的大小.
The basic idea is to create an identical UILabel
to the one that will be shown in the section header. That label will be used to set the desired size for the header in the referenceSizeForHeaderInSection
method.
我在我的 UICollectionReusableView
子类 (MyHeaderCollectionReusableView
) 中有一个名为 label
的标签插座,我通过分配它用于我的部分标题视图在情节提要中(将MyHeader"设置为剖面视图的重用标识符).提到的标签对节标题边框具有水平和垂直空间限制,以便正确自动布局.
I have a label outlet called label
in my UICollectionReusableView
subclass (MyHeaderCollectionReusableView
), which I use for my section header view by assigning it in the storyboard (setting "MyHeader" as Reuse Identifier for the section view). That mentioned label has the horizontal and vertical space constraints to the section header borders in order to autolayout correctly.
override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 3
}
override func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
let headerView =
collectionView.dequeueReusableSupplementaryViewOfKind(kind,
withReuseIdentifier: "MyHeader",
forIndexPath: indexPath)
as MyHeaderCollectionReusableView
headerView.label.text = labels[indexPath.section]
return headerView
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
// that -16 is because I have 8px for left and right spacing constraints for the label.
let label:UILabel = UILabel(frame: CGRectMake(0, 0, collectionView.frame.width - 16, CGFloat.max))
label.numberOfLines = 0
label.lineBreakMode = NSLineBreakMode.ByWordWrapping
//here, be sure you set the font type and size that matches the one set in the storyboard label
label.font = UIFont(name: "Helvetica", size: 17.0)
label.text = labels[section]
label.sizeToFit()
// Set some extra pixels for height due to the margins of the header section.
//This value should be the sum of the vertical spacing you set in the autolayout constraints for the label. + 16 worked for me as I have 8px for top and bottom constraints.
return CGSize(width: collectionView.frame.width, height: label.frame.height + 16)
}
这篇关于基于 UILabel 的动态 UICollectionView 标头大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!