简体   繁体   English

如何计算字符串的高度?

[英]How to calculate height of a String?

I am trying to adjust the cell height resize to fit the UILabel text, but it is not working.. 我正在尝试调整单元格高度的大小以适合UILabel文本,但是它不起作用。

var mySize = CGFloat()
    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! cellView

        cell.myLabel.text = self.items[indexPath.item]
        cell.myLabel.bounds.size.height = self.mySize

        cell.backgroundColor = UIColor.yellowColor()

        return cell
    }

    func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        // handle tap events
        print("You selected cell #\(indexPath.item)!")
    }

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {

        func heightForLabel(text:String, font:UIFont, width:CGFloat) -> CGFloat
        {
            let label:UILabel = UILabel(frame: CGRectMake(0, 0, width, CGFloat.max))
            label.numberOfLines = 0
            label.lineBreakMode = NSLineBreakMode.ByWordWrapping
            label.font = font
            label.text = items[indexPath.row]

            label.sizeToFit()
            return label.frame.height
        }

        let font = UIFont(name: "Helvetica Neue", size: 30)
        let detailHeight = heightForLabel(items[indexPath.row], font: font!, width: UIScreen.mainScreen().bounds.size.width)

        self.mySize = detailHeight

        return CGSizeMake(UIScreen.mainScreen().bounds.size.width, 358 + detailHeight)
    }

Any suggestions what to do here? 有什么建议在这里做什么? Should i do it another way? 我应该用其他方式吗? Please, I need help.. The problem is that the UILabel text is set in the cellForItemAtIndexPath , and items is an array for strings. 请,我需要帮助。问题是UILabel文本在cellForItemAtIndexPath设置,而items是字符串数组。

This is my project file, if someone watch to take a look at it: http://www.filedropper.com/test_37 如果有人看一下,这是我的项目文件: http : //www.filedropper.com/test_37

Why not try this in ObjC 为什么不在ObjC中尝试

 [text boundingRectWithSize:CGSizeMake(maxWidth, maxHeight)
                                  options:NSStringDrawingUsesLineFragmentOrigin
                               attributes:nil context:nil]

This will give CGRect. 这将给CGRect。 Get the height from it. 从中获取高度。 set font size etc in attributes parameter. 在属性参数中设置字体大小等。

UPDATE 更新

In place of this 代替这个

let detailHeight = heightForLabel(items[indexPath.row], font: font!, width: UIScreen.mainScreen().bounds.size.width)

Use this 用这个

let height = items[indexPath.row].boundingRectWithSize(CGSizeMake(CGFloat.max,UIScreen.mainScreen().bounds.size.width), options: .UsesLineFragmentOrigin, attributes: [NSFontAttributeName: font!], context: nil).size.height

Hope this helps 希望这可以帮助

You can do it like that but I have implemented it in different way. 您可以那样做,但是我以不同的方式实现了它。 Here is the sample of code you can do it. 这是您可以执行的代码示例。

 let desiredWidth: CGFloat = tableView.bounds.size.width
 let label: UILabel = UILabel()

 let desiredString = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged."

 label.text = desiredString
 label.numberOfLines = 0;
 label.lineBreakMode = NSLineBreakMode.ByWordWrapping
 let size: CGSize = label.sizeThatFits(CGSizeMake(desiredWidth, CGFloat.max))

 print("Label height you can set to your cell: \(size.height)")

I create this method for getting height of a label. 我创建此方法来获取标签的高度。 You need to provide label's static Width and label's font 您需要提供标签的静态宽度和标签的字体

func dynamicHeight(font: UIFont, width: CGFloat) -> CGFloat{
    let calString = NSString(string: self)
    let textSize = calString.boundingRectWithSize(CGSizeMake(width, CGFloat.max), options: NSStringDrawingOptions.UsesLineFragmentOrigin|NSStringDrawingOptions.UsesFontLeading, attributes: [NSFontAttributeName: font], context: nil)
    return textSize.height
}

Try this... 尝试这个...

   NSString *yourText = @"Your string";
    CGSize lableWidth = CGSizeMake(300, CGFLOAT_MAX);
    CGSize requiredSize = [yourText sizeWithFont:[UIFont fontWithName:@"CALIBRI" size:17] constrainedToSize:lableWidth lineBreakMode:NSLineBreakByWordWrapping];
    int calculatedHeight = requiredSize.height;
    return (float)calculatedHeight;

I took a look at your code, and I was able to solve it. 我看了看你的代码,我就能解决它。

Firstly, on line 71 in your ViewController class: 首先,在ViewController类的第71行:

let height = items[indexPath.row].boundingRectWithSize(CGSizeMake(CGFloat.max, UIScreen.mainScreen().bounds.size.width), options: .UsesLineFragmentOrigin, attributes: [NSFontAttributeName: font!], context: nil).size.height

You accidentally set CGFloat.max as width and the width as height. 您不小心将CGFloat.max设置为宽度,而将宽度设置为高度。 It should be: 它应该是:

CGSizeMake(UIScreen.mainScreen().bounds.size.width, CGFloat.max)

I'd say it's better practice to use the width of the view that the cell is directly contained in (the collectionView ), but that's just my personal opinion. 我会说最好使用单元格直接包含在其中的视图的宽度( collectionView ),但这只是我个人的观点。

Secondly, you need to enable AutoLayout. 其次,您需要启用自动版式。 Go to your Main.storyboard file and make sure Use Auto Layout is selected. 转到您的Main.storyboard文件,并确保已选中“ Use Auto Layout

启用自动版式

Now you need to add constraints . 现在您需要添加constraints (You can read more about AutoLayout and constraints here ) (您可以在此处阅读有关自动布局和约束的更多信息)

There are different ways to add constraints. 有多种添加约束的方法。 The easiest way is to control click a UI element and drag the mouse to the element you want to set a constraint to. 最简单的方法是控制单击UI元素,然后将鼠标拖动到要为其设置约束的元素。

You need to add the following constraints for your cell: 您需要为单元格添加以下约束:

ImageView.top = cell.top
ImageView.leading = cell.leading
ImageView.trailing = cell.trailing
ImageView.bottom = MyLabel.top + 8 (your padding)
MyLabel.leading = cell.leading
MyLabel.trailing = cell.trailing
MyLabel.bottom = cell.bottom

And these for your CollectionView 这些用于您的CollectionView

CollectionView.top = view.top
CollectionView.leading = view.leading
CollectionView.trailing = view.trailing
CollectionView.bottom = view.bottom

I've attached the project, modified with AutoLayout here below. 我已经附加了该项目,并在下面用AutoLayout对其进行了修改。

Modified project 修改项目

Edit: 编辑:

Approach 2 - without AutoLayout. 方法2-不使用自动版式。

This could also be achieved without using AutoLayout by manually updating the cell's label height in collectionView:willDisplayCell: . 在不使用AutoLayout的情况下,也可以通过在collectionView:willDisplayCell:手动更新单元格的标签高度来实现此collectionView:willDisplayCell: I'm sure there are better alternatives, I'd personally try AutoResizingMasks before this approach. 我敢肯定还有更好的选择,在此方法之前,我会亲自尝试使用AutoResizingMasks

Project without AutoLayout 没有自动布局的项目

extension String{ 扩展字符串{

func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat { func height(withConstrainedWidth width:CGFloat,字体:UIFont)-> CGFloat {

    let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)

    let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil)
    return ceil(boundingBox.height)
}}

Crate an String extension 创建一个字符串扩展名

extension String {
    func heightOfString(usingFont font: UIFont) -> CGFloat {
        let fontAttributes = [NSFontAttributeName: font]
        let size = self.size(attributes: fontAttributes)
        return size.height
    }
}

get the height of the string as follows 得到字符串的高度如下

let str = "Hello world"
let strHgt = str.heightOfString(usingFont: UIFont.systemFont(ofSize: 12))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM