6

我会使用 UILabel 来允许用户使用 UIDatePicker 选择日期。

为此,我创建了一个 UILabel 子类,覆盖了 inputView 和 inputAccessoryView 属性,使它们可写;我还实现了 -(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 -- 带有完成按钮的 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

您可以只覆盖 inputView getter 方法,如Apple 文档中所述:

- (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 回答
2

这是@dmitriy-kirakosyan 更新到 Swift 5 的代码片段

class DatePickerLabel: UILabel {

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

    private let _inputAccessoryToolbar: UIToolbar = {
        let toolBar = UIToolbar()
        toolBar.barStyle = UIBarStyle.default
        toolBar.isTranslucent = 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: UIBarButtonItem.Style.plain, target: self, action: #selector(doneClick))
        let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action: nil)

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

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

    override var canBecomeFirstResponder: Bool {
        return true
    }

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

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

}
于 2019-09-03T13:57:48.323 回答
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

请注意,您还应该设置delegateand 在自定义的情况下UIPickerdataSource...

于 2014-04-25T16:04:58.290 回答
0

这是在 Swift 4UILabel中显示的PickerView

final class DatePickerLabel: UILabel {
  private let pickerView: UIPickerView
  private let toolbar: UIToolbar

  required init(pickerView: UIPickerView, toolbar: UIToolbar) {
    self.pickerView = pickerView
    self.toolbar = toolbar
    super.init(frame: .zero)

    let recogniser = UITapGestureRecognizer(target: self, action: #selector(tapped))
    addGestureRecognizer(recogniser)
  }

  required init?(coder aDecoder: NSCoder) {
    fatalError()
  }

  override var inputView: UIView? {
    return pickerView
  }

  override var inputAccessoryView: UIView? {
    return toolbar
  }

  override var canBecomeFirstResponder: Bool {
    return true
  }

  @objc private func tapped() {
    becomeFirstResponder()
  }
}
于 2018-05-31T08:08:37.820 回答