Objective-C自定义类操作和插座 [英] Objective-C Custom Class Actions and Outlets

查看:155
本文介绍了Objective-C自定义类操作和插座的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一个UIView的自定义子类如下:



我创建了一个.xib与UIView包含一个Picker对象和工具栏对象,钩





CustomPickerView.h

  #import< UIKit / UIKit .h> 

@interface CustomPickerView:UIView

@property(强,非原子)IBOutlet UIDatePicker * datePicker;
@property(strong,nonatomic)IBOutlet UIBarButtonItem * doneButton;

- (IBAction)buttonDonePush:(id)sender;

@end



CustomPickerView.m

  #importCustomPickerView.h

@implementation CustomPickerView

- (id)init
{
self = [[[NSBundle mainBundle] loadNibNamed:@CustomPickerViewowner:self options:nil] objectAtIndex:0];
return self;
}

- (void)buttonDonePush:(id)sender
{
[[NSNotificationCenter defaultCenter] postNotificationName:@CustomPickerViewDoneButtonPushobject:nil userInfo:[NSDictionary dictionaryWithObject:self.datePicker.date forKey:@date]];
}

@end

最后,在我的ViewController我在viewDidLoad方法中实例化对象。

   - (void)viewDidLoad 
{
[super viewDidLoad ];

self.customPickerView = [[CustomPickerView alloc] init];
self.customPickerView.datePicker.datePickerMode = UIDatePickerModeTime;

self.dateField.inputView = self.customPickerView;
}

当用户点击self.dateField时,CustomPickerView会很好地弹出



问题是当用户从我的CustomPickerView类中点击完成按钮时,buttonDonePush操作不会触发。

解决方案

这个答案可以被认为是我最近为iOSX提供的类似解决方案的iOS伴侣:



Interface-Builder:combine NSView-class with .xib



您的安排是:




  • Mainstoryboard.storyboard

  • MyViewController.h

  • MyViewController.m


  • CustomPickerView.xib


  • CustomPickerView.h

  • CustomPickerView.m



您想要使用customPickerView作为MyViewController.view的子视图,并希望能够从包含的上下文中访问它的控件。



在您的示例中,您将在代码中创建customPickerView,但另一个有用的方案是将它添加到Interface Builder中的故事板中。




  • p>为您的接口元素声明IBOutlet。你已经为你的datePicker和doneButton做了这个,但你还需要一个IBOutlet到一个UIView,这将是这些项目的包含视图。

      @property(强,非原子)IBOutlet UIView * 




在CustomViewPicker.xib




  • 在Identity Inspector中将文件的所有者类设置为CustomViewPicker。

  • 将xib中的顶级视图设置为

  • 从文件所有者连接您的IBOutlet:查看 datePicker doneButton 到其各自的IB对象

  • 将您的IBAction文件所有者: buttonDonePush doneButton IB对象



在CustomViewPicker.m中:

   - (id)initWithFrame:(CGRect)frame 
{
//在代码中初始化时调用
self = [super initWithFrame:frame];
if(self){
[self initialise];
}
return self;
}

- (void)awakeFromNib
{
//从IB /故事板加载时调用
[self initialise];
}

- (void)initialise
{
NSString * nibName = NSStringFromClass([self class]);
if([[NSBundle mainBundle] loadNibNamed:nibName
owner:self
options:nil]){
[self.view setFrame:[self bounds]];
[self addSubview:self.view];
}

}
- (void)buttonDonePush:(id)sender
{
//按钮动作
}

如果你想在代码中初始化(就像你所做的那样),你的MyViewController会包含这样: p>

   - (void)viewDidLoad 
{
[super viewDidLoad];
CGRect frame = CGRectMake(0,50,320,300);
self.customPickerView = [[CustomPickerView alloc] initWithFrame:frame];

self.customPickerView.datePicker.datePickerMode = UIDatePickerModeTime;
self.dateField.inputView = self.customPickerView;
}

[编辑 c $ c> [self.view addSubview:self.customPickerView]; ]



或者,您可以创建CustomPickerView - 直接在故事板。只需添加自定义视图到您的MyViewController的storyboard场景,并将其类更改为CustomPickerView。链接到 self.customPickerView IBOutlet。



在这种情况下 initWithFrame 不会被调用,但是当MyViewController加载它的CustomPickerView子视图时会调用 awakeFromNib 。您的MyViewController的 viewDidLoad 将如下所示:

   - (void) viewDidLoad 
{
[super viewDidLoad];
self.customPickerView.datePicker.datePickerMode = UIDatePickerModeTime;
self.dateField.inputView = self.customPickerView;
}

如果你想从customPickerView获取你的按钮push动作,你可能考虑使用委托,这可能比你使用NSNotification更自给自足(但是这个问题超出你的原始问题)。


I am attempting to create a custom subclass of a UIView as follows:

I created a .xib with a UIView that contains a Picker object and Toolbar object, hooked up the Outlets and actions.

CustomPickerView.h

#import <UIKit/UIKit.h>

@interface CustomPickerView : UIView

@property (strong, nonatomic) IBOutlet UIDatePicker* datePicker;
@property (strong, nonatomic) IBOutlet UIBarButtonItem* doneButton;

-(IBAction) buttonDonePush:(id)sender;

@end

CustomPickerView.m

#import "CustomPickerView.h"

@implementation CustomPickerView

-(id) init
{
    self=[[[NSBundle mainBundle] loadNibNamed:@"CustomPickerView" owner:self options:nil] objectAtIndex:0];
    return self;
}

-(void) buttonDonePush:(id)sender
{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"CustomPickerViewDoneButtonPush" object:nil userInfo:[NSDictionary dictionaryWithObject:self.datePicker.date forKey:@"date"]];
}

@end

And finally, in my ViewController I instantiate the object in the viewDidLoad method.

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.customPickerView=[[CustomPickerView alloc] init];
    self.customPickerView.datePicker.datePickerMode=UIDatePickerModeTime;

    self.dateField.inputView=self.customPickerView;
}

When the user taps on the self.dateField, my CustomPickerView pops up nicely in place of the standard keyboard.

The problem is when the user taps the Done button from my CustomPickerView class, the buttonDonePush action does not fire.

解决方案

This answer can be considered as the iOS companion to a similar solution I offered recently for iOSX:

Interface-Builder: "combine" NSView-class with .xib

Your arrangement is thus:

  • Mainstoryboard.storyboard
  • MyViewController.h
  • MyViewController.m

  • CustomPickerView.xib

  • CustomPickerView.h
  • CustomPickerView.m

You want to use your customPickerView as a subview of MyViewController.view and want to be able to access it's control widgets from the containing context.

In your example you are creating the customPickerView in code, but another useful scenario is to add it to the storyboard in Interface Builder. This solution will work for both scenarios.

In CustomViewPicker.h

  • declare IBOutlets for your interface elements. You have already done this for your datePicker and doneButton, but you also need an IBOutlet to a UIView which will be the containing view for these items.

    @property (strong, nonatomic) IBOutlet UIView* view;
    

In CustomViewPicker.xib

  • Set the file's owner class to CustomViewPicker in the Identity Inspector.
  • Set the top-level view in the xib to the defaul UIView class (NOT CustomViewPicker).
  • Connect your IBOutlets from the file's owner: view, datePicker, doneButton to their respective IB objects
  • Connect your IBAction from the file's owner: buttonDonePush to the doneButton IB object

In CustomViewPicker.m:

- (id)initWithFrame:(CGRect)frame
{
    //called when initialising in code
    self = [super initWithFrame:frame];
    if (self) {
        [self initialise];
    }
    return self;
}

  - (void)awakeFromNib
  {
      //called when loading from IB/Storyboard
      [self initialise];
  }

- (void) initialise
{
    NSString* nibName = NSStringFromClass([self class]);
    if ([[NSBundle mainBundle] loadNibNamed:nibName
                                      owner:self
                                    options:nil]) {
        [self.view setFrame:[self bounds]];
        [self addSubview:self.view];
    }

}
-(void) buttonDonePush:(id)sender
{
   //button push actions
}

If you want to initialise in code (as you have done), your MyViewController would contain something like this:

- (void)viewDidLoad
{
    [super viewDidLoad];
    CGRect frame = CGRectMake(0, 50, 320, 300);
    self.customPickerView=[[CustomPickerView alloc] initWithFrame:frame];

    self.customPickerView.datePicker.datePickerMode=UIDatePickerModeTime;
    self.dateField.inputView=self.customPickerView;
}

[edit removed this redundant line: [self.view addSubview:self.customPickerView];]

Alternatively you can create your CustomPickerView - and set it's frame - directly in the storyboard. Just add a custom view to your MyViewController's storyboard scene, and change it's class to CustomPickerView. Link it to your self.customPickerView IBOutlet.

In this case initWithFrame does not get called, but awakeFromNib is invoked when MyViewController loads it's CustomPickerView subview. Your MyViewController's viewDidLoad would then look like this:

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.customPickerView.datePicker.datePickerMode=UIDatePickerModeTime;
    self.dateField.inputView=self.customPickerView;
}

If you want to get your button push action out of the customPickerView, you might consider using a delegate, which could be more self-contained than your use of NSNotification (but that issue reaches beyond your original question).

这篇关于Objective-C自定义类操作和插座的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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