Reputation: 1609
I'm making an app with text posts, but I realize that a lot of the text posts will be really long so I added a show all and less button, but when you press it sometimes the cell disappears and you scroll up and it skips to the middle of the cell. Here is what it looks like since it's hard to explain...
I believe this happens due to something with this...
table.rowHeight = UITableViewAutomaticDimension
but it's necessary to make the cells to display custom amounts of text. But anyway here is the code.
Here is the actual function that makes it happen...
var showingMore = [Bool]()
func showAllAndLess(sender: AnyObject) {
var buttonPosition: CGPoint = sender.convertPoint(CGPointZero, toView: self.table)
var indexPath: NSIndexPath = self.table.indexPathForRowAtPoint(buttonPosition)!
if showingMore[indexPath.row] {
sender.setTitle("Show Less", forState: .Normal)
} else {
sender.setTitle("Show All", forState: .Normal)
}
showingMore[indexPath.row] = !showingMore[indexPath.row]
table.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None)
}
Here is the code in the cellForRowAtIndexPath method...
showingMore.append(false)
postCellObj.showAllAndLessButton.hidden = true
if showingMore[indexPath.row] {
postCellObj.message.text = messageString
postCellObj.showAllAndLessButton.setTitle("Show Less", forState: .Normal)
postCellObj.showAllAndLessButton.hidden = false
println("Showing Less")
}
else if count(messageString) >= 800 {
var messageNs = messageString as NSString
var messageFinal = messageNs.substringWithRange(NSRange(location: 0, length: 800))
postCellObj.message.text = messageFinal as String + "..."
postCellObj.showAllAndLessButton.setTitle("Show All", forState: .Normal)
postCellObj.showAllAndLessButton.hidden = false
} else {
postCellObj.message.text = messageString
}
}
Thanks for reading! I hope I gave enough information. And if you need more just say something. (:
P.S. the variable "messageString" is the message text.
Upvotes: 0
Views: 415
Reputation: 10204
This is a known issue. UITableView
dumps previously calculated cell heights if you modify data source (add or remove rows). This is no problem when you scroll down, but as soon as you start scrolling up table view starts jumping.
The solution is to cache cell heights yourself. More information here: https://github.com/smileyborg/TableViewCellWithAutoLayoutiOS8/issues/17
Sometimes jumpy scrolling can be caused by incorrect estimation of cell height (if it is off by an order of magnitude). In this case you can adjust your estimate according to the amount of text (no need to be very precise, though).
Here's a way to estimate the text height:
class func estimatedHeightForText(text: String, andWidth width: CGFloat) -> CGFloat {
let paragraphCount = (text.characters.split { $0 == "\n" }.map { String($0) }).count + 1
// 7 is approximate width of character in points
let charsPerLine = width / 7
let lineCount = text.characters.count / Int(round(charsPerLine)) + 1
// 14 is approximate height of line
let estimatedHeight = 14 * CGFloat(max(lineCount, paragraphCount))
return estimatedHeight
}
Upvotes: 1