首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何使用单例连接一组按钮?

如何使用单例连接一组按钮?
EN

Stack Overflow用户
提问于 2012-02-05 10:25:11
回答 3查看 771关注 0票数 1

我的appDelegate,在方法didFinishLaunchingWithOptions中,我加载我的视图控制器,然后创建一个单例:

代码语言:javascript
代码运行次数:0
运行
复制
UIViewController *MainWinVC = [[p3VC alloc] init];
[[self window] setRootViewController:MainWinVC];
ansButSingleton *ansButs = [[ansButSingleton alloc] init]; 

ansButSingleton.h看起来像这样:

代码语言:javascript
代码运行次数:0
运行
复制
#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像这样:

代码语言:javascript
代码运行次数:0
运行
复制
#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。需要专家指导!谢谢。

编辑...和Rob一起工作来实现他的想法。我的viewLoad方法是从你的方法中复制和粘贴的,但也许其中有我需要更改的地方?

代码语言:javascript
代码运行次数:0
运行
复制
#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];
 }
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-02-05 13:34:56

有许多方法可以做到这一点。我会通过将单例的连接连接到笔尖来实现的。下面是如何实现的。

首先,让我们修复单例类以匹配iOS编程约定,并提供对连接nib中的按钮连接的支持:

AnswerButtons.h

代码语言:javascript
代码运行次数:0
运行
复制
#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

代码语言:javascript
代码运行次数:0
运行
复制
#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类的半边。(您应该考虑将此名称更改为以大写字母开头,拼写为Controller.)
  2. Drag,或者仅将一个“外部对象”从对象库拼写到笔尖中。在身份检查器中,将外部对象的自定义类设置为AnswerButtons.
  3. In

Attributes

  1. ,将其外部对象标识符从应答按钮对象设置为answerButtons.
  2. Control-drag,将按钮连接到相应的插座。

最后,我们需要在加载nib时向nib加载器提供AnswerButtons单例。编辑p3VC.m并为其提供loadView方法:

p3VC.m

代码语言:javascript
代码运行次数:0
运行
复制
- (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];
}

使用这种方法,您还可以在AnswerButtons类中创建IBAction方法,并使用nib将按钮连接到这些操作。

票数 1
EN

Stack Overflow用户

发布于 2012-02-05 10:29:48

由于UIButton继承自UIControl,因此您可以使用以下方法:

代码语言:javascript
代码运行次数:0
运行
复制
[yourButton1 addTarget:yourObject action:@selector(yourMethod) forControlEvents:UIControlEventTouchUpInside];

把它挂在创建按钮的循环中,你就可以开始工作了。如果要从界面构建器添加按钮,则需要为每个按钮挂接一个IBOutlet。示例:在视图控制器init

代码语言:javascript
代码运行次数:0
运行
复制
 self.Ans1 = [[UIButton alloc] init];
 [Ans1 setTitle:@"" forState:UIControlStateNormal];
//set the action
    [Ans1 addTarget:self action:@selector(yourMethod) forControlEvents:UIControlEventTouchUpInside];

另一种方法是为每个按钮创建IBAction方法,并将该方法挂接到单例中的方法,在我看来这要清楚得多。

示例:在视图控制器中:

代码语言:javascript
代码运行次数:0
运行
复制
-(IBAction) button1Press:(id)sender{

[yourSingleton button1Press];

}
票数 1
EN

Stack Overflow用户

发布于 2012-02-05 13:37:20

要将按钮连接到接口构建器,您必须在每个变量声明中的UIButton之前放置"IBOutlet“。

代码语言:javascript
代码运行次数:0
运行
复制
IBOutlet UIButton * Ans1;

然后在界面构建器中,您可以右键单击并从视图控制器拖动到按钮上,然后选择右按钮。然后,如果您想让每个按钮执行一个方法,则应该在.h文件中声明一个IBAction方法:

代码语言:javascript
代码运行次数:0
运行
复制
-(IBAction)doButtonStuff:(id)sender;

然后,要将动作与界面构建器中的每个按钮挂钩,请转到界面构建器,右键单击并从按钮拖动到视图控制器,然后选择要将其关联到的方法。通常使用界面构建器是快速和简单的,但如果你想做一些额外的幕后工作,你可以使用whitelion发布的代码。另外,顺便说一句,为了在设置按钮时使用更少的代码,您可以执行for each循环。

代码语言:javascript
代码运行次数:0
运行
复制
for (UIButton * button in ansButs) {
    self.button = [[UIButton alloc] init];
    [button setTitle:@"" forState:UIControlStateNormal];
}

这是一个很少的代码!您必须在此代码之前声明数组,并包含其中的所有按钮。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9146412

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档