UISegmentedControl无法更新视图

3

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

首先是关于我正在构建的应用程序的一些信息:

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

现在它运行得很好,除了一件事:我拥有的UISegmentedControl在选择另一个段时不更新其视图。它的默认selectedSegmentIndex是'Active',因为用户可能对活动订单最感兴趣,但是当我将其更改为'All'时,tableview显示所有订单(因此谓词正在工作),但视图仍保持在相同的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]; - D-eptdeveloper
该方法确实被调用了,因为它正在更新tableView。 - Joris416
我按照你说的更新了我的方法,但是什么也没改变。changeFilter: 仍然能够被调用而没有任何问题,tableview 也已经被更新了,但是视图仍然没有改变。也许这与它被以编程方式插入到标题视图中有关? - Joris416
你尝试过我给的两个建议吗?如果还是不行,请告诉我发生了什么情况,先试一下。 - D-eptdeveloper
我按照你的建议做了一切。再次测试,一切都正常。我的表格视图已经更新并显示了正确的订单,但分段控件没有更新它的视图。 - Joris416
显示剩余3条评论
1个回答

7

reloadData将重新加载tableView,并且在重新加载tableView时所有的headerViews也将被重新加载。当tableView被重新加载后,会有一个新的header。此时你看到的UISegmentedControl不是你所点击的那个。

创建一个实例变量来保存你选择的索引。

@implementation .. {
    NSInteger selectedIndex;
}

创建视图时,恢复已保存的索引。
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    /* ... */
    control = [[UISegmentedControl alloc] initWithItems:itemArray];
    control.selectedSegmentIndex = selectedIndex;
    /* ... */
}

当改变分段控件时保存索引

- (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:,因为点击已经设置了索引。对于UISegmentedControl,reloadInputViews是完全无用的。但我猜这段代码只是因为它不起作用而被添加的。别忘了把它删掉 ;-)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接