6

UILabel を使用して、ユーザーが UIDatePicker で日付を選択できるようにします。

これを行うために、inputView および inputAccessoryView プロパティを上書きして書き込み可能にする UILabel サブクラスを作成しました。-(BOOL) canBecomeFirstResponder メソッドと -(BOOL) isUserInteractionEnabled メソッドも実装し、両方で YES を返します。次に、UIDatePIcker のインスタンスを inputView プロパティに割り当てました。

この時点で、ラベルをタップすると UIDatePicker が表示されるはずですが、何も起こりません。

何か助けはありますか?

これはコードです:

YPInteractiveUILabel.h

@interface YPInteractiveUILabel : UILabel
    @property (readwrite) UIView *inputView;
    @property (readwrite) UIView *inputAccessoryView;

- (BOOL) canBecomeFirstResponder;
- (BOOL) isUserInteractionEnabled;
@end


YPInteractiveUILabel.h

#import "YPInteractiveUILabel.h"

@implementation YPInteractiveUILabel

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];

    if (self)
    {
        UIDatePicker *datePicker = [[UIDatePicker alloc] init];
        [self  setInputView:datePicker];
    }

    return self;
}

- (BOOL)isUserInteractionEnabled
{
    return YES;
}

- (BOOL)canBecomeFirstResponder
{
    return YES;
}

@end
4

7 に答える 7

10

UILabel + UIDatePicker -- Done ボタンを備えた Swift バージョン。

import UIKit

class DatePickerLabel: UILabel {

    private let _inputView: UIView? = {
        let picker = UIDatePicker()
        return picker
    }()

    private let _inputAccessoryToolbar: UIToolbar = {
        let toolBar = UIToolbar()
        toolBar.barStyle = UIBarStyle.Default
        toolBar.translucent = true

        toolBar.sizeToFit()

        return toolBar
    }()

    override var inputView: UIView? {
        return _inputView
    }

    override var inputAccessoryView: UIView? {
        return _inputAccessoryToolbar
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Plain, target: self, action: #selector(doneClick))
        let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)

        _inputAccessoryToolbar.setItems([ spaceButton, doneButton], animated: false)

        let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(launchPicker))
        self.addGestureRecognizer(tapRecognizer)
    }

    override func canBecomeFirstResponder() -> Bool {
        return true
    }

    @objc private func launchPicker() {
        becomeFirstResponder()
    }

    @objc private func doneClick() {
        resignFirstResponder()
    }

}
于 2016-08-06T11:18:35.983 に答える
5

Apple のドキュメントで説明されているように、inputView getter メソッドを ovveride することができます:

- (UIView *)inputView {
    return myInputView;
}
- (BOOL)canBecomeFirstResponder {
    return YES;
}

次に、becomeFirstResponder を呼び出すジェスチャーまたはボタンを追加します。

- (void)showInputView:(id)sender {
     [self becomeFirstResponder];
}
于 2015-04-29T09:28:26.600 に答える
4

このようなものはどうですか。ラベルをサブクラス化するのではなく、ラベルにジェスチャ認識エンジンを追加し、タップ認識エンジンのハンドラーでピッカーを表示します。ピッカーのアクション メソッドで、ラベルを入力してピッカーを閉じます。この例は機能しますが、見栄えを良くするためにアニメーションを追加したい場合があります。

- (void)viewDidLoad {
    [super viewDidLoad];
    self.label.userInteractionEnabled = YES;
    UITapGestureRecognizer *tapper = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(launchPicker:)];
    [self.label addGestureRecognizer:tapper];
}

-(void)launchPicker:(UITapGestureRecognizer *) tapper {
    UIDatePicker *picker = [[UIDatePicker alloc] initWithFrame:CGRectMake(5, 150, 300, 200)];
    [picker addTarget:self action:@selector(updateLabel:) forControlEvents:UIControlEventValueChanged];
    [self.view addSubview:picker];
}

-(IBAction)updateLabel:(UIDatePicker *)sender {
    self.label.text = [NSString stringWithFormat:@"%@",sender.date ];
    [sender removeFromSuperview];
}
于 2012-10-12T00:07:58.553 に答える
3

提案 (特に NeverBe からのコメントと rdelmar によって提案された回答) のおかげで、コードに問題が見つかりました。簡単に言うと、入力ラベルを表示するには、ユーザーがラベルをタップしたときに becomeFirstResponder メソッドを呼び出す必要があります。

修正された UILabel サブクラスの実装に従います (ヘッダー ファイルは同じままです)。

@implementation YPInteractiveUILabel

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];

    if (self)
    {
        UIDatePicker *datePicker = [[UIDatePicker alloc] init];
        [self  setInputView:datePicker];

        UITapGestureRecognizer *tapper = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(launchPicker:)];
        [self addGestureRecognizer:tapper];

    }

    return self;
}

- (BOOL)isUserInteractionEnabled
{
    return YES;
}

- (BOOL)canBecomeFirstResponder
{
    return YES;
}

-(void)launchPicker:(UITapGestureRecognizer *) tapper
{
    [self becomeFirstResponder];
}


@end
于 2012-10-12T14:12:23.920 に答える
0

これは古い質問であることは知っていますが、これはまだ誰かにとって役立つかもしれません。

これを解決する別の方法があります-ジェスチャ認識機能で物事を複雑にする必要はありません...

GTPDateLabel.h

@interface GTPDateLabel : UILabel

@property (readonly, retain) UIView *inputView;

@end

GTPDateLabel.m

#import "GTPDateLabel.h"

@implementation GTPDateLabel

@synthesize inputView = _inputView;

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];

    if (self)
    {
        self.userInteractionEnabled = YES;
    }

    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];

    if (self)
    {
        self.userInteractionEnabled = YES;
    }

    return self;
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesEnded:touches withEvent:event];

    [self becomeFirstResponder];
}

- (BOOL)canBecomeFirstResponder
{
    return YES;
}

-(UIView *)inputView
{
    if (!_inputView)
    {
        UIDatePicker *datePicker = [[UIDatePicker alloc] init];

        _inputView = datePicker;
    }

    return _inputView;
}

@end

delegateまた、カスタムの場合は andUIPickerも設定する必要があることに注意してくださいdataSource...

于 2014-04-25T16:04:58.290 に答える