Как мне подключить массив кнопок с синглтоном? - PullRequest
1 голос
/ 05 февраля 2012

Мой appDelegate, в методе didFinishLaunchingWithOptions Я загружаю свой контроллер представления, затем создаю синглтон:

UIViewController *MainWinVC = [[p3VC alloc] init];
[[self window] setRootViewController:MainWinVC];
ansButSingleton *ansButs = [[ansButSingleton alloc] init]; 

ansButSingleton.h выглядит так:

#import <Foundation/Foundation.h>

@interface ansButSingleton : NSObject {

    // View objects:

    UIButton *Ans1;
    UIButton *Ans2;
    UIButton *Ans3;
    UIButton *Ans4;
    UIButton *Ans5;
    UIButton *Ans6;
    UIButton *Ans7;
    UIButton *Ans8;

    // Other objects:

    NSArray *ansButs;

}

@property (strong) UIButton *Ans1, *Ans2, *Ans3, *Ans4, *Ans5, *Ans6, *Ans7, *Ans8;
@property (strong) NSArray *ansButs;

+ (ansButSingleton *) ansButsName;  // Declare class method
@end

и ansButSingleton.m вот так:

#import "ansButSingleton.h"

@implementation ansButSingleton

static ansButSingleton *ansButsName;

@synthesize Ans1, Ans2, Ans3, Ans4, Ans5, Ans6, Ans7, Ans8;
@synthesize ansButs;

//////////////////// instantiate ////////////////////

+ (ansButSingleton *) ansButsName { // class method

    @synchronized(self)
    {
        if (!ansButsName)
            ansButsName = [[ansButSingleton alloc] init];        
        return ansButsName;
    }
}

//////////////////// initialize ////////////////////

- (id)init { // class instance method

    NSLog(@"Initializing answer buttons");

    if (ansButsName) {
        return ansButsName;
    }

    self = [super init];

    if(self) {

        // First initialze the individual buttons

        self.Ans1 = [[UIButton alloc] init];
        [Ans1 setTitle:@"" forState:UIControlStateNormal];
        self.Ans2 = [[UIButton alloc] init];
        [Ans2 setTitle:@"" forState:UIControlStateNormal];
        self.Ans3 = [[UIButton alloc] init];
        [Ans3 setTitle:@"" forState:UIControlStateNormal];
        self.Ans4 = [[UIButton alloc] init];
        [Ans4 setTitle:@"" forState:UIControlStateNormal];
        self.Ans5 = [[UIButton alloc] init];
        [Ans5 setTitle:@"" forState:UIControlStateNormal];
        self.Ans6 = [[UIButton alloc] init];
        [Ans6 setTitle:@"" forState:UIControlStateNormal];
        self.Ans7 = [[UIButton alloc] init];
        [Ans7 setTitle:@"" forState:UIControlStateNormal];
        self.Ans8 = [[UIButton alloc] init];
        [Ans8 setTitle:@"" forState:UIControlStateNormal];

        // Make an array containing the objects: this is the objective-C way!

        self.ansButs = [[NSArray alloc] initWithObjects: Ans1, Ans2, Ans3, Ans4, Ans5, Ans6, Ans7, Ans8, nil];
    }

    NSLog(@"Done initializing answer buttons");

    return self;
}
@end

Это прекрасно работает и работает (пока не очень). Кнопки видны из-за успешной загрузки пера. Однако они не активны, так как я не подключил их к коду (без IBActions).

Вопрос: Как подключить созданные таким образом кнопки к кнопкам в кончике? Если бы это были простые кнопки (а не массив кнопок), я бы создал метод и использовал бы IBAction как часть объявления этого метода. Но этот случай кажется немного другим. А может и нет. Если бы это были метки (что мне и нужно сделать позже), мое чтение заставляет меня поверить, что IBOutletCollection может работать, но я не вижу IBActionCollection. Требуется экспертное руководство! Спасибо.

РЕДАКТИРОВАТЬ ... работая с Робом для реализации его идей. Мой метод viewLoad был скопирован и вставлен из вашего, но, возможно, в нем было что-то, что мне нужно было изменить?

#pragma mark - View lifecycle

 - (void)loadView {
 NSDictionary *externals = [NSDictionary dictionaryWithObject:[AnswerButtons answerButtons]
 forKey:@"answerButtons"];
 NSDictionary *nibOptions = [NSDictionary dictionaryWithObject:externals
 forKey:UINibExternalObjects];
 [self.nibBundle loadNibNamed:self.nibName owner:self options:nibOptions];
 [[AnswerButtons answerButtons] buttonsDidLoad];
 }

Ответы [ 3 ]

1 голос
/ 05 февраля 2012

Есть несколько способов сделать это.Я бы сделал это, подключив соединения синглтона в кончике.Вот как.

Во-первых, давайте исправим одноэлементный класс, чтобы он соответствовал соглашениям по программированию на iOS, и обеспечим поддержку для подключения кнопок в кончике:

AnswerButtons.h

#import <Foundation/Foundation.h>

@interface AnswerButtons : NSObject

@property (strong, nonatomic) IBOutlet UIButton *button1, *button2, *button3, *button4, *button5, *button6, *button7, *button8;
@property (strong, nonatomic, readonly) NSArray *buttons;

+ (AnswerButtons *)answerButtons;

- (void)buttonsDidLoad;

@end

AnswerButtons.m

#import "AnswerButtons.h"

@implementation AnswerButtons

@synthesize button1 = _button1;
@synthesize button2 = _button2;
@synthesize button3 = _button3;
@synthesize button4 = _button4;
@synthesize button5 = _button5;
@synthesize button6 = _button6;
@synthesize button7 = _button7;
@synthesize button8 = _button8;

@synthesize buttons = _buttons;

+ (AnswerButtons *)answerButtons {
    static AnswerButtons *singleton;
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        singleton = [[AnswerButtons alloc] init];
    });
    return singleton;
}

- (void)buttonsDidLoad {
    _buttons = [[NSArray alloc] initWithObjects:_button1, _button2, _button3, _button4, _button5, _button6, _button7, _button8, nil];
}

@end

Обратите внимание, что мы создаем синглтон в методе класса при первом запросе синглтона.Не делайте этого в application:didFinishLaunchingWithOptions:.

Далее, давайте подключим кнопки в наконечнике:

  1. Откройте наконечник для класса p3VC.(Вам следует подумать об изменении этого имени, чтобы оно начиналось с заглавной буквы и произносилось ViewController или просто Controller.)
  2. Перетащите «Внешний объект» из библиотеки объектов в перо.
  3. В инспекторе идентичности установите для пользовательского класса внешнего объекта значение AnswerButtons.
  4. . В инспекторе атрибутов установите для идентификатора внешнего объекта значение answerButtons.
  5. .Кнопки «Ответ» являются объектами для каждой из восьми кнопок, соединяющих кнопку с соответствующей розеткой.

Наконец, нам необходимо предоставить синглтон AnswerButtons загрузчику пера, когда мы загружаем его.Отредактируйте p3VC.m и присвойте ему метод loadView:

p3VC.m

- (void)loadView {
    NSDictionary *externals = [NSDictionary dictionaryWithObject:[AnswerButtons answerButtons]
        forKey:@"answerButtons"];
    NSDictionary *nibOptions = [NSDictionary dictionaryWithObject:externals
        forKey:UINibExternalObjects];
    [self.nibBundle loadNibNamed:self.nibName owner:self options:nibOptions];
    [[AnswerButtons answerButtons] buttonsDidLoad];
}

При таком подходе вы также можете создавать IBAction методы в классе AnswerButtons ииспользуйте перо для подключения кнопок к этим действиям.

1 голос
/ 05 февраля 2012

Чтобы подключить кнопки к конструктору интерфейсов, вам нужно поместить «IBOutlet» перед UIButton в каждом из ваших объявлений переменных.

IBOutlet UIButton * Ans1;

Затем в конструкторе интерфейсов вы можете щелкнуть правой кнопкой мыши и перетащить из контроллера вида на кнопку и выбрать правую кнопку. Затем, если вы хотите, чтобы каждая кнопка выполняла метод, вы должны объявить метод IBAction в вашем .h файле:

-(IBAction)doButtonStuff:(id)sender;

Затем, чтобы подключить действие к каждой кнопке в построителе интерфейса, перейдите к построителю интерфейса, щелкните правой кнопкой мыши и перетащите от кнопки, чтобы просмотреть контроллер и выберите метод, с которым вы хотите связать его. Обычно использовать конструктор интерфейса быстро и легко, но если вы хотите сделать что-то дополнительное за кулисами, вы можете использовать опубликованный код. Кроме того, просто примечание: чтобы использовать меньше кода при настройке кнопок, вы можете сделать для каждого цикла.

for (UIButton * button in ansButs) {
    self.button = [[UIButton alloc] init];
    [button setTitle:@"" forState:UIControlStateNormal];
}

Это намного меньше кода !!! Вам нужно объявить массив перед этим кодом и включить в него все кнопки.

1 голос
/ 05 февраля 2012

Поскольку UIButton наследуется от UIControl, вы можете использовать метод:

[yourButton1 addTarget:yourObject action:@selector(yourMethod) forControlEvents:UIControlEventTouchUpInside];

Зацепите это в цикле, где кнопки создаются, и вы готовы идти. Если вы добавляете кнопки из конструктора интерфейсов, вам нужно подключить IBOutlet для каждого. Пример: по вашему мнению контроллер init:

 self.Ans1 = [[UIButton alloc] init];
 [Ans1 setTitle:@"" forState:UIControlStateNormal];
//set the action
    [Ans1 addTarget:self action:@selector(yourMethod) forControlEvents:UIControlEventTouchUpInside];

Другим способом было бы создать метод IBAction для каждой кнопки и привязать этот метод к методу в синглтоне, что, на мой взгляд, гораздо более понятно.

Пример: в вашем представлении контроллер:

-(IBAction) button1Press:(id)sender{

[yourSingleton button1Press];

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...