我有一个包含按钮的表视图。我想做的是,我想让点击的按钮保持在选中状态,直到它们再次被点击(这应该是取消选择它们)。老实说,这就像一个复选框。很简单,对吧
但问题是,由于使用单个布尔标志来查看按钮是第一次按下还是第二次按下,事情变得一团糟。例如,我单击按钮一,然后单击按钮二,现在我想取消选择按钮一,所以我再次单击它,但它没有取消选择,因为Flag设置为YES(尽管它在再次单击时确实取消选择)。
有没有办法避免这种情况,只需点击一下就可以达到预期的效果?屏幕截图:http://i60.tinypic.com/1z51653.png这就是我正在做的:
-(void) btnStateChanged: (UIButton *) btnProblem
{
static BOOL btnPressedFirstTime=YES;
if(btnProblem.selected==YES || btnProblem.highlighted==YES)
{
if(btnPressedFirstTime==YES)
{
[btnProblem setBackgroundImage:[UIImage imageNamed:@"sc123_button_hover"] forState: UIControlStateNormal];
btnPressedFirstTime=NO;
}
else if(btnPressedFirstTime==NO)
{
[btnProblem setBackgroundImage:[UIImage imageNamed:@"sc123_button"] forState: UIControlStateNormal];
btnPressedFirstTime=YES;
}
}
[[NSUserDefaults standardUserDefaults] synchronize];
}
启动一个数组,其中包含描述每个按钮状态的对象。假设你有10个按钮:
NSMutableArray *buttonStates = [NSMutableArray new];
for (int i = 0; i < 10; i++)
{
[buttonStates addObject:[NSNumber numberWithBool:NO]];
}
现在,当您单击按钮编号2时(请注意,您必须用其行的索引标记按钮):
- (void)btnStateChanged:(UIButton *)btnProblem
{
int buttonIndex = btnProblem.tag;
BOOL state = [[buttonStates objectAtIndex:buttonIndex] boolValue];
[buttonStates replaceObjectAtIndex:buttonIndex withObject:[NSNumber numberWithBool:!state]];
}
这样你就能知道每个按钮的状态。
使用一个数组来存储所选对象,也可以说是点击按钮。。。在点击调用的函数中,检查该按钮是否在数组中。。并相应地更改图像,例如-
NSMutableArray *selectedBtnArr = [[NSMutableArray alloc]init];
if ([selectedBtnArr containsObject:btnProblem]) {
[btnProblem setBackgroundImage:[UIImage imageNamed:@"sc123_button"] forState: UIControlStateNormal];
[selectedBtnArr removeObject:btnProblem];
}else{
[btnProblem setBackgroundImage:[UIImage imageNamed:@"sc123_button_hover"] forState: UIControlStateNormal];
[selectedBtnArr addObject:btnProblem];
}
或者,如果您不想为任务使用数组,请使用标记。。设置按钮标签,如1,2,3..10我假设你有10个按钮。并使用此代码来识别是否选择了按钮-
if (btnProblem.tag < 100) {
[btnProblem setBackgroundImage:[UIImage imageNamed:@"sc123_button_hover"] forState: UIControlStateNormal];
btnProblem.tag = btnProblem.tag+100;
}else{
[btnProblem setBackgroundImage:[UIImage imageNamed:@"sc123_button"] forState: UIControlStateNormal];
btnProblem.tag = btnProblem.tag-100;
}
这正是NSMutableIndexSet
的作用。它实际上是布尔标志的稀疏数组。
您可以通过调用addIndex:
来设置和调用removeIndex:
来取消设置任何标志。使用NSIndexSet
的containsIndex:
测试其中一个标志的值。
该代码看起来很像@freshking的NSMutableArray代码,但你会有更少的boolValue和numberWithBool:faffing。
为什么不将UIButton子类化为您想要的视觉行为呢
毕竟,按钮是已经在跟踪其状态的东西。
@interface CBBCheckBoxLikeButton : UIButton
@end
@implementation CBBCheckBoxLikeButton
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
[self communInit];
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
[self communInit];
return self;
}
- (void)communInit
{
// The image setting could be done from the outside ot the class
[self setBackgroundImage:[[UIImage imageNamed:@"grayPixel"] resizableImageWithCapInsets:UIEdgeInsetsZero] forState:UIControlStateNormal];
[self setBackgroundImage:[[UIImage imageNamed:@"greenPixel"] resizableImageWithCapInsets:UIEdgeInsetsZero] forState:UIControlStateSelected];
self.selected = NO;
}
- (void)setHighlighted:(BOOL)highlighted
{
[self updateSelectedStateForHighlighted:highlighted];
[super setHighlighted:highlighted];
}
- (void)updateSelectedStateForHighlighted:(BOOL)highlighted
{
if (highlighted)
self.selected = !self.selected;
}
@end
但是,您仍然会遇到处理TableView重用机制的问题,以使您的视觉与按钮保持同步。但这可能反映在您的数据模型中。
因此,在- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
方法中,您只需要执行以下操作:cell.button.selected = dataForCell.wasButtonSelected;
请注意,该按钮需要是一个"自定义"按钮,"系统"按钮的行为会很奇怪。您可以/应该提供一种可以避免客户端代码陷阱的创建方法。
感谢大家的回复。我尝试了你的一些答案,但可能是因为我没有正确理解,它对我不起作用。这就是我所想的,它对给定的问题很有效。我以前应该想到的,我真傻。标签!这正是我所需要的。
-(void) btnStateChanged: (UIButton *) btnProblem
{
if (btnProblem.tag == 1000) {
[btnProblem setBackgroundImage:[UIImage imageNamed:@"sc123_button_hover"] forState: UIControlStateNormal];
btnProblem.tag = 1001;
}else if(btnProblem.tag == 1001) {
[btnProblem setBackgroundImage:[UIImage imageNamed:@"sc123_button"] forState: UIControlStateNormal];
btnProblem.tag = 1000;
}