将未知数量的行添加到“静态单元”UITableView
我有一个在Interface Builder中创build的6个部分都有不同数量的行的静态表。 我现在想要添加不同行数的第七部分。
首先,当我取消注释由Xcode插入的标准表格委托方法时,我在self.tableView.tableHeaderView = containerView; 在那里我添加了一个表头的标题。
更重要的是,我碰到了下面的代码
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 7; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if (section==6) { return 4; } else { return [super tableView:tableView numberOfRowsInSection:section]; } } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {/* if (indexPath.section == 6) { static NSString *CellIdentifier = @"cellWireless"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; // Configure the cell... return cell; }*/ return [super tableView:tableView cellForRowAtIndexPath:indexPath]; }
我如何正确地离开现有的部分,但添加一个与几个单元格?
要将dynamic单元格添加到静态单元格表中,您必须重写每个具有indexPath的UITableView委托方法。
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section -(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath -(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath -(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath -(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath -(NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
。
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { return NO; } -(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { return NO; } -(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { return UITableViewCellEditingStyleNone; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { int section = indexPath.section; // if dynamic section make all rows the same height as row 0 if (section == self.dynamicSection) { return [super tableView:tableView heightForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]]; } else { return [super tableView:tableView heightForRowAtIndexPath:indexPath]; } } - (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath { int section = indexPath.section; // if dynamic section make all rows the same indentation level as row 0 if (section == self.dynamicSection) { return [super tableView:tableView indentationLevelForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]]; } else { return [super tableView:tableView indentationLevelForRowAtIndexPath:indexPath]; } } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if (section == self.dynamicSection ) { return [self.dataListArray count]; } else { return [super tableView:tableView numberOfRowsInSection:section]; } } -(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath { int section = indexPath.section; int row = indexPath.row; if (section == self.dynamicSection) { // make dynamic row's cell static NSString *CellIdentifier = @"Dynamic Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; } cell.textLabel.text = [self.dataListArray objectAtIndex:row]; return cell; } else { return [super tableView:tableView cellForRowAtIndexPath:indexPath]; } }
只有一旦你有所有的方法重写将您的表开始工作。 对于任何引用静态部分,请参阅[super]。
Darren的回答给了我什么为我工作的想法,但是我没有去实现每一个tableView委托方法。 你真的只需要重写numberOfRowsInSection和cellForRowAtIndexPath。
首先,我在界面生成器中定义了一个静态表格,其中有4个部分,每部分2到4个单元格。 我希望第0,2和3部分是静态的,看起来和在IB中一样,但是我希望第1部分在每个单元格中具有自定义数量的行,并具有自定义显示,这是基于我所具有的值的数组。
在静态表的视图控制器中,覆盖为dynamic部分返回的单元格数量,但接受所有其他部分的默认值(它们将回退到IB值)。 对cellForRowAtIndexPath执行相同的操作,并返回除了第1部分以外的所有部分的[super]实现。
@implementation myMostlyStaticTableViewController @synthesize myFancyArray; - (NSInteger) tableView:(UITableView *) tableView numberOfRowsInSection:(NSInteger) section { if (section == 1) return [myFancyArray count]; // the number of rows in section 1 else return [super tableView:tableView numberOfRowsInSection:section]; } - (UITableViewCell *) tableView:(UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath *) indexPath { // for cells not in section 1, rely on the IB definition of the cell if (indexPath.section != 1) return [super tableView:tableView cellForRowAtIndexPath:indexPath]; // configure a task status cell for section 1 MyCustomTableViewCell *cell; cell = [tableView dequeueReusableCellWithIdentifier:@"myCustomCell"]; if (!cell) { // create a cell cell = [[MyCustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"myCustomCell"]; } cell.myCustomLabel.text = [myFancyArray objectAtIndex:indexPath.row]; return cell; } @end
当然,你需要一个自定义的单元格:
@implementation MyCustomTableViewCell - (UITableViewCell *) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { // initialize cell and add observers self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (!self) return self; self.clipsToBounds = YES; self.selectionStyle = UITableViewCellSelectionStyleNone; // configure up some interesting display properties inside the cell _label = [[UILabel alloc] initWithFrame:CGRectMake(20, 9, 147, 26)]; _label.font = [UIFont fontWithName:@"HelveticaNeue-Medium" size:17]; _label.textColor = [UIColor colorWithWhite:0.2 alpha:1]; [self.contentView addSubview:_label]; return self; } @end
我以为我会根据@ Darren的出色答案添加更新的答案。 大多数委托方法不是必需的。 所以,我只是添加了所需的。 如果您愿意,可以轻松添加自定义单元格,即使使用nib文件。 该图像显示了一个包含3个部分的静态表格。 最后一节是运行时dynamic的。 这非常方便。 这是在ios7顺便说一句。
#define DYNAMIC_SECTION 2 #import "MyTableViewController.h" @interface MyTableViewController () @property (strong, nonatomic)NSArray *myArray; @end @implementation MyTableViewController - (id)initWithCoder:(NSCoder *)aDecoder { if (self = [super initWithCoder:aDecoder]) { _myArray = @[@"ONE", @"TWO", @"THREE", @"FOUR"]; } return self; } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return [super numberOfSectionsInTableView:tableView]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if (section != DYNAMIC_SECTION) { return [super tableView:tableView numberOfRowsInSection:section]; } return [self.myArray count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.section != DYNAMIC_SECTION) { return [super tableView:tableView cellForRowAtIndexPath:indexPath]; } static NSString *id = @"MyCell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:id]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:id]; } cell.textLabel.text = self.myArray[indexPath.row]; return cell; } // required -(NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath { int section = indexPath.section; if (section == DYNAMIC_SECTION) { return [super tableView:tableView indentationLevelForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]]; } else { return [super tableView:tableView indentationLevelForRowAtIndexPath:indexPath]; } } // Not required - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { if (section != DYNAMIC_SECTION) { return [super tableView:tableView titleForHeaderInSection:section]; } return @"some title"; }
我将在Swift中发布答案,但它也应该在Objective-C中工作。
根据我的经验,在UITableViewController
重写这些方法已经足够了:
tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat tableView(tableView: UITableView, indentationLevelForRowAtIndexPath indexPath: NSIndexPath) -> Int
如果你想在你的表视图中有自定义的表格视图单元格,你也需要将子类的UITableViewCell
与nib一起打包,并将其注册到你的表格视图中。
我的整个控制器看起来像这样:
var data = ["Ahoj", "Hola", "Hello"] override func viewDidLoad() { super.viewDidLoad() tableView.registerNib(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "reuseIdentifier") } // MARK: - Table view data source override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { if section == 1 { return data.count } return super.tableView(tableView, numberOfRowsInSection: section) } override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { if indexPath.section == 1 { let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) as! CustomCell cell.titleLabel.text = data[indexPath.row] return cell } return super.tableView(tableView, cellForRowAtIndexPath: indexPath) } override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return 44 } override func tableView(tableView: UITableView, indentationLevelForRowAtIndexPath indexPath: NSIndexPath) -> Int { return 0 } override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { tableView.deselectRowAtIndexPath(indexPath, animated: true) if indexPath.section == 1 { print(data[indexPath.row]) } } @IBAction func addItem() { data.append("Item \(data.count)") tableView.beginUpdates() tableView.insertRowsAtIndexPaths([NSIndexPath(forRow: data.count - 1, inSection: 1)], withRowAnimation: .Left) tableView.endUpdates() } @IBAction func removeItem() { if data.count > 0 { data.removeLast() tableView.beginUpdates() tableView.deleteRowsAtIndexPaths([NSIndexPath(forRow: data.count, inSection: 1)], withRowAnimation: .Left) tableView.endUpdates() } }
我想你将不得不使你的UITableViewdynamic。 因为你有一个“未知”的行数,你很可能将委托方法设置为这样的:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [someArray count]; }
我发现我觉得很有意思,比“评论”更值得回答。 我有这个静态tableView与dynamic行工作,然后停止工作。 原因很简单。 我以前有过
[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]
后来决定我想/需要一个自定义单元格,我将在我的StoryBoard中devise,并只设置网点到我的UITableView子类。 所以我使用了另一种技术
[super tableView:tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:indexPath.section]];
这里的问题似乎是这个单元格被重用,因此你一次只能看到一个单元格。 有时候你什么也看不到,他们都是空的! 如果你滚动,你会看到其他细胞马上出现然后消失(更像闪烁!)。
这让我非常吃惊,直到我意识到什么是(im)可能。 此外,不要试图做
[super.tableView dequeueReusableCellWithIdentifier:CellIdentifier]
因为正如其他人所说,这总是返回nil
在一个静态tableView。
—
所以我不确定该怎么做。 我想我会使用“静态原型”路线,其中包括
- 使用一个原型表视图与细胞标识符像“31”第3行1.我可以做一些像
NSString * identifier = [NSString stringWithFormat:@“%d%d”,indexPath.section,indexPath.row]; cell = [tableView dequeueReusableCellWithIdentifier:identifier];
- 使用原型单元格以及标题。 我使用
"Cell1-Header"
作为部分1头部的Cell Identifier,然后有类似的东西
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { NSString * identifier = [NSString stringWithFormat:@“Cell%d-Header”,section]; UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:identifier]; 返回cell.contentView; }
这里要做的基本的事情是,你总是可以从一个静态的tableView开始,但是当你意识到你需要dynamic的东西的时候,把它换成Prototype(它会保留你的行,尽pipe我不记得它是什么)与部分!)并且使用这个KISS技术。
我想我find了一个更好更容易的解决scheme,在IB中使用“fantom”部分或行。
如果知道在第7节中可以使用的单元格的最大数目(可以说10),那么当在IB中configuration第7节时,应该将行数设置为10。
你不必强制使用所有的10行,这可以通过设置
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section.
例如,如果在部分== 6(实际上是第7部分)时返回5,则只显示5行。
我承认在绝对意义上这不是dynamic的,但也许可以解决大部分情况。