如何创建自定义 iOS 视图类并实例化它的多个副本(在 IB 中)? [英] How do I create a custom iOS view class and instantiate multiple copies of it (in IB)?

查看:22
本文介绍了如何创建自定义 iOS 视图类并实例化它的多个副本(在 IB 中)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在制作一个具有多个计时器的应用程序,它们基本上都是一样的.

I am currently making an app that will have multiple timers, which are basically all the same.

我想创建一个自定义类,该类使用定时器的所有代码以及布局/动画,因此我可以拥有 5 个彼此独立运行的相同定时器.

I want to create a custom class that uses all of the code for the timers as well as the layout/animations, so I can have 5 identical timers that operate independently of each other.

我使用 IB (xcode 4.2) 创建了布局,定时器的所有代码目前都在 viewcontroller 类中.

I created the layout using IB (xcode 4.2) and all the code for the timers is currently just in the viewcontroller class.

我很难思考如何将所有内容封装到自定义类中,然后将其添加到视图控制器中,任何帮助将不胜感激.

I am having difficulty wrapping my brain around how to encapsulate everything into a custom class and then add it to the viewcontroller, any help would be much appreciated.

推荐答案

从概念上来说,你的计时器应该是 UIView 的子类,而不是 NSObject.

Well to answer conceptually, your timer should likely be a subclass of UIView instead of NSObject.

要在 IB 中实例化计时器的实例,只需将 UIView 拖放到视图控制器的视图上,并将其类设置为计时器的类名.

To instantiate an instance of your timer in IB simply drag out a UIView drop it on your view controller's view, and set it's class to your timer's class name.

记得在视图控制器中#import你的定时器类.

Remember to #import your timer class in your view controller.

用于 IB 设计(代码实例见修订历史)

我对情节提要不是很熟悉,但我知道您可以在 IB 中使用 .xib 文件构建您的界面,该文件与使用情节提要版本几乎相同;你甚至应该能够复制 &将现有界面中的视图作为一个整体粘贴到 .xib 文件中.

I'm not very familiar at all with storyboard, but I do know that you can construct your interface in IB using a .xib file which is nearly identical to using the storyboard version; You should even be able to copy & paste your views as a whole from your existing interface to the .xib file.

为了测试这一点,我创建了一个名为MyCustomTimerView.xib"的新的空 .xib.然后我添加了一个视图,并添加了一个标签和两个按钮.像这样:

To test this out I created a new empty .xib named "MyCustomTimerView.xib". Then I added a view, and to that added a label and two buttons. Like So:

我创建了一个名为MyCustomTimer"的新的objective-C类子类UIView.在我的 .xib 中,我将 File's Owner 类设置为 MyCustomTimer.现在我可以像任何其他视图/控制器一样自由地连接动作和出口.生成的 .h 文件如下所示:

I created a new objective-C class subclassing UIView named "MyCustomTimer". In my .xib I set my File's Owner class to be MyCustomTimer. Now I'm free to connect actions and outlets just like any other view/controller. The resulting .h file looks like this:

@interface MyCustomTimer : UIView
@property (strong, nonatomic) IBOutlet UILabel *displayLabel;
@property (strong, nonatomic) IBOutlet UIButton *startButton;
@property (strong, nonatomic) IBOutlet UIButton *stopButton;
- (IBAction)startButtonPush:(id)sender;
- (IBAction)stopButtonPush:(id)sender;
@end

剩下的唯一障碍是在我的 UIView 子类上获取这个 .xib.使用 .xib 可以大大减少所需的设置.由于您使用故事板加载计时器,我们知道 -(id)initWithCoder: 是唯一会被调用的初始化程序.所以这里是实现文件的样子:

The only hurdle left to jump is getting this .xib on my UIView subclass. Using a .xib dramatically cuts down the setup required. And since you're using storyboards to load the timers we know -(id)initWithCoder: is the only initializer that will be called. So here is what the implementation file looks like:

#import "MyCustomTimer.h"
@implementation MyCustomTimer
@synthesize displayLabel;
@synthesize startButton;
@synthesize stopButton;
-(id)initWithCoder:(NSCoder *)aDecoder{
    if ((self = [super initWithCoder:aDecoder])){
        [self addSubview:
         [[[NSBundle mainBundle] loadNibNamed:@"MyCustomTimerView" 
                                        owner:self 
                                      options:nil] objectAtIndex:0]];
    }
    return self;
}
- (IBAction)startButtonPush:(id)sender {
    self.displayLabel.backgroundColor = [UIColor greenColor];
}
- (IBAction)stopButtonPush:(id)sender {
    self.displayLabel.backgroundColor = [UIColor redColor];
}
@end

名为 loadNibNamed:owner:options: 的方法完全符合它的要求.它加载 Nib 并将文件的所有者"属性设置为 self.我们提取数组中的第一个对象,即 Nib 的根视图.我们将视图添加为子视图,瞧它在屏幕上.

The method named loadNibNamed:owner:options: does exactly what it sounds like it does. It loads the Nib and sets the "File's Owner" property to self. We extract the first object in the array and that is the root view of the Nib. We add the view as a subview and Voila it's on screen.

显然,这只是在按下按钮时更改标签的背景颜色,但是这个示例应该能让您顺利进行.

Obviously this just changes the label's background color when the buttons are pushed, but this example should get you well on your way.

基于评论的注释:

值得注意的是,如果您遇到无限递归问题,您可能错过了这个解决方案的微妙技巧.它没有做你认为它在做的事情.放置在故事板中的视图不会被看到,而是加载另一个视图作为子视图.它加载的视图是在笔尖中定义的视图.笔尖中的文件所有者"是那个看不见的视图.很酷的部分是这个看不见的视图仍然是一个 Objective-C 类,它可以用作它从笔尖引入的视图的各种视图控制器.例如,MyCustomTimer 类中的 IBAction 方法在视图控制器中比在视图中更多.

It is worth noting that if you are getting infinite recursion problems you probably missed the subtle trick of this solution. It's not doing what you think it's doing. The view that is put in the storyboard is not seen, but instead loads another view as a subview. That view it loads is the view which is defined in the nib. The "file's owner" in the nib is that unseen view. The cool part is that this unseen view is still an Objective-C class which may be used as a view controller of sorts for the view which it brings in from the nib. For example the IBAction methods in the MyCustomTimer class are something you would expect more in a view controller than in a view.

作为旁注,有些人可能会争辩说这破坏了 MVC,我有点同意.在我看来,它与自定义 UITableViewCell 更密切相关,它有时也必须是部分控制器.

As a side note, some may argue that this breaks MVC and I agree somewhat. From my point of view it's more closely related to a custom UITableViewCell, which also sometimes has to be part controller.

还值得注意的是,这个答案是为了提供一个非常具体的解决方案;创建一个可以在 相同视图 上多次实例化的笔尖,就像故事板上的布局一样.例如,您可以轻松想象一次在 iPad 屏幕上显示六个这样的计时器.如果您只需要为要在整个应用程序中多次使用的视图控制器指定一个视图,那么 jyavenard 对此提供的解决方案问题几乎肯定对您来说是一个更好的解决方案.

It is also worth noting that this answer was to provide a very specific solution; create one nib that can be instantiated multiple times on the same view as laid out on a storyboard. For example, you could easily imagine six of these timers all on an iPad screen at one time. If you only need to specify a view for a view controller that is to be used multiple times across your application then the solution provided by jyavenard to this question is almost certainly a better solution for you.

这篇关于如何创建自定义 iOS 视图类并实例化它的多个副本(在 IB 中)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆