繁体   English   中英

Objective-C自定义类动作和输出

[英]Objective-C Custom Class Actions and Outlets

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

我使用UIView创建了一个.xib,其中包含一个Picker对象和Toolbar对象,并连接Outlets和操作。

在此处输入图片说明

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

最后,在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:与.xib结合使用NSView类

因此,您的安排是:

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

  • CustomPickerView.xib

  • CustomPickerView.h
  • CustomPickerView.m

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

在您的示例中,您正在代码中创建customPickerView,但另一个有用的方案是将其添加到Interface Builder中的情节提要中。 该解决方案适用于两种情况。

在CustomViewPicker.h中

  • 为您的接口元素声明IBOutlets。 您已经为datePicker和doneButton完成了此操作,但是还需要将UIView的IBOutlet用作这些项目的包含视图。

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

在CustomViewPicker.xib中

  • 在Identity Inspector中将文件的所有者类设置为CustomViewPicker。
  • 将xib中的顶级视图设置为默认的UIView类( 不是 CustomViewPicker)。
  • 将您的IBOutlet从文件的所有者: viewdatePickerdoneButton到它们各自的IB对象
  • 将IBAction从文件所有者连接: buttonDonePushdoneButton IB对象

在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
}

如果要初始化代码(如已完成),则MyViewController将包含以下内容:

- (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;
}

[ 编辑删除了这条多余的线: [self.view addSubview:self.customPickerView]; ]

或者,您可以直接在情节提要中创建CustomPickerView并设置其框架。 只需将自定义视图添加到MyViewController的故事板场景中,然后将其类更改为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中获取按钮按下操作,则可以考虑使用委托,与使用NSNotification相比,委托可以更加独立(但此问题超出了您的原始问题)。

编辑:

上面的答案指出了这一点,但是在init方法中,您设置了self,但是这在对self进行初始化之前就发生了。 如果可以在创建此特定视图的位置显示代码,则将大有帮助。 这是我的建议。

在控制此自定义视图部署的类中:

//to invoke your view
CustomPickerView *myView;
NSArray *xibContents = [[NSBundle mainBundle]loadNibNamed:@"CustomPickerView" owner:nil options:nil];
for (id xibObject in xibContents) {
    if ([xibObject isKindOfClass:[CustomPickerView class]]) {
        myView = (CustomPickerView *)xibObject;
        break;
    }
}
//now *myView is instantiated as your custom picker view
//do what you want here, add to subview, set frame, etc

在CustomPickerView.m文件中,删除init方法。

上一个答案:

您正在此实现中使用NSNotificationCenter。 当用户触摸完成按钮时,将发布NSNotification 您必须明确地“选择加入”和“收听”这些通知。 您可以通过在通知中心注册来实现。

在viewDidLoad中:

 [[NSNotificationCenter defaultCenter] addObserver:self
    selector:@selector(receivedNotification:) 
    name:@"CustomPickerViewDoneButtonPush"
    object:nil];

然后,您需要实现在此指定的选择器:

-(void)receivedNotification:(NSNotification *)note {
    NSDictionary *obj = [note object];
    NSLog(@"%@",obj);
    //dismiss the date picker here...
    //etc...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM