【问题标题】:Adding cells programmatically to UITableView以编程方式将单元格添加到 UITableView
【发布时间】:2012-02-24 11:02:13
【问题描述】:

我最近刚刚开始为 iPhone 编程,我正在制作一个连接到数据库并获取一组行名并显示它们的应用程序。选中后,行背景颜色会发生变化,即您可以进行多项选择,它们都将是不同的颜色。所以我从服务器获取 XML 没有问题,我创建了一个 UITableView 来显示单元格。但是,我不知道如何将单元格添加到表中。我看了一下insertRowsAtIndexPaths,但我不确定如何使用它?据我了解,insertRowsAtIndexPaths 有两个参数:

一个 NSArray,它包含单元格应该在哪一行和哪一节。这样做的问题是我的应用程序将具有动态的行数。如果我不知道我将拥有多少行,我将如何创建 NSArray?我可以使用 NSMutableArray 吗?

它采用的第二个参数是动画 - 这很简单。

我遇到的另一个问题是我在哪里实际创建单元格?如何将单元格传递给 tableview?

我已尝试阅读文档,但似乎不是很清楚!这是我目前在视图控制器的 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];

【问题讨论】:

    标签: ios objective-c iphone uitableview


    【解决方案1】:

    我认为你是从错误的方向来解决这个问题的。 UITableViews 不能按您的预期工作。 insertRowsAtIndexPaths 用于向表中插入新行,而不是在第一个实例中填充它。

    UITableViews 通过调用一些委托方法来工作,这些委托方法允许您根据需要将数据呈现给表格视图。然后框架负责繁重的工作以填充单元格、处理滚动和触摸事件等。

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

    祝你好运!

    【讨论】:

    • 谢谢,我知道我完全不知道它是如何工作的。我现在已经设法正确输出单元格,但我遇到了问题。我正在从数据库中检索 12 行,但是,屏幕只适合 7 行。一旦屏幕已满并且在模拟器中,如果我尝试向下滚动,我在 cellForRowAtIndexPath 方法中的 NSString *sEventType = [[eventTypes valueForKeyPath:@"name.text"] objectAtIndex:indexPath.row]; 中会出现错误。有什么我想念的吗?像我必须添加一个滚动控制器还是什么?再次感谢您的及时和乐于助人的回复!
    • 链接已损坏。这就是为什么您至少应该发布一些示例代码而不是依赖外部链接。
    • 链接已损坏,但您可以在此处找到此网址的内容:web.archive.org/web/20150928131750/http://www.iosdevnotes.com/…
    【解决方案2】:

    不需要使用insertRowsAtIndexPaths

    检查:UITableViewDataSource Protocol ReferenceUITableView Class Reference

    魔法发生在这三个方法(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];
    

    【讨论】:

    • 感谢您的回复,我希望我可以选择多个答案作为已接受的答案。
    • 没关系,同一个问题有不同的方法。如果你开始学习,你应该学习教程来了解事情是如何工作的,而不仅仅是代码。但两者都确实有帮助
    • 是的,我想会有。不过,我遇到了另一个问题,希望您能提供帮助-我正在从数据库中检索 12 行,但是屏幕只适合 7 行。一旦屏幕满了,并且在模拟器中,如果我尝试向下滚动,我会得到一个NSString 中的错误 *sEventType = [[eventTypes valueForKeyPath:@"name.text"] objectAtIndex:indexPath.row];在 cellForRowAtIndexPath 方法中。几乎就像该方法一旦到达屏幕底部就会停止运行。这是我做错了吗?
    • 不确定。你在使用:dequeueReusableCellWithIdentifierreuseIdentifier??也许你应该提出另一个问题来解释你的错误..
    【解决方案3】:
    //######## 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
    

    【讨论】:

      【解决方案4】:

      您不必担心。单元格将自动创建。看看这些 UITableview Class Reference

      Tableview_iPhone

      你必须实现 UITableView 数据源和委托协议。也看看这个教程 UITableview Tutorial

      【讨论】:

        猜你喜欢
        • 2020-10-18
        • 1970-01-01
        • 2020-10-16
        • 2022-10-20
        • 2011-10-20
        • 1970-01-01
        • 2015-04-27
        • 2014-10-16
        • 1970-01-01
        相关资源
        最近更新 更多