选择一个UIButtons时取消选择

时间:2013-09-02 13:16:37

标签: ios objective-c uibutton

我在游戏中设置了八(8)个UIButtons。选择一个时,它会显示它已被选中,如果再次单击它,它将显示为未选中。但是,我想这样做,以便当您选择一个按钮并选择其他七(7)中的任何一个时,它们将被取消选择。

我知道如何通过使用[buttonName setSelected:NO]来做到这一点,但问题是我无法将buttonOne传递给buttonTwo,如果buttonTwo已经传递给buttonOne,因为我已经在buttonOne中导入了buttonTwo的头文件。如果我有两个标题互相导入,它会抛出一个解析错误。我已经坚持了一段时间了,并希望有人可以解决我的问题。

感谢您的帮助。

10 个答案:

答案 0 :(得分:12)

获取当前按钮的父视图并遍历其中的所有按钮,取消选中所有按钮。然后,选择当前的那个。

// Unselect all the buttons in the parent view
for (UIView *button in currentButton.superview.subviews) {
    if ([button isKindOfClass:[UIButton class]]) {
        [(UIButton *)button setSelected:NO];
    }
}

// Set the current button as the only selected one
[currentButton setSelected:YES];

注意:正如评论中所建议的那样,您可以保留一组按钮,并按照上述代码与父视图的子视图相同的方式进行检查。如果包含按钮的视图中包含许多其他子视图,这将提高代码的性能。

答案 1 :(得分:2)

我知道回答这个问题为时已晚,但我只用了很少的代码就完成了。这是我做的:

NSArray *arrView = self.view.subviews;
    for (UIButton *button in arrView) {
        if ([button isKindOfClass:[UIButton class]]) {
            [((UIButton *) button) setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        }
    }
[button1 setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];

答案 2 :(得分:2)

简单的方法。

-(void)buttonSelected:(id)sender{
    UIButton *currentButton = (UIButton *)sender;
    for(UIView *view in self.view.subviews){

        if([view isKindOfClass:[UIButton class]]){

            UIButton *btn = (UIButton *)view;
            [btn setSelected:NO];
        }
    }

    [currentButton setSelected:YES];

}

答案 3 :(得分:1)

我实际上通过阅读你们所有人的输入来创建答案,我非常感谢你们。在这篇文章之前,我不知道UIButton类的tag属性。

我创建了自己的UIButton子类,我们称之为CustomUIButton.m。我创建了一个NSMutableArray属性,用于存储按钮,我将其称为customButtonArray

当我创建按钮时,我设置了tag属性,并将按钮添加到父视图控制器上的本地数组。在创建了我想要的所有按钮后,我设置了customButtonArray,如下所示:

// Initialize buttonHolderArray
NSMutableArray *buttonHolderArray = [[NSMutableArray alloc] init];

// Create a button
CustomUIButton *newButton = [[CustomUIButton alloc] initWithFrame:CGRectMake(10, 10, 50, 30)];
newButton.tag = 1;
[newButton setImage:[UIImage imageNamed:@"newButtonUnselected" forControlState:UIControlStateNormal]];
[buttonHolderArray addObject:newButton];

// Create additional buttons and add to buttonHolderArray...
// using different numbers for their tags (i.e. 2, 3, 4, etc)

// Set customButtonArray property by iterating through buttonHolderArray
NSInteger buttonCount = [buttonHolderArray count];

for (int i = 0; i < buttonCount; i++)
{
   [[buttonHolderArray objectAtIndex:i] setCustomButtonArray:buttonHolderArray];
}

要取消选择在调用其他按钮handleTap:时选择的任何其他按钮,我会遍历子类主文件中的customButtonArray并将selected属性设置为NO。我还从我手动填充图像的另一个数组属性中设置了正确的图像,我这样做,因此每次按下按钮时都不必填充数组。最后,取消选中所有其他按钮,如下所示:

// Populate two arrays: one with selected button images and the other with
// unselected button images that correspond to the buttons index in the 
// customButtonArray
NSMutableArray *tempSelectedArray = [[NSMutableArray alloc] init];
[tempSelectedArray addObject:[UIImage imageNamed:@"newButtonSelected"]];
// Add the other selected button images...
// Set the property array with this array
[self setSelectedImagesArray:tempSelectedArray];

NSMutableArray *tempUnselectedArray = [[NSMutableArray alloc] init];
[tempUnselectedArray addObject:[UIImage imageNamed:@"newButtonUnselected"]];
// Add the other unselected button images...
// Set the property array with this array
[self setUnselectedImagesArray:tempUnselectedArray];

- (void)handleTap:(UIGestureRecognizer *)selector
{
    // Get the count of buttons stored in the customButtonArray, use an if-elseif
    // statement to check if the button is already selected or not, and iterate through
    // the customButtonArray to find the button and set its properties
    NSInteger buttonCount = [[self customButtonArray] count];

    if (self.selected == YES)
    {
        for (int i = 0; i < buttonCount; i++)
        {
            if (self.tag == i)
            {
                [self setSelected:NO];
                [self setImage:[[self unselectedImagesArray] objectAtIndex:i] forControlState:UIControlStateNormal];
            }
        }
    }
    else if (self.selected == NO)
    {
        for (int i = 0; i < buttonCount; i++)
        {
            if (self.tag == i)
            {
                [self setSelected:NO];
                [self setImage:[[self selectedImagesArray] objectAtIndex:i] forControlState:UIControlStateNormal];
            }
        }
    }

    for (int i = 0; i < buttonCount; i++)
    {
        if (self.tag != i)
        {
            [self setSelected:NO];
            [self setImage:[[self unselectedImagesArray] objectAtIndex:i] forControlState:UIControlStateNormal];
        }
    }
}

感谢所有有用的信息,我想应该分享我提出的最终答案,以帮助其他遇到此问题的人。

答案 4 :(得分:0)

这里最简单的方法是让父UIView按钮打开并迭代它。以下是我的代码中的一个简单示例:

for (UIView *tmpButton in bottomBar.subviews)
{
  if ([tmpButton isKindOfClass:[UIButton class]])
  {
       if (tmpButton.tag == 100800)
       {
           tmpButton.selected = YES;
           [tmpButton setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];
           [tmpButton setTitleColor:[UIColor greenColor] forState:UIControlStateHighlighted];

       }else{

          tmpButton.selected = NO;
          [tmpButton setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
          [tmpButton setTitleColor:[UIColor redColor]  forState:UIControlStateHighlighted];
        }
    }
}

答案 5 :(得分:0)

回答“如果我有两个标题互相导入,它会抛出一个解析错误”......

你应该尽量避免在.h文件中使用#import,而是声明你想要用作前向类声明的任何内容:

@class MyCustomClass

@interface SomethingThatUsesMyCustomClass : UIViewController

@property (nonatomic, strong) MyCustomClass *mcc;

@end

然后{。{1}} .m文件中的标题:

#import

这种方法可以防止#import "MyCustomClass.h" @implementation SomethingThatUsesMyCustomClass -(MyCustomClass *)mcc { // whatever } @end 周期引起的错误。

虽然我必须说我同意SergiusGee关于这个设置感觉有点奇怪的问题的评论。

答案 6 :(得分:0)

我找到了解决这个问题的简单方法。我的示例是2个按钮,但您可以轻松添加更多if语句以添加其他按钮。将所有按钮连接到.h文件作为属性并命名它们(我做了button1&amp; button2)。将以下代码放在.m文件中并将其(通过故事板)连接到所有按钮。确保在设置按钮时为正常的UIControlStateNormal&amp;设置图像。 UIControlStateSelected或这不会工作。

- (IBAction)selectedButton1:(id)sender {

if ([sender isSelected]) {
    [sender setSelected:NO];

    if (sender == self.button1) {
        [self.button2 setSelected:YES];
    }
    if (sender == self.button2) {
        [self.button1 setSelected:YES];
    }
}

else
{
    [sender setSelected:YES];

    if (sender == self.button1) {
        [self.button2 setSelected:NO];
    }
    if (sender == self.button2) {
        [self.button1 setSelected:NO];
    }

}

答案 7 :(得分:0)

您是否尝试使用ReactiveCocoa框架并为您的代码添加一些块,这不是最简单的方法,但我会说当您有多个依赖项并且非常适合扩展时它是最有效的

我创建了一个小项目,使用我建议的方法解决您的问题(我尝试将其改编为良好的旧MVC模式,而不是我喜欢的MVVM)

你可以在这里找到它

https://github.com/MWaly/MWButtonExamples

确保根据需要安装cocoa pods文件&#34; ReactiveCocoa&#34;和&#34; BlocksKit&#34;对于此示例

我们将使用两个主要类

ViewController =&gt; viewController对象显示按钮 MWCustomButton =&gt;处理事件的自定义UIButton

创建按钮时,还会使用属性

创建对viewController的弱引用
@property (weak) ViewController *ownerViewController ;

事件将在blocksKit bk_addEventHandler方法的帮助下处理,并将其传递给ViewController的块(selectedButtonCallBackBlock)

 [button bk_addEventHandler:^(id sender)
    {
        self.selectedButtonCallBackBlock(button);

    } forControlEvents:UIControlEventTouchUpInside];

现在在ViewController中触摸的每个按钮都会被触发,如果适用的话,它会更改当前选中的按钮

__weak __typeof__(self) weakSelf = self;

self.selectedButtonCallBackBlock=^(MWCustomButton* button){
     __typeof__(self) strongSelf = weakSelf;
    strongSelf.currentSelectedButton=button;
      };

在MWCustomButton类中,它会监听&#34; currentSelectedButton&#34;的属性中的任何更改。它的ownerViewController,并将使用我们良好的Reactive Cocoa

根据它更改其选择属性
 ///Observing changes to the selected button
    [[RACObserve(self, ownerViewController.currentSelectedButton) distinctUntilChanged] subscribeNext:^(MWCustomButton *x) {
            self.selected=(self==x);
    }];

我认为这可以解决您的问题,您的问题可能会以更简单的方式解决,但我相信使用这种方法会更具可扩展性和清洁性。

答案 8 :(得分:0)

循环显示父视图中的所有视图。检查它是否是UIButton(或您的自定义按钮类)而不是发件人。将所有视图设置为isSelected为false。完成循环后,将发送方按钮设置为true。

Swift 3方式:

func buttonPressed(sender: UIButton) {
    for view in view.subviews {
        if view is UIButton && view != sender {
            (view as! UIButton).isSelected = false
        }
    }
    sender.isSelected = true
}

答案 9 :(得分:0)

雨燕4

  //Deselect all tip buttons via IBOutlets

  button1.isSelected = false
  button2.isSelected = false
  button3.isSelected = false

  //Make the button that triggered the IBAction selected.
  sender.isSelected = true

  //Get the current title of the button that was pressed.
    let buttonTitle = sender.currentTitle!