【问题标题】:UISegmentedControl not updating viewUISegmentedControl 不更新视图
【发布时间】:2013-09-06 11:46:47
【问题描述】:

我正在 Xcode 5 中构建一个应用程序,我遇到了 UISegmentedControl 的一些奇怪行为。

首先了解我正在构建的应用程序的一些信息:

我正在构建一个应用程序,我希望允许用户在其中订购注册公司的产品。作为一项额外的服务,我想让他们看到他们所做的订单,甚至可以根据他们的状态过滤订单:所有订单、活动订单和已交付订单。订单显示在 UITableView 中,我在标题视图中创建了一个UISegmentedControl 来过滤订单。当UISegmentedControlselectedSegmentIndex 发生变化时,它会执行NSPredicate 来过滤数组并仅显示所需的订单。

现在一切正常,除了一件事:当我选择另一个段时,我拥有的 UISegmentedControl 没有更新它的视图。默认selectedSegmentIndex 是'Active',因为用户可能对活动订单最感兴趣,但是当我将其更改为'全部'时,表格视图显示所有订单(因此谓词有效),但视图仍然存在在同一个selectedSegmentIndex

我做了很多研究来解决这个问题,但没有答案能解决我的问题..我的代码:

    - (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{

    if(section == 0) {
        UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0.0f,0.0f, 320, 45)]; // x,y,width,height

        //label
        UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320, 20)];
        title.text = @"Kies een filter...";
        [headerView addSubview:title];

        //segmentedcontrol
        NSArray *itemArray = [NSArray arrayWithObjects: @"Alle", @"Actief", @"Afgehandeld", nil];
        control = [[UISegmentedControl alloc] initWithItems:itemArray];
        [control setFrame:CGRectMake(0.0f, 20.0f, 320.0, 35.0)];
        control.userInteractionEnabled = YES;
        control.tintColor = [UIColor blackColor];
        [control setEnabled:YES];
        [control addTarget:self action:@selector(changeFilter:) forControlEvents:UIControlEventAllEvents];
        [headerView addSubview:control];

        //label containing selected filter info
        UILabel *info = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 55.0f, 320, 20)];
        if ([selectedFilterInfo isEqualToString:@"Alle"]) {
            info.text = @"Alle orders:";
        }
        else if ([selectedFilterInfo isEqualToString:@"Actief"]) {
            info.text = @"Alle actieve orders:";
        }
        else if ([selectedFilterInfo isEqualToString:@"Afgehandeld"]) {
            info.text = @"Alle afgehandelde orders:";
        }
        [headerView addSubview:info];

        headerView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"bar.png"]];
        return headerView;
    }
}

以及它触发的动作:

- (void)changeFilter:(id)sender {
UISegmentedControl *segmentedControl = (UISegmentedControl *)sender;
if (segmentedControl.selectedSegmentIndex == 0) {
    selectedFilterInfo = @"Alle";
    filteredArray = nil;
    [segmentedControl reloadInputViews];
    [segmentedControl setSelectedSegmentIndex:0];
}

else if (segmentedControl.selectedSegmentIndex == 1) {
    NSPredicate *deliveredpredicate = [NSPredicate predicateWithFormat:@"SELF.delivered contains[c] %@", @"0"];
    NSMutableArray *notDeliveredArray = [NSMutableArray arrayWithArray:[sortedArray filteredArrayUsingPredicate:deliveredpredicate]];
    filteredArray = [NSMutableArray arrayWithArray:notDeliveredArray];
    selectedFilterInfo = @"Actief";
    [segmentedControl reloadInputViews];
    [segmentedControl setSelectedSegmentIndex:1];
}

else if (segmentedControl.selectedSegmentIndex == 2) {
    NSPredicate *deliveredpredicate = [NSPredicate predicateWithFormat:@"SELF.delivered contains[c] %@", @"1"];
    NSArray *deliveredArray = [sortedArray filteredArrayUsingPredicate:deliveredpredicate];
    filteredArray = [NSMutableArray arrayWithArray:deliveredArray];
    selectedFilterInfo = @"Afgehandeld";
    [segmentedControl reloadInputViews];
    [segmentedControl setSelectedSegmentIndex:2];
}
[self.tableView reloadData];

}

我没有包含 numberOfCellsInSection 等,因为 tableview 部分运行良好。唯一不起作用的是更新视图。

任何解决方案将不胜感激,提前谢谢大家!

【问题讨论】:

  • 你是否调用了changeFilter方法?如果不是,那就是问题所在,然后用此行替换您的代码: [control addTarget:self action:@selector(changeFilter:) forControlEvents:UIControlEventValueChanged];
  • 该方法确实被调用,因为它正在更新 tableView。
  • 替换我在第一条评论中提到的行,如果没有必要,则从所有 [segmentedControl reloadInputViews] 中删除这两行; [segmentedControl setSelectedSegmentIndex:2];然后重新加载表
  • 我按照你说的更新了我的方法,但没有任何改变。 changeFilter: 仍然被调用,没有任何问题,并且 tableview 被更新,但视图仍然没有改变。也许这与它以编程方式插入标题视图的事实有关?
  • 你对我给出的两个建议都试过了吗?如果那么它也不起作用,那么先告诉我发生了什么,试试看

标签: iphone objective-c xcode uitableview uisegmentedcontrol


【解决方案1】:

reloadData 会重新加载 tableView,当你重新加载 tableView 时,所有 headerViews 也会重新加载。当 tableView 重新加载时,会有一个新的标题。而你现在看到的 UISegmentedControl 并不是你点击的那个。

创建一个保存所选索引的 ivar

@implementation .. {
    NSInteger selectedIndex;
}

创建视图时恢复保存的索引

- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    /* ... */
    control = [[UISegmentedControl alloc] initWithItems:itemArray];
    control.selectedSegmentIndex = selectedIndex;
    /* ... */
}

更改segmentedControl时保存索引

- (void)changeFilter:(id)sender {
    UISegmentedControl *segmentedControl = (UISegmentedControl *)sender;
    selectedIndex = segmentedControl.selectedSegmentIndex;
    if (segmentedControl.selectedSegmentIndex == 0) {
        selectedFilterInfo = @"Alle";
        filteredArray = nil;
    }
    /* ... */

    // reloads the table and all header views!
    [tableView reloadData];
}

顺便说一句。当您使用 UISegmentedControls 时,无需再次调用setSelectedSegmentIndex:,点击已设置索引。并且 reloadInputViews 对于 UISegmentedControl 完全没用。但我猜这个代码是刚刚添加的,因为它不起作用。不要忘记删除它;-)

【讨论】:

  • 让我开心,爱它。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-04
  • 1970-01-01
相关资源
最近更新 更多