Objective-C: массив UIButtons

Если у меня есть большое количество кнопок, настроенных в Interface Builder, как я могу поместить их в массив с помощью кода?

Например, если у меня три кнопки и в файле интерфейса я их определяю:

@property (nonatomic, retain) IBOutlet UIButton *button1;
@property (nonatomic, retain) IBOutlet UIButton *button2;
@property (nonatomic, retain) IBOutlet UIButton *button3;

Если я хочу переименовать каждую из этих кнопок, чтобы сказать «Привет», я хочу иметь возможность объединить их в массив, а затем использовать такую ​​функцию, как:

for (int i = 0; i < someArray.count; i++)
{
    someArray[i].text = @"Hello";
}

Может ли кто-нибудь предоставить информацию о том, как это достигается (если это возможно)?

Спасибо


person achiral    schedule 15.09.2011    source источник
comment
Самое простое решение — создавать кнопки в коде, а не в Interface Builder. Есть и другие способы сделать это, но ни один из них не является особенно красивым.   -  person EricS    schedule 15.09.2011


Ответы (5)


Если предположить, что кнопки в IB правильно подключены к свойствам IBOutlet, то это так же просто, как:

NSArray *buttonArray = [[NSArray alloc] initWithObjects:button1,button2,button3,nil];
person ennuikiller    schedule 15.09.2011
comment
Это то, что я надеюсь сделать. Я не могу проверить это в данный момент, но надеялся написать это, прежде чем я вернусь домой, чтобы проверить это. Если бы это было так просто, то это было бы замечательно! Спасибо. - person achiral; 15.09.2011
comment
Хотя это должно работать нормально - я думаю, что решение IBOutletCollection от @Lachlan заслуживает внимания и может быть более подходящим. Это позволяет вам делать проводку прямо в конструкторе интерфейсов. - person Paul.s; 15.09.2011
comment
Один вопрос, может кто прояснит. Является ли хорошей практикой создание массива из 5 таких кнопок? UIButton *buttons[5];, а затем используйте кнопку [0] = ... . Также в сравнениях используйте if (button[0] == currentButton) ... - person Petrescu Silviu; 16.10.2015

Другой подход заключается в подключении кнопок к NSArray в Interface Builder.

@property (nonatomic, retain) IBOutletCollection(UIButton) NSArray *buttons;
person Lachlan Roche    schedule 15.09.2011
comment
0o0o Сегодня я узнал кое-что новое. Я никогда не знал, что это можно сделать. классно! Спасибо, что поделился - person Pavan; 12.08.2012
comment
Имейте в виду, что массив не упорядочен в раскадровках, однако он упорядочен в файлах nib (xib). - person Vahram Dodoryan; 17.08.2013

Следующий код добавит 5 кнопок, каждая с новым тегом, а также свяжет их с событием. Кнопки будут размещены рядом с отступом 5px:

Если вы планируете получить доступ к кнопке за пределами области for{} ниже, вы можете определить свою кнопку в своем заголовке, в противном случае вы можете определить ее внутри области. UIButton * settButton;

.m

CGFloat staticX         = 5;    // Static X for all buttons.
CGFloat staticWidth     = 60;   // Static Width for all Buttons. 
CGFloat staticHeight    = 56;   // Static Height for all buttons.
CGFloat staticPadding   = 5;    // Padding to add between each button.

for (int i = 0; i < 5; i++) 
{
    settButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [settButton setTag:i];
    [settButton setFrame:CGRectMake((staticX + (i * (staticHeight + staticPadding))),5,staticWidth,staticHeight)];
    [settButton setImage:[UIImage imageNamed:[NSString stringWithFormat:@"%i.png",i]] forState:UIControlStateNormal];
    [settButton addTarget:self action:@selector(buttonEvent:) forControlEvents:UIControlEventTouchDown];
    [settButtonView addSubview: settButton];
}
[self.view addSubview: settButtonView];
person WrightsCS    schedule 15.09.2011
comment
Полезный пост. Я думаю, что может быть опечатка. Должен ли кадр x основываться на ширине: [settButton setFrame:CGRectMake((staticX + (i * (staticWidth + staticPadding))),5,staticWidth,staticHeight)]; - person DenVog; 29.11.2014
comment
Это действительно зависит от вашего использования для этого. Это не фрагмент OOTB, вам нужно заставить его работать на вас; необходимо изменить рамку, чтобы она лучше всего подходила для вашей ситуации. - person WrightsCS; 01.12.2014
comment
@WrightsCS мои требования отличаются, но ваш ответ действительно помог мне решить мою проблему. Большое спасибо! - person Mihir Oza; 07.05.2020

Поскольку вы создали кнопки непосредственно в Interface Builder, не можете ли вы просто установить их прямо в коде?

Более общее решение было бы примерно таким... если я предполагаю две вещи: что все они являются подвидами представления UIViewController и что эти UIButtons являются единственными UIButtons в этом представлении, вы можете что-то сделать нравится:

for (UIView *aView in [self.view subviews]) {
   if ([aView isKindOfClass:[UIButton class]) {
      UIButton *aButton = (UIButton *) aButton;
      [aButton setTitle:@"Hello" forState:UIControlStateNormal];
   }
}
person Matthew Gillingham    schedule 15.09.2011

Я думаю, что проще всего создать одну кнопку, которую вы будете инициализировать и добавлять в изменяемый массив:

in *.m:

UIButton *buttonChar;

в вашей функции:

buttonArray = [[NSMutableArray alloc] init];

for (int i=0; i<lenghtWord; i++) {
    buttonChar = [[UIButton alloc] initWithFrame:CGRectMake(.2*size.height+(float)i*charFontSize, .5*size.width, charFontSize, charFontSize)];
    buttonChar.tag = i;

    [buttonChar setTitleColor:[UIColor blackColor] forState:(UIControlStateNormal)];
    [buttonChar setTitle:[[NSString alloc] formatWithString:@"Button %d",i] forState:UIControlStateNormal];
    buttonChar.titleLabel.font = [UIFont boldSystemFontOfSize:15];
    buttonChar.titleLabel.textAlignment = UITextAlignmentCenter;
    buttonChar.layer.cornerRadius = 5;
    buttonChar.layer.masksToBounds = YES;
    buttonChar.layer.borderWidth = 1;
    buttonChar.layer.borderColor = [[UIColor blackColor] CGColor];
    [buttonChar setBackgroundColor:[UIColor whiteColor]];
    [buttonChar addTarget:self action:@selector(buttonAction:withEvent:) forControlEvents:UIControlEventTouchDragInside];
    [buttonArray addObject:buttonChar];
}

кнопки доступны через:

[[buttonArray objectAtIndex:j] setTitle:@" " forState:UIControlStateNormal];

Поскольку опция тега также заполнена, я всегда могу сказать, какая кнопка из массива была нажата, если она была отображена (buttonAction:withEvent:)

Ваше здоровье

person carlos    schedule 28.05.2013