ios 使用静态单元格隐藏 UITableView 中的单元格 - 并且没有自动布局崩溃
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18939879/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hide cells in a UITableView with static cells - and no autolayout crash
提问by ConfusedNoob
I have a table view form created using Static Cells in IB/Storyboard. However, I need to hide some of the cells at runtime depending on certain conditions.
我有一个使用 IB/Storyboard 中的静态单元格创建的表视图表单。但是,我需要根据某些条件在运行时隐藏一些单元格。
I have found a few 'answers; to this question on SO, e.g.
我找到了一些“答案”;关于SO的这个问题,例如
UITableView set to static cells. Is it possible to hide some of the cells programmatically?
UITableView 设置为静态单元格。是否可以以编程方式隐藏某些单元格?
.. and they focus on setting the height of the cell / row to 0. This is great, except I now get exceptions from AutoLayout because the constraints can't be satisfied. How do I get around this last problem? Can I temporarily disable Auto-Layout for a subview? Is there a better way to be doing this in iOS7?
.. 他们专注于将单元格/行的高度设置为 0。这很好,除了我现在从 AutoLayout 获得异常,因为无法满足约束。我如何解决最后一个问题?我可以暂时禁用子视图的自动布局吗?有没有更好的方法在 iOS7 中做到这一点?
采纳答案by ConfusedNoob
I found the best way to do this is to simply handle the numberOfRowsInSection, cellForRowAtIndexPath and heightForRowAtIndexPath to selectively drop certain rows. Here's a 'hardcoded' example for my scenario, you could do something a little smarter to intelligently remove certain cells rather than hard code it like this, but this was easiest for my simple scenario.
我发现这样做是简单地处理numberOfRowsInSection,和的cellForRowAtIndexPath到heightForRowAtIndexPath选择性丢弃某些行的最好方式。这是我的场景的“硬编码”示例,您可以做一些更聪明的事情来智能地删除某些单元格,而不是像这样对其进行硬编码,但这对于我的简单场景来说是最简单的。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
if (indexPath.section == 0 && hideStuff) {
cell = self.cellIWantToShow;
}
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGFloat height = [super tableView:tableView heightForRowAtIndexPath:indexPath];
if (indexPath.section == 0 && hideStuff) {
height = [super tableView:tableView heightForRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:0]];
}
return height;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger count = [super tableView:tableView numberOfRowsInSection:section];
if (section == 0 && hideStuff) {
count -= hiddenCells.count;
}
return count;
}
回答by fede1608
Hide the cells on the storyboard and set the height to 0:
隐藏故事板上的单元格并将高度设置为 0:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
let cell: UITableViewCell = super.tableView(tableView, cellForRowAtIndexPath:indexPath)
return cell.hidden ? 0 : super.tableView(tableView, heightForRowAtIndexPath:indexPath)
}
}
回答by otello
The simplest way is to change height of sections and rows. It works for me.
最简单的方法是更改部分和行的高度。这个对我有用。
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
if (section == 3) {
return 0;
} else {
return [super tableView:tableView heightForHeaderInSection:section];
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
if (indexPath.section == 3) {
cell.hidden = YES;
return 0;
} else {
cell.hidden = NO;
return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}
}
回答by Ian Howson
If you ensure there's no constraint touching the bottom edge of the cell, autolayout shouldn't barf (tested on iOS 6.0, 6.1, 7.0). You'll still 'anchor' to the top edge and have to pin the heights. (You can do the reverse and anchor to the bottom, of course.)
如果您确保没有约束接触单元格的底部边缘,则自动布局不应该停止(在 iOS 6.0、6.1、7.0 上测试)。您仍将“锚定”到顶部边缘,并且必须固定高度。(当然,您可以反向操作并锚定到底部。)
If your layout depends on both the top and bottom edge positions, it may be possible to programmatically remove the constraints (they're just objects, after all).
如果您的布局取决于顶部和底部边缘位置,则可以通过编程方式删除约束(毕竟它们只是对象)。
回答by GayleDDS
The kosher way to do this is to use dynamic cells, setting the row height to 0 is a hack. Static cells are very convenient but limited in functionality.
这样做的犹太洁食方法是使用动态单元格,将行高设置为 0 是一种技巧。静态单元非常方便,但功能有限。
回答by Andreas
I managed to avoid exceptions from Auto Layout by first removing the constraints on the cell's contentView
programmatically in viewDidLoad
, and then setting that cell's height to 0 in heightForRowAtIndexPath
.
我设法通过首先以contentView
编程方式删除单元格in的约束viewDidLoad
,然后将该单元格的高度设置为 0 in来避免自动布局的异常heightForRowAtIndexPath
。
回答by Fiser33
I have found a way that allows you even row animations and is working on iOS 8.3. All you need is to implement the tableView:numberOfRowsInSection:data source method and then add/delete row by UITableView methods insertRowsAtIndexPaths:withRowAnimation:and deleteRowsAtIndexPaths:withRowAnimation:.
我找到了一种方法,甚至可以让您行动画,并且正在 iOS 8.3 上工作。您只需要实现tableView:numberOfRowsInSection:数据源方法,然后通过 UITableView 方法insertRowsAtIndexPaths:withRowAnimation:和deleteRowsAtIndexPaths:withRowAnimation:添加/删除行 。
Here is example of hiding exact row based on UISwitchstate:
以下是基于UISwitch状态隐藏确切行的示例:
- (IBAction)alowNotif:(id)sender {
UISwitch *sw = (UISwitch*)sender;
NSIndexPath *index = [NSIndexPath indexPathForRow:5 inSection:0];
if ([sw isOn]) {
[self.tableView insertRowsAtIndexPaths:@[index] withRowAnimation:UITableViewRowAnimationAutomatic];
}
else {
[self.tableView deleteRowsAtIndexPaths:@[index] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (![notifications isOn]) {
return 5;
}
return 6;
}
As was mentioned above by @algal, numberOfRowInSection:is still UITableViewDataSourcemethod, so one does not simply know how long its gonna work.
正如@algal 上面提到的,numberOfRowInSection:仍然是UITableViewDataSource方法,所以人们不知道它会工作多长时间。
回答by nejcb1
The best way for me was to modify numberOfRowsInSection method. I removed datasource which i did not want to display. Best solution for me, because everything is in one function.
对我来说最好的方法是修改 numberOfRowsInSection 方法。我删除了不想显示的数据源。对我来说最好的解决方案,因为一切都在一个功能中。
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if(section==0) {
NSUInteger productCount = _products.count;
for(loop trough your data) {
if(your condition is true)
productCount--;
}
}
return productCount;
} else
return self.groups.count;
}
回答by RickJansen
Implemented this too, for a tableview in a StoryBoard. My cells are embedded in sections with a header, represented by that blue cube in xcode6 IB. Indeed if you implement heightForHeaderInSection, heightForFooterInSection and titleForHeaderInSection,titleForFooterInSection you can access the headers when the table is displayed, and return 0.0 and nil respectively, and return 0 for numberOfRowsInSection.
也为 StoryBoard 中的 tableview 实现了这一点。我的单元格嵌入在带有标题的部分中,由 xcode6 IB 中的蓝色立方体表示。实际上,如果您实现 heightForHeaderInSection、heightForFooterInSection 和 titleForHeaderInSection、titleForFooterInSection,您可以在显示表格时访问标题,并分别返回 0.0 和 nil,并为 numberOfRowsInSection 返回 0。
Basically it all works fine, except that for every cell hidden a ca. 10 pixel high vertical space remains for every cell (section) you hide. Any idea what that could be?
基本上一切正常,除了每个单元格都隐藏了一个 ca。您隐藏的每个单元格(部分)保留 10 像素高的垂直空间。知道那可能是什么吗?