我正在尝试创建 UIView 的自定义子类,如下所示:
我创建了一个带有 UIView 的 .xib,其中包含 Picker 对象和 Toolbar 对象,并连接了 Outlet 和操作。
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
自定义PickerView.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: "combine" NSView-class with .xib
你的安排是这样的:
- 主 Storyboard. Storyboard
- MyViewController.h
MyViewController.m
CustomPickerView.xib
- CustomPickerView.h
- CustomPickerView.m
您希望将 customPickerView 用作 MyViewController.view 的 subview ,并希望能够从包含的上下文访问它的控制小部件。
在您的示例中,您正在代码中创建 customPickerView,但另一个有用的场景是将其添加到 Interface Builder 中的 Storyboard 中。该解决方案适用于这两种情况。
在 CustomViewPicker.h 中
为您的界面元素声明 IBOutlet。您已经为 datePicker 和 didButton 完成了此操作,但您还需要一个到 UIView 的 IBOutlet,它将成为这些项目的包含 View 。
@property (strong, nonatomic) IBOutlet UIView* view;
在 CustomViewPicker.xib 中
- 在身份检查器中将文件的所有者类设置为 CustomViewPicker。
- 将 xib 中的顶级 View 设置为默认 UIView 类(不 CustomViewPicker)。
- 将文件所有者的 IBOutlet:
view
、datePicker
、doneButton
连接到各自的 IB 对象 - 将文件所有者的 IBAction:
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];
]
或者,您可以直接在 Storyboard中创建 CustomPickerView - 并设置它的框架。只需将自定义 View 添加到 MyViewController 的 Storyboard场景,并将其类更改为 CustomPickerView。将其链接到您的 self.customPickerView
IBOutlet。
在这种情况下,initWithFrame
不会被调用,但当 MyViewController 加载其 CustomPickerView subview 时,会调用 awakeFromNib
。您的 MyViewController 的 viewDidLoad
将如下所示:
- (void)viewDidLoad
{
[super viewDidLoad];
self.customPickerView.datePicker.datePickerMode=UIDatePickerModeTime;
self.dateField.inputView=self.customPickerView;
}
如果您想从 customPickerView 中获取按钮推送操作,您可以考虑使用委托(delegate),它可能比使用 NSNotification 更加独立(但该问题超出了您最初的问题)。
关于ios - Objective-C 自定义类操作和导出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18520695/