我有一个包含一些stackviews的单元格,底部stackView包含一个textView和一个自定义分隔符。
我想创建一个选项,当用户点击单元格时,它会显示点击文本视图的全文,因此该单元格中的最大行数为0,其他单元格中的最大行数应为3.
我使用了这个教程http://www.roostersoftstudios.com/2011/04/14/iphone-uitableview-with-animated-expanding-cells/,我修改了一下,我的代码:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(iden_tableViewCell4) as! TableViewCell4
if let selectedCellIP = selectedIndexPath {
if indexPath == selectedCellIP {
cell.textTextVIew.textContainer.maximumNumberOfLines = 0
}
else {
cell.textTextVIew.textContainer.maximumNumberOfLines = textVIewMaxNumberOfLines
}
}
else {
cell.textTextVIew.textContainer.maximumNumberOfLines = textVIewMaxNumberOfLines
}
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
//The user is selecting the cell which is currently expanded
//we want to minimize it back
if selectedIndexPath == indexPath {
selectedIndexPath = nil
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
return
}
//First we check if a cell is already expanded.
//If it is we want to minimize make sure it is reloaded to minimize it back
if let selIndexPath = selectedIndexPath {
let previousPath = selIndexPath
selectedIndexPath = indexPath
tableView.reloadRowsAtIndexPaths([previousPath], withRowAnimation: .Fade)
}
//Finally set the selected index to the new selection and reload it to expand
selectedIndexPath = indexPath
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
}
在我设置的viewDidLoad
中
tableView.estimatedRowHeight = 160
tableView.rowHeight = UITableViewAutomaticDimension
扩展和收缩效果很好,但其他单元格的textView高度有一个奇怪的行为。当第一个单元格被扩展时,我向下滚动,最后一个单元格也被扩展,而且不应该扩展。
答案 0 :(得分:0)
使用个人选择索引是危险的事情。您不仅可能会错过didSelectRowAtIndexPath
中的角落情况,也不可能适用于多种选择
您应该将单元格扩展/压缩通知拆分为2个不同的块(无需跟踪selectedIndexPath
,更强大的代码):
<强>展开强>
override func tableView(_ tableView: UITableView,
didSelectRowAt indexPath: IndexPath) {
self.reloadRowsAtIndexPaths(tableView,
indexPath:indexPath)
}
<强>合同强>
override func tableView(_ tableView: UITableView,
didDeselectRowAt indexPath: IndexPath) {
self.reloadRowsAtIndexPaths(tableView,
indexPath:indexPath)
}
selectRowAtIndexPath
会破坏选择 这可以防止didDeselectRowAtIndexPath
被调用。
解决方法是缓存整个选择,而不是单个索引,并在重新加载后恢复此类选择。
完整代码:
注意维护cacheSelectedRows
的时间和方式。这使用普通UITableViewCell
。它所需要的只是reuseIdentifier
。
class TableViewController: UITableViewController {
var cacheSelectedRows:[IndexPath]? = nil
override func viewDidLoad() {
super.viewDidLoad()
tableView.estimatedRowHeight = 160
tableView.rowHeight = UITableViewAutomaticDimension
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 8
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
if let textLabel = cell.textLabel {
textLabel.backgroundColor = UIColor.clear
textLabel.numberOfLines = 1
if let cacheSelectedRows = cacheSelectedRows {
textLabel.numberOfLines = (cacheSelectedRows.contains(indexPath)) ? 0 : 1
}
textLabel.text = "\(1 + indexPath.row), Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
}
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.reloadRowsAtIndexPaths(tableView, indexPath:indexPath)
}
override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
self.reloadRowsAtIndexPaths(tableView, indexPath:indexPath)
}
func reloadRowsAtIndexPaths(_ tableView: UITableView, indexPath: IndexPath) {
cacheSelectedRows = tableView.indexPathsForSelectedRows
tableView.reloadRows(at: [indexPath], with: .fade)
// Restore selection
if let cacheSelectedRows = cacheSelectedRows {
for path in cacheSelectedRows {
self.tableView.selectRow(at: path, animated: false, scrollPosition: .none)
}
}
}
}
<强>演示强>
►在GitHub上找到此解决方案,并在Swift Recipes上找到其他详细信息。
答案 1 :(得分:0)
我没有找到答案,为什么发生了textView和单元格高度的奇怪行为,但我有解决方案。
所以看起来tableView.estimatedRowHeight = 160
和tableView.rowHeight = UITableViewAutomaticDimension
并不尊重textView所有单元格的最大行数。 cellForRow工作正常,它设置了限制,但行高有时会扩展,有时会收缩。
所以我从StackView中解开了textView和底部分隔符,用Label替换了TextView并设置了autolayaut约束。现在它工作正常,没有奇怪的行为。