以编程方式向UITableView添加单元格

12

我最近才开始为 iPhone 编程,正在制作一个连接到数据库并获取一组行名称并将它们显示出来的应用程序。当选中时,行的背景颜色会改变,即您可以进行多次选择,并且它们的颜色都不同。因此,我毫无问题地从服务器获取了 XML 并创建了一个 UITableView(表格视图) 来显示单元格。但是,我不知道如何将单元格添加到表格中。我查看了 insertRowsAtIndexPaths(插入指定位置的行) 但是我不确定该如何使用它?据我所知,insertRowsAtIndexPaths 接受两个参数:

一个包含单元格应该在哪一行及哪个部分的 NSArray(数组)。问题在于我的应用程序将具有动态数量的行。如果我不知道我将有多少行,我该如何创建 NSArray?我可以使用 NSMutableArray 吗?

它接受的第二个参数是一个动画 - 这很简单。

我遇到的另一个问题是:我应该在哪里创建这些单元格?如何将单元格传递给表视图?

我试过阅读文档,但文档似乎不是很清晰!这是我目前在视图控制器的 loadview 方法中拥有的代码:

 //Before this I get the XML from the server so I am ready to populate
 //cells and add them to the table view
 NSArray *cells = [NSArray arrayWithObjects:
                   [NSIndexPath indexPathForRow:0 inSection:0],
                   [NSIndexPath indexPathForRow:1 inSection:0],
                   [NSIndexPath indexPathForRow:2 inSection:0],
                   [NSIndexPath indexPathForRow:3 inSection:0],
                   [NSIndexPath indexPathForRow:4 inSection:0],
                   [NSIndexPath indexPathForRow:5 inSection:0],
                   [NSIndexPath indexPathForRow:6 inSection:0],
                   [NSIndexPath indexPathForRow:7 inSection:0],
                   [NSIndexPath indexPathForRow:8 inSection:0],
                   [NSIndexPath indexPathForRow:9 inSection:0],
                   [NSIndexPath indexPathForRow:10 inSection:0],
                   [NSIndexPath indexPathForRow:11 inSection:0],
                   [NSIndexPath indexPathForRow:12 inSection:0],
                   nil];
[eventTypesTable beginUpdates];
[eventTypesTable insertRowsAtIndexPaths:cells withRowAnimation:UITableViewRowAnimationNone];
[eventTypesTable endUpdates];
4个回答

18

我认为您的思路有误。UITableView并不像您预期的那样工作。 insertRowsAtIndexPaths 用于向表格中插入新行,而不是在第一次填充时使用。

UITableView通过调用许多委托方法来允许您按需要向表格视图呈现数据。然后框架会处理繁重的工作来填充单元格、处理滚动和触摸事件等。

我建议您先阅读诸如此类的教程:http://www.iosdevnotes.com/2011/10/uitableview-tutorial/ ,它看起来相当详细。它解释了如何为表格设置数据源以及如何配置UITableView呈现您的数据的方式。

祝好运!


谢谢,我发现我完全对它的工作原理感到困惑。我现在已经成功地输出了单元格,但是我遇到了一个问题。我从数据库中检索到12行,但屏幕只能显示7行。一旦屏幕满了,在模拟器中如果我尝试向下滚动,就会在cellForRowAtIndexPath方法内的NSString *sEventType = [[eventTypes valueForKeyPath:@ "name.text"] objectAtIndex:indexPath.row];出错。我需要添加滚动控制器或其他什么吗?再次感谢您迅速而有帮助的回应! - KerrM
7
链接已损坏。这就是为什么您应该至少发布一些示例代码而不是依赖外部链接的原因。 - Jared Price
链接已经失效,但是你可以在这里找到该网址的内容:http://web.archive.org/web/20150928131750/http://www.iosdevnotes.com/2011/10/uitableview-tutorial/。 - Upsilon42

16

不需要使用 insertRowsAtIndexPaths

请参考:UITableViewDataSource协议参考UITableView类参考

其中这三个方法(UITableViewDataSource协议方法)发挥着重要的作用:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

你只需要填充一个数组。是的,它可以是一个NSMutableArray

例如,你可以在- (void)viewDidLoad中填充数组:

yourItemsArray = [[NSMutableArray alloc] initWithObjects:@"item 01", @"item 02", @"item 03", nil];

然后像这样使用数据源方法:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    // If You have only one(1) section, return 1, otherwise you must handle sections
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return [yourItemsArray count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    // Configure the cell...
    cell.textLabel.text = [yourItemsArray objectAtIndex:indexPath.row];

    return cell;
}

这样就会自动创建这些单元格。

如果要更改数组,只需要调用:

[self.tableView reloadData];

谢谢您的回复,我希望我能选择多个答案作为被接受的答案。 - KerrM
3
没问题,解决同一个问题有不同的方法。如果您刚开始学习,应该参考教程以了解事物的运作方式,而不仅仅是代码。实际上两者都很有帮助。 - Frade
是的,我想会有这样的问题。不过我遇到了另一个问题,希望你能帮忙 - 我从数据库中检索了12行数据,但屏幕只能容纳7行。一旦屏幕满了,在模拟器中如果我尝试向下滚动,就会在cellForRowAtIndexPath方法中的NSString *sEventType = [[eventTypes valueForKeyPath:@"name.text"] objectAtIndex:indexPath.row];处出现错误。就好像该方法在到达屏幕底部时就停止运行了。这是我做错了什么吗? - KerrM
不确定。您是否正在使用:dequeueReusableCellWithIdentifierreuseIdentifier?也许您应该提出另一个问题来解释您的错误。 - Frade

2
//######## Adding new section programmatically to UITableView    ############

  @interface MyViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
    {
        IBOutlet UITableView *tblView;
        int noOfSection;
    }
    -(IBAction)switchStateChanged:(id)sender;
    @end



    @implementation MyViewController
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (self) {
            // Custom initialization
        }
        return self;
    }
    - (void)viewDidLoad{
        [super viewDidLoad];

        noOfSection = 2;
    }
    - (void)viewDidUnload{
        [super viewDidUnload];
    }
    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
        if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {

            return YES;
        }

        return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
    }
    #pragma mark - TableView Delegate Methods
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
        return noOfSection;
    }
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

        return 1;
    }
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
        if(indexPath.section == 2){
            return 200;
        }
        return  50;
    }

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

        static NSString *CellIdentifier = @"Cell";

        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];

            UISwitch *switchBtn = [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 20, 10)];
            cell.accessoryView = switchBtn; 

            [switchBtn addTarget:self action:@selector(switchStateChanged:) forControlEvents:UIControlEventValueChanged];
            cell.textLabel.font = [UIFont systemFontOfSize:14];
            cell.detailTextLabel.font = [UIFont systemFontOfSize:11];
            cell.textLabel.numberOfLines = 2;
            cell.detailTextLabel.numberOfLines = 2;
        }



        if(indexPath.section == 0){
            cell.textLabel.text = @"Cell-1 Text";
            cell.detailTextLabel.text = @"Cell-1 Detail text";
        }
        else if(indexPath.section == 1){
            cell.textLabel.text = @"Cell-2 Text";
        }
        else { // new added section code is here...
            cell.textLabel.text = @"New Added section";
        }
        [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
        return cell;
    }
    -(IBAction)switchStateChanged:(id)sender{
        UISwitch *switchState = sender;

        if(switchState.isOn == YES){
            NSLog(@"ON");
            NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:2];
            [self insertNewSectionWithIndexPath:indexPath];
        }
        else {
            NSLog(@"OFF");
            [self removeSectionWithIndexPath:[NSIndexPath indexPathForRow:0 inSection:2]];
        }
    }
    -(void)insertNewSectionWithIndexPath:(NSIndexPath *)indexPath{


        noOfSection = 3;
        [tblView insertSections:[NSIndexSet indexSetWithIndex:2] withRowAnimation:UITableViewRowAnimationFade];
    }
    -(void)removeSectionWithIndexPath:(NSIndexPath *)indexPath{
        noOfSection = 2;
        [tblView deleteSections:[NSIndexSet indexSetWithIndex:2] withRowAnimation:UITableViewRowAnimationFade];
    }
    @end

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接