Iphone UISegmentControl放置在tableView';s头
我在实现段控制时遇到一些问题。因为我希望它是一个固定的标题,所以当我滚动时,我总能看到它,我已经在Iphone UISegmentControl放置在tableView';s头,iphone,objective-c,ios,uitableview,uisegmentedcontrol,Iphone,Objective C,Ios,Uitableview,Uisegmentedcontrol,我在实现段控制时遇到一些问题。因为我希望它是一个固定的标题,所以当我滚动时,我总能看到它,我已经在 -(UIView*)表格视图:(UITableView*)表格视图标题部分:(NSInteger)部分 一切都很好,直到这里,段控制出现。问题是在单击段时。虽然调用了使用选择器实现的函数,并且段控件具有正确的selectedSegmentIndex,但除了最初使用 sortControl.selectedSegmentIndex=0。此段在高亮显示和非高亮显示时(再次按下时)进行交互。另一件奇怪的
-(UIView*)表格视图:(UITableView*)表格视图标题部分:(NSInteger)部分
一切都很好,直到这里,段控制出现。问题是在单击段时。虽然调用了使用选择器实现的函数,并且段控件具有正确的selectedSegmentIndex,但除了最初使用
sortControl.selectedSegmentIndex=0在<代码>视图ForHeaderin部分中的代码>
。此段在高亮显示和非高亮显示时(再次按下时)进行交互。另一件奇怪的事情是,当我按下其他线段时,0处的线段会高亮显示
以下是查看标题部分的完整代码:
- (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;
}
这是因为您设置了sortControl.instantily=YES代码>
此属性使SegmentedControl的每个段的行为类似于“瞬时按钮”,这意味着当触摸某个段时,该段将高亮显示,然后触发事件,当您停止触摸时,该段将返回其原始状态
删除此行(或将此属性设置为否)应该可以解决您的问题。这是因为您设置了sortControl.instantily=YES代码>
此属性使SegmentedControl的每个段的行为类似于“瞬时按钮”,这意味着当触摸某个段时,该段将高亮显示,然后触发事件,当您停止触摸时,该段将返回其原始状态
删除此行(或将此属性设置为“否”)可以解决您的问题。这里有两种问题:
第一个问题是AliSoftware在之前的回答中提出的:您必须将瞬时属性设置为“否”,以避免闪烁问题
但主要的问题在于您使用委托方法的方式。在这种方法中,每次都要重新创建相同的视图,但会产生两种不良影响:
tableView:viewForHeaderInSection:
-第一个按钮在应用程序中可见:分段控件重新初始化,选定按钮设置为第一个(索引0)
-第二种方法是在每次表视图调用该方法时添加内存泄漏。请注意,该方法被表视图多次调用并从控件中调用:基本上,每当标题在屏幕外滚动,然后重新输入时,表需要重新生成视图并再次调用该方法。在您的代码中,该段已创建,但从未释放,因此会泄漏
这个问题的解决方案是为头定义一个实例,最初将其设置为nil,然后检查它是否为nil。如果为nil,则创建它,如果不是,则使用先前生成的实例。
另一种可能的方法是在下面的代码中。因此,创建一个静态实例,并使用GCD的dispatch_一次性创建分段控件。在这种情况下,您将永远不会丢失当前控件状态,因为它将在每次标头调用时重新使用。您还可以通过将整个头UIView创建移动到dispatch_once块中来提高性能,从而避免每次额外的alloc
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;
}
这里有两种问题:
第一个问题是AliSoftware在之前的回答中提出的:您必须将瞬时属性设置为“否”,以避免闪烁问题
但主要的问题在于您使用委托方法的方式。在这种方法中,每次都要重新创建相同的视图,但会产生两种不良影响:
tableView:viewForHeaderInSection:
-第一个按钮在应用程序中可见:分段控件重新初始化,选定按钮设置为第一个(索引0)
-第二种方法是在每次表视图调用该方法时添加内存泄漏。请注意,该方法被表视图多次调用并从控件中调用:基本上,每当标题在屏幕外滚动,然后重新输入时,表需要重新生成视图并再次调用该方法。在您的代码中,该段已创建,但从未释放,因此会泄漏
这个问题的解决方案是为头定义一个实例,最初将其设置为nil,然后检查它是否为nil。如果为nil,则创建它,如果不是,则使用先前生成的实例。
另一种可能的方法是在下面的代码中。因此,创建一个静态实例,并使用GCD的dispatch_一次性创建分段控件。在这种情况下,您将永远不会丢失当前控件状态,因为它将在每次标头调用时重新使用。您还可以通过将整个头UIView创建移动到dispatch_once块中来提高性能,从而避免每次额外的alloc
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;
}
我已将属性设置为“否”,但它仍然不起作用。该函数仍然被调用,.selectedSegmentIndex也正确,但是除了第一个现在永久高亮显示的段之外,这些段不会高亮显示。如果不使用tintColor怎么办?(可能考虑到您使用的tintColor,高亮显示状态下衍生的颜色与正常状态下衍生的颜色没有什么不同?)实际上,我刚刚意识到,每次进入viewForHeaderInSection
方法时,您都会重新创建segmentedControl!难怪每次都有selectedSegmentIndex=0
属性做作!您应该只创建一次segmentedControl(在viewDidLoad方法中,甚至使用Interface Builder来避免无用的代码),并将其影响到实例变量(或内部@property
)。这样,您就不会每次重新创建不同的segmentedControl,尤其不会将其selectedSegment
重新影响为0!另外一个注意事项:我希望您使用的是新的自动重新登录(ARC)功能(默认情况下,对于新的Xcode4项目为on,而对于使用Xcode3创建的项目为off)。如果