我正在尝试创建UIView的自定义子类,如下所示:
我创建了一个带有UIView的.xib,其中包含Picker对象和Toolbar对象,连接了Outlets和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
最后,在我的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类中点击Done按钮时,buttonDonePush操作不会触发。
答案 0 :(得分:1)
这个答案可以被视为我最近为iOSX提供的类似解决方案的iOS伴侣:
Interface-Builder: "combine" NSView-class with .xib
您的安排是:
MyViewController.m
CustomPickerView.xib
您希望将customPickerView用作MyViewController.view的子视图,并希望能够从包含的上下文中访问它的控件小部件。
在您的示例中,您将在代码中创建customPickerView,但另一个有用的方案是将其添加到Interface Builder中的故事板。此解决方案适用于两种情况。
在CustomViewPicker.h中
为您的界面元素声明IBOutlets。您已经为datePicker和doneButton完成了此操作,但您还需要一个UIView的IBOutlet,它将是这些项的包含视图。
@property (strong, nonatomic) IBOutlet UIView* view;
在CustomViewPicker.xib
中view
,datePicker
,doneButton
连接到各自的IB对象buttonDonePush
连接到doneButton
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更自包含(但这个问题超出了原来的问题)。
答案 1 :(得分:0)
编辑:
上面的答案指出了这一点,但是在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...
}