2015-12-14 4 views
10

Я пытаюсь настроить высоту ячейки изменить размер, чтобы соответствовать текст 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) 
    } 

Любые предложения, что делать здесь? Должен ли я сделать это по-другому? Пожалуйста, мне нужна помощь .. Проблема в том, что текст UILabel установлен в cellForItemAtIndexPath, а items - это массив для строк.

Это мой файл проекта, если кто-то смотреть, чтобы взглянуть на него: http://www.filedropper.com/test_37

+0

Вы задали себя как делегат коллекцииView? Кроме того, это должно быть 'return label.frame.size.height' в функции' heightForLabel' – mbo42

+0

@ mbo42 - Да, все еще не работает. –

+0

Вызывается функция? Какие результаты вы получаете? Btw, в 'cellForItemAtIndexPath' вам не нужно изменять кадр ячейки. – mbo42

ответ

2

Вы можете сделать это так, но я реализовал его по-разному. Вот пример кода, который вы можете сделать.

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)") 
+0

Я получаю это на выходе: http://s23.postimg.org/ydrqqcutn/Screen_Shot_2015_12_14_at_10_27_08.png - Но как установить высоту метки? –

+1

Вам нужно рассчитать его при перезагрузке вашего стола, так что вы можете использовать его в 'heightForRowAtIndexPath' –

+0

Ох, как? Я не понимаю это. –

4

Почему бы не попробовать это в ObjC

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

Это даст CGRect. Получите высоту от нее. задайте размер шрифта и т. д. в параметре атрибутов.

UPDATE

Вместо этого

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

Используйте этого

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

Надеется, что это помогает

+0

и где я могу это использовать? –

+0

Это тоже не сработало. Http://s17.postimg.org/6t42d2zzj/Simulator_Screen_Shot_14_Dec_2015_10_54_55.png –

+0

Добавлена ​​ссылка на мой проект, если вы хотите посмотреть на него: http://www.filedropper.com/test_37 –

0

Попробуйте это ...

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; 
0

Я взглянул на ваш код, и я смог его решить.

Во-первых, по линии 71 в вашем ViewController классе:

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

Вы случайно установили CGFloat.max как ширина и ширину, как высота. Оно должно быть:

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

Я бы сказал, что это лучше, рекомендуется использовать ширину зрения, что клетка непосредственно содержится в (в collectionView), но это только мое личное мнение.

Во-вторых, вам необходимо включить AutoLayout. Перейдите в свой Main.storyboard файл и убедитесь, что выбрано Use Auto Layout.

Enable AutoLayout

Теперь вам нужно добавить constraints. (Вы можете узнать больше об AutoLayout и ограничениях here)

Существуют различные способы добавления ограничений. Самый простой способ - это щелкнуть элемент пользовательского интерфейса и перетащить мышь на элемент, которому вы хотите установить ограничение.

Вам необходимо добавить следующие ограничения для ячейки:

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 

И это для CollectionView

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

Я приложил проект, модифицированную AutoLayout здесь ниже.

Modified project

Edit:

подход 2 - без AutoLayout.

Этого также можно достичь без использования AutoLayout, вручную обновив высоту ярлыка ячейки в collectionView:willDisplayCell:. Я уверен, что есть лучшие альтернативы, я лично попробую AutoResizingMasks до этого подхода.

Project without AutoLayout

+0

Хорошая работа! Вопросы; Можете ли вы это сделать без использования автоматического макета? Потому что у меня есть приложение, сделанное без автоматической компоновки. –

+0

Я думаю, вы могли вручную установить рамки для ImageView и MyLabel после выполнения вычислений. Обратите внимание, что вам не нужно реализовывать AutoLayout для всех представлений только потому, что вы отметили этот флажок. Вы можете выбрать именно это для этого ViewController. – mbo42

+0

Можете ли вы также представить пример проекта для этого решения без автоматического макета? Это было бы очень полезно, поскольку я никогда не использовал Auto Layout раньше :) –

1

Я создаю этот метод для получения высоты этикетки. Вы должны предоставить статическую ширину этикетки и шрифт этикетки

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 
} 
0

расширения Строка {

FUNC высоты (withConstrainedWidth ширина: 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) 
}} 
0

Crate ап Расширение строки

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

получить высоту строки следующим образом:

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