[英]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类
因此,您的安排是:
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相比,委托可以更加独立(但此问题超出了您的原始问题)。
编辑:
上面的答案指出了这一点,但是在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.