【问题标题】:How do you use for loop in didSelectRowAtIndexPath to minimize my code?如何在 didSelectRowAtIndexPath 中使用 for 循环来最小化我的代码?
【发布时间】:2012-10-10 05:38:49
【问题描述】:

如下所示,我有两个部分“A-M”和“N-Z”。我计划添加几个城市,但我的 didSelectRowAtIndexPath 代码似乎很长。

什么循环,你如何实现它,这样我就不必添加很多 else if。

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    switch (section) {
        case 0:
            return @"A-M";
            break;

        case 1:
            return @"N-Z";
            break;

        default:
            break;
    }
    return nil;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0 && indexPath.row == 0) {
        self.cityController.title = @"Bologna";
    }

    else if (indexPath.section == 0 && indexPath.row == 1) {
        self.cityController.title = @"Florence";
    }

    else if (indexPath.section == 1 && indexPath.row == 0) {
        self.cityController.title = @"Naples";
    }

    else if (indexPath.section == 1 && indexPath.row == 1) {
        self.cityController.title = @"Rome";
    }

[self.navigationController pushViewController: self.cityController animated: YES];
}

【问题讨论】:

    标签: iphone ios ios5 ios4


    【解决方案1】:

    我会采用不同的方法来编写代码。因为您在其中对这些城市名称进行了硬编码,所以您将更加难以添加/删除/以其他方式维护您的代码。在最基本的层面上,您可以在表格视图中保留一系列城市。这将允许您在不更改代码的情况下更改数据。

    标题:

    @interface MyTableViewController : UITableViewController
    
    @property (nonatomic, strong) NSArray *cities;
    
    @end
    

    实施:

    @implementation MyTableViewController
    
    // other code
    
    #pragma mark - UITableViewDelegate
    
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        NSString *city = self.cities[indexPath.row];
    
        MyCityController *controller = // Init code;
        controller.title = city;
    
        NSLog(@"Selected city: %@", city);
    }
    
    // Other code
    
    @end
    

    您的数据源应该以类似方式实现:

    - (UITableViewCell *)tableView:(UITableView *) cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        static NSString *CELL_ID = @"CITIES";
    
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CELL_ID];
    
        cell.textLabel.text = self.cities[indexPath.row];
    
        // Other setup code
    
        return cell;
    }
    

    您可以使用硬编码值延迟加载它们:

    - (void)cities {
        if (_cities == nil) {
            _cities = @[@"Bologna", @"Florence", @"Milan", @"Naples", @"Rome"];
        }
    
        return _cities;
    }
    

    或者从viewDidLoad中的plist加载它们

    - (void)viewDidLoad {
        if (!self.cities) {
            NSString *path = [[NSBundle mainBundle] pathForResource:@"cities" ofType:@"plist"];
            NSDictionary *cityDict = [NSDictionary dictionaryWithContentsOfFile:path];
            self.cities = [cityDict objectForKey:@"cities"];
        }
    }
    

    【讨论】:

    • 我对这个真的很陌生,所以我仍然不完全了解使用什么。你能告诉我怎么做吗?漂亮请。
    • @Jahm 就个人而言,我会放弃这两个部分。无论如何,您都希望将它们按字母顺序排列,并且将它们分解不会给您的用户带来任何好处。只要有一个按字母顺序排列的城市列表。您可以对它们进行硬编码或将它们与您的应用一起存储在 plist 中。
    • 快速提问。 NSMUtableArray 可以代替使用 NSArray 吗?
    • @Jahm 为作业使用适当的集合。如果您不需要在运行时添加或删除项目,只需使用不可变的NSArray
    • 这与上述问题无关。我有一个关于 [__NSArrayM objectAtIndex:] 的错误:索引 2 超出范围 [0 .. 1]'。我该如何解决这个问题?
    【解决方案2】:

    你为什么不把所有这些都填入静态数组,可能是这样的

    NSArray *strings = @[ @[ @"City1", @"B", @"C" ], @[ @"D", @"E", @"F" ]];
    

    然后返回这个。

    Strings[sectionindex][roeindex];
    

    【讨论】:

      【解决方案3】:

      您应该有一个适当的数据结构来保存表中每一行的数据。在这种情况下,您应该有一个字典数组(或类似的东西)。顶级数组每个部分将有一个条目。对于节中的每一行,节数组将有一个条目。这些条目中的每一个都将是字典或一些表示该行数据的自定义对象。这将包括标题和有关该行数据的任何其他内容。

      此数据结构将用于“cellForRowAtIndexPath”和“didSelectRowsAtIndexPath”。根据 indexPath 提取字典或自定义类。

      因此,您的整个 'didSelectRowAtIndexPath' 只需几行代码。

      【讨论】:

      • 是的,如果数据在 plist 中,那么当您将 plist 加载到数组中时,您会得到我所描述的内容。只要您的 plist 数据按照您希望它显示在表格中的方式设置(两个部分有两组行)。
      【解决方案4】:

      您可以使用 switch case 来避免 if-else。但是您是否在 tableview 中显示这些城市名称并基于将名称发送到 cityController 的选择?如果是,那么也不需要使用 switch case,因为您的方式使用数组显示这些名称,同样您可以使用 indexPath 发送该名称。

      使用开关盒:

      switch(indexPath.section)
      {
        case 0:
              {
                 switch(indexPath.row)
                 {
                   case 0:
                    stmt;
                    break;
      
                    case 1:
                    stmt;
                    break;
                 }
              }
        same as case0... 
      } 
      

      【讨论】:

        【解决方案5】:

        我同意@Wayne Hartman 的观点,你不想要一个 for 循环,你只想要一个包含所有数据的数组。每次生成(或出列)单元格时都会调用 cellForRowAtIndexPath,如果您只是告诉它从数组中加载其标题,例如

        [cell.textLabel setText:[citiesInItaly objectAtIndex:indexPath.row] 
        

        这将比硬编码单元格标题更干净。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-08-29
          • 1970-01-01
          • 1970-01-01
          • 2019-07-27
          • 1970-01-01
          • 2021-10-11
          • 2012-11-01
          • 1970-01-01
          相关资源
          最近更新 更多