【问题标题】:Get segmentedcontrol value from tableviewcells从表格视图单元格中获取分段控制值
【发布时间】:2013-12-17 21:46:12
【问题描述】:

如何从 tableviewcells 中的分段控件中获取值(选定状态)? 当我按下“获取状态”按钮时,它应该返回每个分段控件的值。我尝试了不同的方法,但我找不到一种有效的方法:(

到目前为止我的代码:

- (void)viewDidLoad
{
[super viewDidLoad];

tableData = [[NSMutableArray alloc] initWithCapacity:0];
tableData = [NSArray arrayWithObjects:@"First", @"Second", @"Third", nil];
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

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

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:@"StateCell"];
if (cell == nil)
{
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"StateCell"];
}

//Config cell..
cell.textLabel.text = [tableData objectAtIndex:indexPath.row];

NSArray *itemArray = [NSArray arrayWithObjects: @"1", @"2", @"3", nil];
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:itemArray];
segmentedControl.frame = CGRectMake(110, 7, 100, 28);

[cell.contentView addSubview:segmentedControl];

return cell;
[[self tableView] reloadData];
}

- (IBAction)getStates:(id)sender {

// Ruturn the current selected statement, for the individual cell's segmentedcontrol..
// Ex. First = SelectedState 1, Second = SelectedState 0 & Third = SelectedState 2..

}

所以我真正想要的是;是“获取状态”按钮操作必须执行的操作..

感谢您的宝贵时间!

【问题讨论】:

  • 您自己尝试过吗?还是你只是要代码?
  • 嗨。我一直在尝试各种方法..所以代码会非常好!我只有 15 岁,对 IOS 开发还很陌生;)
  • 请将您尝试过的代码添加到您的问题中,并详细说明您遇到的具体部分以及出了什么问题。
  • 我发现的最后一个方法充满了错误和过时的代码:(如果你能帮助我继续我的项目,这将对我有很大帮助!:) 谢谢
  • 您需要在问题中添加相关代码,否则我们无法帮助您。我们需要先了解您做错了什么,然后才能告诉您要解决的问题。

标签: ios xcode uitableview ios7 uisegmentedcontrol


【解决方案1】:

您的代码有几个问题。大多数情况发生是因为 UITableView 重用了它的单元格。

每次显示单元格时,您都会创建一个新的 UISegmentedControl,但您不应该这样做。仅当您创建单元格时才应创建 UISegmentedControl,将该代码移动到 cell == nil)

您没有保存段状态的数据源。您不应该在视图中保存状态,尤其是在处理 tableView 时,因为单元格被重用。

这里有一个示例,它将获得您需要的功能。

// this is an object of your model, it has a title and saves the selected index
@interface MBFancyObject : NSObject
@property (strong, nonatomic) NSString *title;
@property (assign, nonatomic) NSInteger selectedIndex;
@end

@implementation MBFancyObject
@end


@interface MasterViewController () {
    NSMutableArray *_objects;     // stores instances of MBFancyObject
}
@end

@implementation MasterViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // set up the model
    _objects = [NSMutableArray array];
    for (NSInteger i = 0; i < 6; i++) {
        MBFancyObject *object = [[MBFancyObject alloc] init];
        object.title = [NSString stringWithFormat:@"Object #%ld", (long)i];
        object.selectedIndex = i % 3;
        [_objects addObject:object];
    }

    UIBarButtonItem *button = [[UIBarButtonItem alloc] initWithTitle:@"Get States" style:UIBarButtonItemStyleBordered target:self action:@selector(logStates:)];
    self.navigationItem.rightBarButtonItem = button;
}

#pragma mark - Table View

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return _objects.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"FancyCell"];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"FancyCell"];
        // add the segmentedControl when you create a new cell
        UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:@[@"1", @"2", @"3"]];
        segmentedControl.frame = CGRectMake(110, 7, 100, 28);
        [cell.contentView addSubview:segmentedControl];

        // add an action so we can change our model if the view changes
        [segmentedControl addTarget:self action:@selector(didChangeSegmentedControl:) forControlEvents:UIControlEventValueChanged];

        // use a tag so we can retrieve the segmentedControl later
        segmentedControl.tag = 42;
    }
    // either if the cell could be dequeued or you created a new cell,
    // segmentedControl will contain a valid instance 
    UISegmentedControl *segmentedControl = (UISegmentedControl *)[cell.contentView viewWithTag:42];

    MBFancyObject *object = _objects[indexPath.row];
    cell.textLabel.text = object.title;
    segmentedControl.selectedSegmentIndex = object.selectedIndex;
    return cell;
}

- (IBAction)didChangeSegmentedControl:(UISegmentedControl *)sender {
    // transform the origin of the cell to the frame of the tableView
    CGPoint senderOriginInTableView = [self.tableView convertPoint:CGPointZero fromView:sender];

    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:senderOriginInTableView];
    NSAssert(indexPath, @"must have a valid indexPath");
    MBFancyObject *object = _objects[indexPath.row];
    object.selectedIndex = sender.selectedSegmentIndex;
}

- (IBAction)logStates:(id)sender {
    // query the model, not the view
    for (NSInteger i = 0; i < [_objects count]; i++) {
        MBFancyObject *object = _objects[i];
        NSLog(@"Object \"%@\" - %ld", object.title, (long)object.selectedIndex);

        // since you have only one section, each indexPath is 0,i
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
    }
}

@end

【讨论】:

  • 非常感谢!我不知道如何定义新单元格,除了“对象#7”等等。如果我想要 20 个单元格,名字像狗、猫、马……希望你仍然想帮助我!我正在谈论的代码在 - (void)viewDidLoad :)
  • 移除viewDidLoad 中的for 循环,并为每一行手动创建MBFancyObject。或者保留 for 循环并从数组中获取动物字符串,以便您可以替换 stringWithFormat: thingie。
  • 感谢您的快速答复!我认为在数组中使用字符串的方法是最好的,并保持循环;)当你说“或保持 for 循环并从数组中获取动物字符串以便你可以替换 stringWithFormat:thingie”时,这听起来很容易,但对于像我这样 15 岁,还没有接受过应用程序开发教育的人来说,这可能很难! :P 我会继续努力,但如果你能给我一个例子怎么做 = 太棒了!! :D 谢谢!
【解决方案2】:

使用一个数组来存储所有的段控件值,当点击一个段控件时,只需相应地改变值即可。

【讨论】:

    【解决方案3】:

    你在这里重用有严重的问题

    永远不要在 tableView:cellForRowAtIndexPath: 方法中分配新的 UI 元素,除非它在 ​​if 条件 if (cell == nil)

    tableView:cellForRowAtIndexPath: 中的内容更改为

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"StateCell"];
    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"StateCell"];
    
        // Add the Segmented Control
        NSArray *itemArray = [NSArray arrayWithObjects: @"1", @"2", @"3", nil];
        UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:itemArray];
        segmentedControl.frame = CGRectMake(110, 7, 100, 28);
        segmentedControl.tag = 1;
        [cell addSubview:segmentedControl];
    }
    
    //Config cell..
    cell.textLabel.text = [tableData objectAtIndex:indexPath.row];
    
    // Get that Segmented Control
    UISegmentedControl *segmentedControl = (UISegmentedControl *)[cell viewWithTag:1];
    segmentedControl.selectedSegmentIndex = 0; // Set your default value here or add your data in an array and read from that array
    
    return cell;
    

    然后在按钮的动作中这样做

    for (UITableViewCell *cell in [tableView visibleCells]) {
        UISegmentedControl *segmentedControl = (UISegmentedControl *)[cell viewWithTag:1];
        NSLog(@"%d",segmentedControl.selectedSegmentIndex);
    }
    

    但是,除非您的表格中只有 3 个单元格以避免重用或可见性问题,否则此代码并不完美

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多