2

次のように UIView のカスタム サブクラスを作成しようとしています。

Picker オブジェクトと Toolbar オブジェクトを含む UIView を使用して .xib を作成し、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 アクションが起動しないことです。

4

2 に答える 2

2

この回答は、私が最近 iOSX 向けに提供した同様のソリューションの iOS コンパニオンと見なすことができます。

Interface-Builder: NSView クラスと .xib を「組み合わせる」

したがって、あなたの取り決めは次のとおりです。

  • 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ではありません) に設定します。
  • ファイルの所有者から IBOutlets を接続します: viewdatePickerdoneButtonそれぞれの IB オブジェクトに
  • ファイルの所有者からの IBAction を IB オブジェクトに接続しbuttonDonePushますdoneButton

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れませんが、awakeFromNibMyViewController が CustomPickerView サブビューをロードするときに呼び出されます。MyViewController は次のviewDidLoadようになります。

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

ボタンのプッシュ アクションを customPickerView から取り出したい場合は、NSNotification を使用するよりも自己完結型のデリゲートを使用することを検討してください (ただし、その問題は元の質問を超えています)。

于 2013-08-29T23:21:42.480 に答える