如何连接带有单例的按钮数组?
我的 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];
}
My appDelegate, in the method didFinishLaunchingWithOptions I load my view controller then create a singleton:
UIViewController *MainWinVC = [[p3VC alloc] init];
[[self window] setRootViewController:MainWinVC];
ansButSingleton *ansButs = [[ansButSingleton alloc] init];
ansButSingleton.h looks like this:
#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
and ansButSingleton.m like this:
#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
This builds and runs fine (it doesn't do much yet). The buttons are visible due to the successful loading of the nib. However, they are not active since I haven't connected them to the code (no IBActions).
Question: How do I connect buttons created this way to the buttons in the nib? If these were simple buttons (not an array of buttons) I would create a method and use IBAction as part of that method declaration. But this case seems a bit different. Or maybe not. If these were labels (which I also need to do later), my reading leads me to believe IBOutletCollection might work, but there is no IBActionCollection that I can see. Expert guidance needed! Thanks.
EDIT ... working with Rob to implement his ideas. My viewLoad method was copied and pasted from yours, but maybe there was something in it I needed to change?
#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];
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
有多种方法可以做到这一点。我会通过在笔尖上连接单例的连接来做到这一点。方法如下。
首先,让我们修复单例类以匹配 iOS 编程约定,并提供对笔尖中按钮连接的支持:
AnswerButtons.h
AnswerButtons.m
请注意,我们在类方法中创建单例第一次请求单例。不要在
application:didFinishLaunchingWithOptions:
中执行此操作。接下来,让我们连接笔尖中的按钮:
p3VC
类的笔尖。 (您应该考虑更改此名称以大写字母开头,并拼出ViewController
或只是Controller
。)AnswerButtons
。answerButtons
。最后,当我们加载笔尖时,我们需要向笔尖加载器提供
AnswerButtons
单例。编辑p3VC.m
并给它一个loadView
方法:p3VC.m
通过这种方法,您还可以在
中创建
类并使用笔尖将按钮连接到这些操作。IBAction
方法AnswerButtonsThere are a number of ways you could do this. I'd do it by hooking up the singleton's connections in the nib. Here's how.
First, let's fix up the singleton class to match iOS programming conventions and provide the support for wiring up the button connections in the nib:
AnswerButtons.h
AnswerButtons.m
Note that we create the singleton in the class method the first time the singleton is requested. Don't do it in
application:didFinishLaunchingWithOptions:
.Next, let's hook up the buttons in the nib:
p3VC
class. (You should consider changing this name to start with a capital letter and spell outViewController
or justController
.)AnswerButtons
.answerButtons
.Finally, we need to provide the
AnswerButtons
singleton to the nib loader when we load the nib. Editp3VC.m
and give it aloadView
method:p3VC.m
With this approach, you can also create
IBAction
methods in theAnswerButtons
class and use the nib to connect the buttons to those actions.由于
UIButton
继承自UIControl
,您可以使用以下方法:将其挂钩到创建按钮的循环中,然后就可以开始了。如果您要从界面生成器添加按钮,那么您需要为每个按钮挂钩一个
IBOutlet
。示例:在视图控制器init
中:另一种方法是为每个按钮创建
IBAction
方法,并将该方法挂接到单例中的方法,我认为这是更清楚了。示例:在您的视图控制器中:
Since
UIButton
inherits fromUIControl
you can use the method:Hook that in the loop where the buttons are created and you are good to go. If you are adding the buttons from interface builder then you need to hook an
IBOutlet
for each. Example: In your view controllerinit
:Another way would be to create the
IBAction
method for each button and hook that method to the method in the singleton, which in my opinion is much more clear.Example: in your view controller:
要将按钮连接到界面生成器,您必须在每个变量声明中的 UIButton 之前放置“IBOutlet”。
然后在界面生成器中,您可以右键单击并从视图控制器拖动到按钮上,然后选择右侧按钮。然后,如果您想让每个按钮执行一个方法,您应该在 .h 文件中声明一个 IBAction 方法:
然后,要将该行为连接到界面构建器中的每个按钮,请转到界面构建器,右键单击并从按钮拖动到查看控制器并选择您想要将其关联的方法。通常,使用界面生成器既快速又简单,但如果您想在幕后做一些额外的事情,您可以使用whitelion发布的代码。
另外,请注意,为了在设置按钮时使用更少的代码,您可以为每个循环执行一个。
这样代码就少了很多!!!您必须在此代码之前声明数组并在其中包含所有按钮。
To connect the buttons to interface builder, you'd have to place "IBOutlet" before the UIButton in each one of your variable declarations.
Then in interface builder, you can right click and drag from view controller onto the button and select the right button. Then if you wanted to have each button perform a method, you should declare an IBAction method in your .h file:
Then to hook up the act to each button in interface builder, go to interface builder and right click and drag from the button to view controller and select what method you want to associate it with. Typically using interface builder is quick and easy but if you want to do some extra behind the scenes stuff, you can use the code whitelion posted.
Also, just a side note, to use less code when setting up your buttons, you can do a for each loop.
This is a lot less code!!! You'd have to declare the array before this code and include all of the buttons in it.