#iphone #objective-c #xcode #loops #uibutton
#iPhone #objective-c #xcode #циклы #uibutton
Вопрос:
В моем файле .h есть 39 разных переменных UIButton, но я хотел бы добавить каждую из них в массив без необходимости вводить одно и то же 39 раз.
Есть ли способ, которым я мог бы сделать это в цикле for?
Кнопкам присвоены соответствующие имена: btn1, btn2, btn3 и т.д.
Ответ №1:
Возможно, вы захотите отказаться от 39 кнопок в вашем заголовочном файле и вместо этого иметь один массив. Я подозреваю, что вы хотите использовать ссылки вручную, чтобы вы могли воспользоваться преимуществами Interface Builder для управления событиями и макетом. Я предлагаю сделать что-то немного другое.
Создайте единственное свойство — an NSMutableArray
. Затем, когда представление загрузится, создайте кнопки на лету.
Чтобы получить доступ к кнопке, используйте что-то вроде [self.arrayOfButtons objectAtIndex:38];
. (В случае 39 кнопок это вернет последнюю кнопку.);`
Чтобы создать кнопку, вы используете следующее:
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
Обратите внимание, что вы передаете фрейм init
метода вашей кнопки. Рамка вашей кнопки будет начинаться в верхнем левом углу ее контейнера, и ваша кнопка будет иметь площадь 100 пикселей. Фрейм является экземпляром CGRect
. (Вы создаете цикл CGRect
путем вызова функции CGRectMake(x,y,width,height)
.
Чтобы создать 39 кнопок, вам может потребоваться выполнить цикл следующим образом, учитывая массив для хранения кнопок, myButtons
и предопределенные numberOfButtons
переменные и размерность:
for(int i=0;i<numberOfButtons;i ){
//Create the button
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(x,y,width, height)];
//Store the button in our array
[self.myArray addObject:button];
//Release the button (our array retains it for us)
[button release];
}
Конечно, вам нужно будет установить уникальные значения для x
, y
width
и height
для каждой кнопки, иначе все они будут перекрываться. После того, как вы создали свои кнопки, вы можете что-то с ними делать, например, устанавливать ярлык или показывать их на экране. Чтобы отобразить их на экране, вы можете сделать что-то вроде этого:
for(UIButton *button in self.myButtons){
//add the button to the view
[self.view addSubview:button];
}
Конечно, просто добавлять кнопки на экран бесполезно. Вы должны быть в состоянии заставить их что-то делать. Чтобы добавить действие к кнопке, вы можете использовать:
[button addTarget:self action:@selector(someMethod:) forControlEvents:UIControlEventTouchDown];
В первой части addTarget:self
говорится, что этот контроллер представления обрабатывает событие, которое вы собираетесь попросить его обработать. action:@selector(someMethod:)
указывает классу, какой метод выполнять при возникновении события. Затем forControlEvents:UIControlEventTouchDown
говорится, что указанный класс должен выполнять указанный метод при нажатии на кнопку.
Итак, в вашем заголовке:
#import <UIKit/UIKit.h>
@interface MyClass :UIViewController{
NSMutableArray *myButtons;
}
@property (nonatomic, retain) NSMutableArray *myButtons;
//Use UIButton as the sender type if you want
- (void)someMethod:(id)sender;
// ... Other code can go here of course
@end
И в вашей реализации вы можете использовать это:
#import MyClass.h
@implementation MyClass
- (id)init{
self = [super init];
if(self){
NSMutableArray *temp = [[NSMutableArray alloc] init];
self.myButtons = temp;
[temp release];
}
return self;
}
- (void)viewDidLoad{
//
// Create the buttons
//
for(int i=0;i<numberOfButtons;i ){
//Create the button
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(x,y,width, height)];
//You may want to set button titles here
//or perform other customizations
//Store the button in our array
[self.myArray addObject:button];
//Release the button (our array retains it for us)
[button release];
}
//
// Show the buttons onscreen
//
for(UIButton *button in self.myButtons){
//add the button to the view
[self.view addSubview:button];
//add the action
[button addTarget:self action:@selector(someMethod:) forControlEvents:UIControlEventTouchDown];
}
}
- (void)someMethod:(id)sender{
//Do something when the button was pressed;
}
- (void)dealloc{
[self.myButtons release];
[super dealloc];
}
@end
Теперь вы можете перейти в button paradise, не используя Interface Builder в самолете. Запускайте UIButton с удовольствием!
Комментарии:
1. Какой блестящий подход!! Я использую UIScrollView, поэтому изначально установить рамки было бы сложнее. Большое спасибо, что потратили на это свое время, это действительно ценно!
2. Спасибо. На самом деле, установить рамки в UIScrollView не так сложно. UIScrollView имеет свойство, называемое contentSize. Фреймы основаны на фрейме родительского представления. Просто добавьте их в режим прокрутки.
3. Кроме того, метод foreach не существует в objective-c.
4. Попробуйте опубликовать новый вопрос и пример кода, показывающий, что вы пробовали, а что не работает b
Ответ №2:
Вот так:
NSMutableArray *arr = [NSMutableArray array];
for(int i = 1; i <= 39; i) {
[arr addObject:[self valueForKey:[NSString stringWithFormat:@"btn%d", i]]];
}
Ответ №3:
for(int i=1; i<totalButtonCount; i ) {
NSString *buttonClassName = [NSString stringWithFormat:@"btn%d", i];
[[NSClassFromString(buttonClassName) alloc] init];
//add to array
}
Редактировать: после повторного прочтения вашего вопроса это может быть не то, что вы просите. Я думал, вы хотите создать кучу экземпляров похожих классов.
Комментарии:
1. Шериман возможно ли, что я написал комментарий перед редактированием? 🙂
2. Я сделал это немедленно. Простите за мой предыдущий тон, вчерашний день был … напряженным. 😉
3. не беспокойтесь. В любом случае, для протокола, я ответил довольно скоро после того, как вы дали ответ, и печатал со своего iPhone, так что, возможно, я даже не мог увидеть редактирование, пока не закончил печатать; p Да, повторение блуда — это некоторые типы, взятые с iPhone, насколько это возможно, хе-хе 🙂
Ответ №4:
Вы могли бы создать метод получения, названный после каждой кнопки, а затем вызвать [self valueForKey:]; для каждой, но что-то здесь просто кричит «ужасный дизайн» 🙂
Комментарии:
1. Полностью согласен. Что-то вонючее.
Ответ №5:
Программирование значений ключей — ваш друг
В принципе, вы можете выполнять цикл и создавать свои кнопки, и пока у вас есть определенные свойства для ваших кнопок, вы можете.
[self setObject:newButton forKey@"button1"];
где button1 — это та же строка, что и имя вашей переменной.