【问题标题】:Obj-C iPhone UISegmentedControl in UITableViewUITableView 中的 Obj-C iPhone UISegmentedControl
【发布时间】:2011-07-14 04:07:55
【问题描述】:

我的表中有 9 个部分(它们是从数组中提取的)。在 4 个部分中,我将有 1 行拉出 UIPickerView。在其中的 5 个部分中,我需要 5 个不同的 UISegmentedControl,具有不同数量的选择选项(2-5 个选项)。有没有人对我的实施有任何提示?

我应该为每个 UISegmentedControl 构建单独的 xib 文件吗?我觉得会有/应该有更好的方法来做到这一点。

任何帮助将不胜感激!

【问题讨论】:

    标签: iphone objective-c uitableview uisegmentedcontrol


    【解决方案1】:

    indexPath 对象中,您可以查看表格视图项的rowsection。那时你可以决定显示什么,你的视图,一些文本另一个视图,不管是cell的值。请记住,单元格是 UIView,因此您可以添加子视图和所有这些。 UITableView 的 Apple 文档实际上有一节介绍如何创建带有控制器的静态单元格以及如何用其他视图覆盖 cell 对象。

    由于一切都是静态的,您可以在常规 cellForRowAtIndexPath 中使用类似这样的 switch 语句检查这些部分:

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *MyIdentifier = @"aCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
    if (cell == nil) { 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2
                                                      reuseIdentifier:MyIdentifier] autorelease]; }
    switch ([indexPath section]) {
        case 0:{
            cell.textLabel.text = @"The first section's cell";
            break;
        }
        case 1:{
            switch ([indexPath row]) {
                case 0:{
                    //The first row of the second section
                    break;
                }
                case 1:{
                    //The second row of the second section
                    break;
                }
                case 2:{
                    //The third row of the second section
                    break;
            }
    
    
            }
            break;
        }   
        case 2:{
            //the third section
            break;
        }
        case 3:{
            //the fourth section
            cell.textLabel.text = @"Notes";
            cell.detailTextLabel.text = currentClient.Notes;
            break;
        }
    
        default:
            break;
    }
    
    return cell;
    }
    

    【讨论】:

      【解决方案2】:

      您的表结构在 NSArray 中,因此我建议您为应该具有分段控件的每一行创建一个 NSDictionary,并将其添加到表结构 NSArray

      您需要字典中的三个对象。一个标题,一个带有段名称的 NSArray,你需要一个用于设置和获取所选索引的键。

      我为我的一些应用程序中的设置视图控制器做了类似的事情。这就是 NSDictionary 的样子:

      [NSDictionary dictionaryWithObjectsAndKeys:
        @"Value of Foo", kSettingsLabel,              // for the textLabel
        [UISegmentedControl class], kSettingsView,    // which UIControl
        @"foo", kSettingsKey,                         // the key for setValue:forKey: and valueForKey:
        [NSArray arrayWithObjects: @"Green", @"Round", @"Auto",nil], kSettingsValue,  // the titles of the segments
      nil] 
      

      这就是我在 tableview 中设置 UISegmentedControls 的方式:

      NSDictionary *dictionary = [[self.dataSourceArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
      // omitted: check in the dictionary which cell we need... (I wrote it that it can use almost all UIControls)
      // omitted: dequeue a cell with a UISegmentedControl ... 
      // configure cell:
      NSArray *segmentTitles = [dictionary objectForKey:kSettingsValue];
      UISegmentedControl *segment = (UISegmentedControl *)[cell viewWithTag:kTagSegment];
      [segment removeAllSegments];
      for (NSString *segmentName in segmentTitles) {
          // if index is higher than number of indexes title is inserted at last available index. 
          // so first object in array is placed at first position in segmentcontrol
          [segment insertSegmentWithTitle:segmentName atIndex:1000 animated:NO];
      }
      [segment setSelectedSegmentIndex:[[self valueForKey:[dictionary valueForKey:kSettingsKey]] intValue]];
      //omitted: setup cell title ... and return cell
      

      UISegmentedControl 连接到如下所示的值更改操作:

      NSIndexPath *indexPath = [self.settingsTable indexPathForCell:(UITableViewCell *)[[sender superview] superview]];
      if (indexPath == nil)
          return;
      NSDictionary *dictionary = [[self.dataSourceArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
      
      if ([sender isKindOfClass:[UISegmentedControl class]]) {
          [self setValue:[NSNumber numberWithInt:((UISegmentedControl *)sender).selectedSegmentIndex] forKey:[dictionary valueForKey:kSettingsKey]];
      }
      

      当然你也需要指定键的 setter 和 getter:

      - (NSNumber *)foo {
          return [NSNumber numberWithInt:someValue];
      }
      
      - (void)setFoo:(NSNumber *)n {
          someValue = [n intValue];
      }
      

      你可以合成它们,但我想在我的类中使用 int 值而不是 NSNumbers,所以我自己编写了 setter 和 getter。


      这样做的最大优点是它是完全动态的。如果你想重新排列单元格,只需将它们在数组中移动(我使用 plist 使这更容易)。

      第一次使用时会有点复杂,但很快就会清楚。而且你不想在你的类界面中有五个不同的 .xibs 和五个不同的 UISegmentedControls。

      【讨论】:

      • 这样一来,我根本不用任何IB,对吧?这看起来比我正在寻找的要复杂一些,因为这些行永远不需要是动态的。我很欣赏发布代码的努力(这实际上可能会在应用程序的不同视图中使用),但是您可以为静态表推荐不同的方法吗?
      • 我使用了一个 .xib,它有 10 个 UITableViewCells 用于我需要的所有不同单元格。老实说,对于静态表,我会以几乎相同的方式进行操作。创建具有单元格布局的 .xib 并在代码中创建段标题。如果这是静态的,则不需要字典或键值访问。带有硬编码值的 if (row == 1) /* setup cell */ 就足够了。
      • 太棒了!就我而言,我会使用 'if (section == 1) /* setup cell*/,但想法保持不变。那么然后做一些类似this blog post?的事情在代码中而不是在IB中设置段标题有什么好处?如果无论如何我都在搞乱 IB,我不会通过在 IB 中设置它们来节省一些编码,还是我在这里遗漏了什么?
      • 您当然可以在 Interface Builder 中创建每一行。这种方式没有问题。我通常不这样做,因为当我想让片段更宽一点时,我必须在 5 个单元格上进行。而且我至少改变了界面元素的位置 10 次。而且我以至少两种语言发布我的所有应用程序,因此代码方式还有另一个优势。但是使用界面生成器并没有错。做最适合你的事情。如果你喜欢在 IB 做这件事,那就去做吧。
      • 太棒了!非常感谢您的帮助!
      【解决方案3】:

      您可以通过多种方式轻松做到这一点。

      1. 您可以设置UISegmentedControl标签,然后像这样访问它。
      2. 您可以通过编程方式为每个部分创建控件。这还需要您设置标签,以便您可以通过其他方法访问它。

      在我看来,这些是实现您想要做的最简单的方法。

      这两种方式都需要您在标题中定义控件。

      .h

      @interface MyViewController : UIViewController
      {
          UISegmentedControl *myControl;
      }
      @property (nonatmoic, retain) UISegmentedControl *segment;
      @end
      

      .m

      #import "MyViewControler.h"
      @implementation MyViewController
      @synthesize myControl;
      . . .
      

      【讨论】:

      • 您能详细说明这些方法吗?我已经在我的头文件中定义了所有需要的东西,并在我的 .m 中合成了它们,但我不知道如何巧妙地决定哪个 UISegmentedControl 放在哪个部分。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-06
      • 1970-01-01
      • 2017-05-21
      • 1970-01-01
      • 2014-01-18
      相关资源
      最近更新 更多