表格视图单元格高度
Posted
技术标签:
【中文标题】表格视图单元格高度【英文标题】:Table View Cell Height 【发布时间】:2017-07-27 08:18:17 【问题描述】:我的表格视图中有多个单元格;例如猫细胞、狗细胞、鸡细胞。在 Cat Cell 中,我有两个视图:图形视图和图像视图。
如果图形视图被隐藏而图像视图可见,那么我想将单元格高度设置为 200,在相反的情况下设置为 350。
我将如何实现这一目标?我正在表格视图的heightForRowAt
委托方法中注册我的 nib 文件,但我尝试了不同的方法无济于事。这是我单元格中的两个视图:
@property (weak, nonatomic) IBOutlet UIView *imagesView;
@property (weak, nonatomic) IBOutlet UIView *graphView;
...这是我的heightForRowAt
方法:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
TrainingImageCell *cell = (TrainingImageCell*)[self.tableView dequeueReusableCellWithIdentifier:@"TrainingImageCell"];
if (cell.isGraphViewOnTop == YES)
return 350;
else
return 200;
return 200;
【问题讨论】:
为什么要在 heightForRowAt 中注册 nib 文件。您正在注册新单元格,因此无法访问现有单元格。如果您希望它以您的风格工作,而不是在 IndexPath 处为行注册高度的新单元格,您可以使用 indexPath 作为 TrainingImageCell currentCell = (TrainingImageCell)[tableView cellForRowAtIndexPath:indexPath]; 访问现有单元格并检查属性。 在 heightForRowAtIndexPath 中使用 dequeueReusableCellWithIdentifier 方法是无效的。因为首先调用 heightForRowAtIndexPath 方法,然后调用 cellForRowAtIndexPath 方法。如果你给我看一些 cellForRowAtIndexPath 方法的代码,我可以帮助你吗? 我得到了那部分@YagneshDobariya 我必须像答案中提到的那样使用它,但我现在遇到了重新加载表格视图的问题。我已经定义了一个布尔属性 isShowingGraphView 并在注册笔尖后在 cellForRowAt 中隐藏和取消隐藏我的视图。我在 heightforRowAt 中调用此属性并反对 bool 返回高度,但如果我调用 reload TableView 整个视图就会消失。 @UsamabinAttique 你为什么使用 TrainingImageCell cell = (TrainingImageCell)[self.tableView dequeueReusableCellWithIdentifier:@"TrainingImageCell"];在 heightForRowAtIndexPath 中。直接使用与在 cellForRowAtIndexPath 中设置“isGraphViewOnTop”相同的条件。我认为问题应该在这里。 【参考方案1】:您需要访问tableView
中已有的内容,而不是启动一个新单元格。
而不是
TrainingImageCell *cell = (TrainingImageCell*)[self.tableView dequeueReusableCellWithIdentifier:@"TrainingImageCell"];
做
TrainingImageCell *currentCell = (TrainingImageCell*)[tableView cellForRowAtIndexPath:indexPath];
然后看看房产。
编辑: 看看我们的冗长讨论,这里有一个非常可靠的例子,说明您可以在 Swift 中使用一种方法。
import UIKit
class RightAlignedCell: UITableViewCell
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var subLabel: UILabel!
// Your boolean property you would like to map
var randomBool: Bool = false
class RightAlignedTableViewController: UIViewController
// This is just an example for the dataSource, you should have this somewhere already
lazy var dataSource: [Bool] =
var dataSource: [Bool] = []
for index in 0..<10
dataSource.append(index % 2 == 0)
return dataSource
()
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad()
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
override func viewWillAppear(_ animated: Bool)
super.viewWillAppear(animated)
tableView.reloadData()
extension RightAlignedTableViewController: UITableViewDelegate
extension RightAlignedTableViewController: UITableViewDataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return 10
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
// Take a look in the !!!dataSource!!!, what is value for isHidden
let isHidden = self.dataSource[indexPath.row]
// return the right height
return isHidden ? 60 : 100
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell: RightAlignedCell = tableView.dequeueReusableCell(withIdentifier: "RightAlignedCell", for: indexPath) as! RightAlignedCell
cell.titleLabel.text = "Something"
cell.subLabel.text = "Nothing"
cell.randomBool = self.dataSource[indexPath.row]
return cell
【讨论】:
是的,我可以访问这样的属性,我想做的是 if (currentCell.graphView setHidden:YES) return 350; 其他 返回 200;但它给了我一个错误, ps isGraphViewOnTop 只是一个布尔值,所以如果设置为是或否,它本身不知道该怎么做。我在某处的函数中使用它。请原谅我的无知,但这是实现我想要实现的目标的正确方法吗? 不,这不是正确的方法。在这里,您应该做的就是查看标志是否为true
或false
并返回一个值。做某处-> [currentCell.graphView setHidden:YES]
然后重新加载tableview([tableView realodData]),所以会再次询问高度。
我在我的 cellForRowAt 中调用 ([tableView realodData]) 但问题是我的整个视图在我取消注释时都会消失。我还尝试了使用 0,0 的 reloadRowsatindexpath,因为此单元格仅在 indexPath =0 时执行,但如果我这样做,应用程序将崩溃。
不要从cellForRowAtIndexPath
调用[tableView reload]
,这会导致无限循环。你在哪里设置[currentCell.graphView setHidden:YES]
?
我在类中定义了一个 bool 属性 isShowingGraph,我正在针对 cellForRowAt 中的 bool 值设置 setHidden。我正在使用重用标识符注册单元格。如果我使用您规定的方法,我应该在哪里重新加载数据?因为如果我在 heightforRowAt 中这样做,整个视图就会消失。【参考方案2】:
为什么要在 heightForRowAt 中注册 nib 文件。您正在注册新单元,因此无法访问现有单元。如果您希望它以您的风格工作,而不是在 IndexPath 处为行注册新的高度单元格,您可以使用 indexPath as 访问现有单元格
TrainingImageCell *currentCell = (TrainingImageCell*)[tableView cellForRowAtIndexPath:indexPath];
并访问检查属性。
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
TrainingImageCell *currentCell = (TrainingImageCell*)[tableView cellForRowAtIndexPath:indexPath];
if (cell.isGraphViewOnTop == YES)
return 350;
return 200;
【讨论】:
是的,我可以访问这样的属性,我想做的是 if (currentCell.graphView setHidden:YES) return 350; 其他 返回 200;但它给了我一个错误, ps isGraphViewOnTop 只是一个布尔值,所以如果设置为是或否,它本身不知道该怎么做。我在某处的函数中使用它。请原谅我的无知,但这是实现我想要实现的目标的正确方法吗? 你在哪里使用它??您必须在 cellForRowAtIndexPath 中将标志值设置为 isGraphViewOnTop,然后才能在此处使用。 您可以为 Row 的高度设置适当的 AutoLayout 和 UIAutomatic Dimension。 如果你想根据 Graph View 是否可见来操作 tableVieCells 的高度,我建议在你的单元格中使用 UIStackView。它只对可见的组件进行管理。检查此链接atomicbird.com/blog/uistackview-table-cells。 我在我的单元格类中的一个函数中使用它,当我使用 UIView transitionWithView 并没有在 cellForRowAt 中的任何位置设置标志时,我正在翻转图形视图和图像视图。 ps 该项目非常庞大,并且在单元格中调用了很多功能,因此目前使用 UIStackView 走这条路可能不是最好的选择。【参考方案3】:如果你dequeueReusableCellWithIdentifier
你只是得到一个新单元格,它不会有任何数据来检查isGraphViewOnTop
我的建议是返回UITableViewAutomaticDimension
并使用常量设置单元格视图,这样当元素被隐藏时,单元格的大小会更小。
【讨论】:
以上是关于表格视图单元格高度的主要内容,如果未能解决你的问题,请参考以下文章