6

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

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

谢谢你的帮助。

4

10 回答 10

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];

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

于 2013-09-02T13:24:33.183 回答
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];
于 2016-02-19T14:08:56.040 回答
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];

}
于 2016-05-24T07:28:00.950 回答
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];
        }
    }
}

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

于 2013-09-11T08:30:44.070 回答
1

我想出了一个非常简单的方法来解决这个问题。我的示例是 2 个按钮,但您可以轻松地为其他按钮添加更多 if 语句。将所有按钮作为属性连接到 .h 文件并命名它们(我做了 button1 和 button2)。将以下代码放在您的 .m 文件中并将其(通过情节提要)连接到所有按钮。确保在设置按钮时为正常的 UIControlStateNormal 和 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];
    }

}
于 2015-04-06T20:21:06.250 回答
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];
        }
    }
}
于 2013-09-02T13:19:38.260 回答
0

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

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

@class MyCustomClass

@interface SomethingThatUsesMyCustomClass : UIViewController

@property (nonatomic, strong) MyCustomClass *mcc;

@end

然后#import.m 文件中的标题:

#import "MyCustomClass.h"

@implementation SomethingThatUsesMyCustomClass

-(MyCustomClass *)mcc
{
   // whatever
}

@end

这种方法将防止由#import循环引起的错误。

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

于 2013-09-02T13:26:03.880 回答
0

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

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

你可以在这里找到它

https://github.com/MWaly/MWButtonExamples

确保安装 cocoa pods 文件,因为我们需要此示例的“ReactiveCocoa”和“BlocksKit”

我们将使用两个主要类

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

创建按钮时,还会使用该属性创建对 viewController 的弱引用

@property (weak) ViewController *ownerViewController ;

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

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

    } forControlEvents:UIControlEventTouchUpInside];

现在在 ViewController 中为每个触摸的按钮调用 callBackButtonBlock 将被触发,如果适用,它将更改其当前选择的按钮

__weak __typeof__(self) weakSelf = self;

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

在 MWCustomButton 类中,它将侦听其 ownerViewController 的“currentSelectedButton”属性的任何更改,并使用我们良好的 Reactive Cocoa 根据它更改其选择属性

 ///Observing changes to the selected button
    [[RACObserve(self, ownerViewController.currentSelectedButton) distinctUntilChanged] subscribeNext:^(MWCustomButton *x) {
            self.selected=(self==x);
    }];

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

于 2015-04-07T00:33:44.800 回答
0

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

斯威夫特 3 方式:

func buttonPressed(sender: UIButton) {
    for view in view.subviews {
        if view is UIButton && view != sender {
            (view as! UIButton).isSelected = false
        }
    }
    sender.isSelected = true
}
于 2017-07-31T15:56:41.097 回答
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!
于 2020-09-26T06:30:38.750 回答