xcode UILabel 不显示 inputView
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12849146/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
UILabel doesn't show inputView
提问by massyc
I would use a UILabel to allow users to select a date with UIDatePicker.
我会使用 UILabel 来允许用户使用 UIDatePicker 选择日期。
To do this, I created an UILabel subclass overwriting the inputView and the inputAccessoryView properties making them writable; I also implemented the -(BOOL) canBecomeFirstResponder and the -(BOOL) isUserInteractionEnabled methods returning YES for both. Then I assigned an instance of UIDatePIcker to the inputView property.
为此,我创建了一个 UILabel 子类,覆盖 inputView 和 inputAccessoryView 属性,使它们可写;我还实现了 -(BOOL) canBecomeFirstResponder 和 -(BOOL) isUserInteractionEnabled 方法,两者都返回 YES。然后我将 UIDatePIcker 的一个实例分配给 inputView 属性。
At this point my expectation is that when the label is tapped an UIDatePicker should appear, but nothing happens.
在这一点上,我的期望是当标签被点击时 UIDatePicker 应该出现,但没有任何反应。
Any help?
有什么帮助吗?
This is the code:
这是代码:
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
采纳答案by massyc
Thanks to the suggestions (especially the comment from NeverBe and the answer proposed by rdelmar) I found the problem in my code. In brief, in order to show the input label, a call to the becomeFirstResponder method when the user tap the label is needed.
感谢建议(尤其是来自 NeverBe 的评论和 rdelmar 提出的答案),我在我的代码中发现了问题。简而言之,为了显示输入标签,需要在用户点击标签时调用 becomeFirstResponder 方法。
Following the UILabel subclass implementation corrected (the header file remains the same):
在 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
回答by Dmitriy Kirakosyan
UILabel + UIDatePicker -- Swift version with Done button.
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()
}
}
回答by rdelmar
How about something like this. Rather than subclass the label, just add a gesture recognizer to it, and bring up the picker in the tap recognizer's handler. In the picker's action method, populate the label and dismiss the picker. This example works, but you'd probably want to add some animation to make it look better:
这样的事情怎么样。而不是将标签子类化,只需向其添加一个手势识别器,并在点击识别器的处理程序中调出选择器。在选择器的操作方法中,填充标签并关闭选择器。此示例有效,但您可能希望添加一些动画以使其看起来更好:
- (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];
}
回答by ims
You can just ovveride inputView getter method, like explained in Apple documentation:
您可以只覆盖 inputView getter 方法,如Apple 文档中所述:
- (UIView *)inputView {
return myInputView;
}
- (BOOL)canBecomeFirstResponder {
return YES;
}
Then add a gesture or a button to call becomeFirstResponder:
然后添加一个手势或按钮来调用 becomeFirstResponder:
- (void)showInputView:(id)sender {
[self becomeFirstResponder];
}
回答by Adobels
This is a code snipet of @dmitriy-kirakosyan updated to Swift 5
这是更新到 Swift 5 的 @dmitriy-kirakosyan 的代码片段
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()
}
}
回答by onmyway133
Here is the UILabel
that shows PickerView
, in Swift 4
这是在 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()
}
}
回答by Rok Jarc
I know this is an old question but this might still be useful to someone.
我知道这是一个老问题,但这可能对某人仍然有用。
There is another way to solve this - there is no need to complicate things with gesture recognizers...
还有另一种方法可以解决这个问题 - 无需使用手势识别器使事情复杂化......
GTPDateLabel.h
GTPDateLabel.h
@interface GTPDateLabel : UILabel
@property (readonly, retain) UIView *inputView;
@end
GTPDateLabel.m
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
Note that you should also set the delegate
and in case of custom UIPicker
also dataSource
...
请注意,您还应该设置delegate
和 在自定义的情况下UIPicker
也dataSource
...