2015-07-11 97 views
0

我正在嘗試創建一個自定義的UITableViewCell,並且存在具有適當高度的單元格框架問題。這很麻煩,因爲iPhone 4s/5s運行iOS 8.4的單元尺寸正確,但運行相同操作系統的iPhone 6/6 +的單元尺寸卻不正確。UITableViewCell高度不正確,sizeToFit尺寸不正確

混沌發生在messageLabel上,呼叫sizeToFit。有些標籤幾乎看起來在下面有額外的空白行,但顯然沒有單元格所顯示的那麼高。

下面是自定義單元格。看起來會引起麻煩的標籤是messageLabel。要查看幀的標籤,let borders = true

// 
// NotesTableViewCell.swift 
// urchin 
// 
// Created by Ethan Look on 6/17/15. 
// Copyright (c) 2015 Tidepool. All rights reserved. 
// 

import Foundation 
import UIKit 

let noteCellHeight: CGFloat = 128 
let noteCellInset: CGFloat = 16 
let labelSpacing: CGFloat = 6 

class NoteCell: UITableViewCell { 

    let borders = false 

    var cellHeight: CGFloat = CGFloat() 

    let usernameLabel: UILabel = UILabel() 
    let timedateLabel: UILabel = UILabel() 
    var messageLabel: UILabel = UILabel() 

    func configureWithNote(note: Note) { 

     usernameLabel.text = note.user!.fullName 
     usernameLabel.font = UIFont(name: "OpenSans-Bold", size: 17.5)! 
     usernameLabel.textColor = UIColor.blackColor() 
     usernameLabel.sizeToFit() 
     let usernameX = noteCellInset 
     let usernameY = noteCellInset 
     usernameLabel.frame.origin = CGPoint(x: usernameX, y: usernameY) 

     let dateFormatter = NSDateFormatter() 
     dateFormatter.dateFormat = "EEEE M.d.yy h:mm a" 
     var dateString = dateFormatter.stringFromDate(note.timestamp) 
     dateString = dateString.stringByReplacingOccurrencesOfString("PM", withString: "pm", options: NSStringCompareOptions.LiteralSearch, range: nil) 
     dateString = dateString.stringByReplacingOccurrencesOfString("AM", withString: "am", options: NSStringCompareOptions.LiteralSearch, range: nil) 
     timedateLabel.text = dateString 
     timedateLabel.font = UIFont(name: "OpenSans", size: 12.5)! 
     timedateLabel.textColor = UIColor.blackColor() 
     timedateLabel.sizeToFit() 
     let timedateX = contentView.frame.width - (noteCellInset + timedateLabel.frame.width) 
     let timedateY = usernameLabel.frame.midY - timedateLabel.frame.height/2 
     timedateLabel.frame.origin = CGPoint(x: timedateX, y: timedateY) 

     messageLabel.frame.size = CGSize(width: contentView.frame.width - 2 * noteCellInset, height: CGFloat.max) 
     let hashtagBolder = HashtagBolder() 
     let attributedText = hashtagBolder.boldHashtags(note.messagetext) 
     messageLabel.attributedText = attributedText 
     messageLabel.adjustsFontSizeToFitWidth = false 
     messageLabel.lineBreakMode = NSLineBreakMode.ByWordWrapping 
     messageLabel.numberOfLines = 0 
     messageLabel.sizeToFit() 
     let messageX = noteCellInset 
     let messageY = usernameLabel.frame.maxY + 2 * labelSpacing 
     messageLabel.frame.origin = CGPoint(x: messageX, y: messageY) 

     contentView.addSubview(usernameLabel) 
     contentView.addSubview(timedateLabel) 
     contentView.addSubview(messageLabel) 

     cellHeight = noteCellInset + usernameLabel.frame.height + 2 * labelSpacing + messageLabel.frame.height + noteCellInset 

     if (borders) { 
      usernameLabel.layer.borderWidth = 1 
      usernameLabel.layer.borderColor = UIColor.redColor().CGColor 

      timedateLabel.layer.borderWidth = 1 
      timedateLabel.layer.borderColor = UIColor.redColor().CGColor 

      messageLabel.layer.borderWidth = 1 
      messageLabel.layer.borderColor = UIColor.redColor().CGColor 

      self.contentView.layer.borderWidth = 1 
      self.contentView.layer.borderColor = UIColor.blueColor().CGColor 
     } 

     self.contentView.frame.size = CGSize(width: self.contentView.frame.width, height: cellHeight) 
    } 
} 

而且heightForRowAtIndexPath

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { 
     let cell = NoteCell(style: .Default, reuseIdentifier: nil) 
     cell.configureWithNote(notes[indexPath.row]) 
     return cell.cellHeight 
} 

該項目是開源的,on Github,可以隨意克隆庫,並檢查了所有的代碼自己。

謝謝!

回答

0

而是在heightForRowAtIndexPath:創建一個全新的細胞,我簡單地創建確定單元格高度的UI元素(usernameLabel和messageLabel),大小它們,然後做一個簡單:

檢查它計算以確定細胞高度。

通過這樣做,我從來沒有創建一個新的細胞,後來出隊。

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { 

    let usernameLabel = UILabel(frame: CGRectZero) 
    usernameLabel.font = UIFont(name: "OpenSans-Bold", size: 17.5)! 
    usernameLabel.text = notes[indexPath.row].user!.fullName 
    usernameLabel.sizeToFit() 

    let messageLabel = UILabel(frame: CGRect(x: 0, y: 0, width: self.view.frame.width - 2*noteCellInset, height: CGFloat.max)) 
    let hashtagBolder = HashtagBolder() 
    let attributedText = hashtagBolder.boldHashtags(notes[indexPath.row].messagetext) 
    messageLabel.attributedText = attributedText 
    messageLabel.adjustsFontSizeToFitWidth = false 
    messageLabel.lineBreakMode = NSLineBreakMode.ByWordWrapping 
    messageLabel.numberOfLines = 0 
    messageLabel.sizeToFit() 

    let cellHeight = noteCellInset + usernameLabel.frame.height + 2 * labelSpacing + messageLabel.frame.height + noteCellInset 

    return cellHeight 
} 
0

不幸的是,你不能這樣做,因爲首先調用tableView(_:heightForRowAtIndexPath),並且返回的值用於創建將在tableView(_:cellForRowAtIndexPath)中出隊的單元格。單元格不能設置其自己的大小,因爲在它可以這樣做的時候(例如awakeFromNibprepareForResuse),表格視圖將已經具有它的高度值。我已經使用了一些令人吃驚的解決方法,但是使用自定義表格視圖單元更容易。與sizeToFit適當 http://www.appcoda.com/self-sizing-cells/