放置在tableView标头中时,UISegmentedControl表现异常

时间:2011-09-19 08:50:47

标签: iphone objective-c ios uitableview uisegmentedcontrol

我在实现段控件时遇到了一些问题。因为我希望它是一个固定的标题,所以当我滚动我总能看到它,我已经在

中实现了它

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

直到这里一切都很好,出现了分段控制。问题是单击细分时。尽管调用了使用选择器实现的函数并且段控件具有正确的selectedSegmentIndex,但除了最初使用

设置的段之外,段不会突出显示。 sortControl.selectedSegmentIndex = 0;中的

viewForHeaderInSection。此段交互突出显示且不突出显示(再次按下时)。另一个奇怪的事情是,当我按下其他段时,0处的段将突出显示。

以下是viewForHeaderInSection的完整代码:

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

     UIColor *tintColor = [UIColor colorWithRed:241.0/255 green:78.0/255 blue:35.0/255 alpha:1];



    sortControl = [[UISegmentedControl alloc] initWithItems:
                   [NSArray arrayWithObjects:@"Distance", @"Rating", @"Name", nil]];
    sortControl.segmentedControlStyle = UISegmentedControlStyleBar;

        sortControl.tintColor = tintColor;
    sortControl.frame = CGRectMake(20, 20, 280, 35);
    sortControl.selectedSegmentIndex = 0;
    [sortControl addTarget:self action:@selector(sortChanged) forControlEvents:UIControlEventValueChanged];

        UIView *view=[UIView new];
        view.frame = CGRectMake(0, 0, 320, 70);
        view.backgroundColor =[UIColor blueColor];
        [sortControl setEnabled:YES forSegmentAtIndex:0];
        [sortControl setEnabled:YES forSegmentAtIndex:1];
        [sortControl setEnabled:YES forSegmentAtIndex:2];


        view.userInteractionEnabled = YES;

        [view addSubview:sortControl];




        return view;

    }

2 个答案:

答案 0 :(得分:2)

这是因为您设置了sortControl.momentary = YES;

此属性使SegmentedControl的每个片段的行为类似于“瞬时按钮”,这意味着当触摸片段时,片段会突出显示,然后触发事件,当您停止触摸时,它会恢复到原始状态。

删除此行(或将此属性设置为NO)可以解决您的问题。

答案 1 :(得分:2)

你有两种问题: 第一个是由AliSoftware在之前的回复中出现的:你必须将瞬时属性设置为NO以避免闪烁问题。

但主要问题在于您使用

tableView:viewForHeaderInSection:
委托方法的方式。在此方法中,每次重新创建相同的视图时,会产生两个不良影响: - 第一个在您的应用程序中可见:分段控件重新初始化,所选按钮设置为第一个(索引0) - 第二个是每次表视图调用方法时都会添加内存泄漏。考虑到这个方法被表视图多次调用并且超出了你的控制范围:基本上每当标题在屏幕外滚动然后重新进入时,表需要重新生成视图并再次调用该方法。在您的代码中,段创建但从未泄漏,因此泄漏。

此问题的解决方案是为标头定义单个实例,将其初始设置为nil,然后检查它是否为nil。如果nil创建它,如果不使用以前生成的实例。 另一种可能的方法是在下面的代码中。因此,创建一个静态实例并使用GCD的dispatch_once仅在第一次创建分段控件。在这种情况下,您将永远不会丢失当前控制状态,因为它将在每个标头调用中重用。您还可以通过在dispatch_once块中移动整个标头UIView创建来提高性能,这样每次都可以避免额外的分配。



static UISegmentedControl *sortControl;

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

    UIColor *tintColor = [UIColor colorWithRed:241.0/255 green:78.0/255 blue:35.0/255 alpha:1];


    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sortControl = [[UISegmentedControl alloc] initWithItems:
                        [NSArray arrayWithObjects:@"Distance", @"Rating", @"Name", nil]];
        sortControl.segmentedControlStyle = UISegmentedControlStyleBar;

        sortControl.tintColor = tintColor;
        sortControl.frame = CGRectMake(20, 20, 280, 35);
        sortControl.selectedSegmentIndex = 0;

    });

    [sortControl addTarget:self action:@selector(sortChanged) forControlEvents:UIControlEventValueChanged];

    UIView *view=[UIView new];
    view.frame = CGRectMake(0, 0, 320, 70);
    view.backgroundColor =[UIColor blueColor];
    sortControl.momentary = NO;
    [sortControl setEnabled:YES forSegmentAtIndex:0];
    [sortControl setEnabled:YES forSegmentAtIndex:1];
    [sortControl setEnabled:YES forSegmentAtIndex:2];


    view.userInteractionEnabled = YES;

    [view addSubview:sortControl];




    return view;

}
相关问题