【问题标题】:XCode: Displaying a UIDatePicker when user clicks on UITextboxXCode:当用户单击 UITextbox 时显示 UIDatePicker
【发布时间】:2012-02-16 22:47:56
【问题描述】:

我已经彻底研究了这个话题,发现有人在许多网站上发布了完全相同的问题,包括 stackoverflow 中的右 here

我已经尝试了所有建议,但无法让 UIDatePicker 实际显示。我采取什么方法似乎并不重要。我尝试使用继承模型,在该模型中我继承了 UITextBox 控件并覆盖它的默认方法以显示 UIDatePicker,然后我确保在 StoryBoard 中我将 UITextView 控件的类设置为该自定义类。我尝试以编程方式生成 UIDatePicker 并尝试将其拖到 StoryBoard 中的视图上。当我尝试编程方法时,什么都没有显示,当我尝试将它拖到 StoryBoard 上时,它总是显示。当我将它的属性设置为“隐藏”时,它会隐藏,但即使我尝试将代码添加到应该取消隐藏它的 textboxDidBeginEditing 方法,我也无法显示它。 我确保将 UITextView 的 inputView 属性设置为等于我的 UIDatePicker 控件。

没有任何效果!我不明白为什么 Apple 不只是将 UIDatePicker 设为 UITextView 控件的 Attributes Inspector 下拉列表中的默认选项之一。那会让这一切变得容易得多。

以下是我的实现类文件中的一些代码。

#import "AddTasksViewController.h"

@implementation AddTasksViewController

@synthesize dueDate;
@synthesize description;
@synthesize shortTitle;
@synthesize datePicker;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
        self.dueDate.inputView = datePicker;

    }
    return self;
}

- (IBAction)dueDateDidBeginEditing:(UITextView *)textField 
{  
    [textField resignFirstResponder];
    [datePicker setFrame:CGRectMake(0,200,320,120)];
    [datePicker addTarget:self action:@selector(done) forControlEvents:UIControlEventValueChanged];
    [self.view addSubview:datePicker];
}

这是我的头文件的样子...

#import <UIKit/UIKit.h>

@interface AddTasksViewController : UIViewController

@property (nonatomic, copy) IBOutlet UITextView      *dueDate;
@property (nonatomic, copy) IBOutlet UITextView      *description;
@property (nonatomic, copy) IBOutlet UITextView      *shortTitle;
@property (nonatomic, retain) IBOutlet UIDatePicker    *datePicker;

- (IBAction)doneEditing:(id)sender;
- (IBAction)dateChanged:(id)sender;
- (IBAction)dueDateDidBeginEditing:(UITextView *)textField;

@end

正如我已经提到的,我采用的另一种方法(即子类化 UITextView)也不起作用。我复制了here 提供的代码,与显示的完全相同。然后,我将名为“DateField”的自定义类添加到我的项目(头文件和实现文件)中,然后在我的 AddTaskViewController.h 和 AddTaskViewController.m 文件中将 DueDate 的 UITextBox 声明替换为 DateField,并确保 StoryBoard 引用通过在 Identity Inspector 中为控件的类选择 DateField 来更新。

无论我做什么,我都无法在单击 UITextView 时显示 UIDatePicker。当我设置断点时,它确实命中了dueDateDidBeginEditing 方法,所以我知道某些东西正在被触发。问题是我不明白为什么 UIDatePicker 没有显示 subView。

任何帮助都将不胜感激,因为这个看似简单的任务似乎比它应该花费的时间要长得多。在 Java 和 C# 中,我可以闭上眼睛、双手绑在背后做这类事情,但对于 Objective-C,一切都变得不必要地复杂。语法真的让我很生气。

这么多方括号!!!啊啊啊!!!

【问题讨论】:

  • ..你知道数据源和委托吗??
  • 您无法在-initWithNibName:bundle: 中配置您的视图,因为此时您的网点为零。试试-viewDidLoad

标签: iphone ios xcode uitextview uidatepicker


【解决方案1】:

在 .h 文件中添加 UITextField 的委托,以便在触摸时调用此函数。然后使用文本字段的标记值来确定选择该字段时要执行的操作。

-(BOOL) textFieldShouldBeginEditing:(UITextField *) textField 
{
    activeTextField = textField;

    if (textField.tag == 1) 
    {
        self.datePicker.datePickerMode = UIDatePickerModeDate;
        self.isDatePicker = TRUE;
        self.tempTextField = textField;
        [self showPicker];
        return NO;
    }
    else if (textField.tag == 2) 
    {
        self.datePicker.datePickerMode = UIDatePickerModeTime;
        self.isDatePicker = TRUE;
        self.tempTextField = textField;
        [self showPicker];

        return NO;
    }
    else if (textField.tag == 3)
    {
        self.isDatePicker = FALSE;
        self.tempTextField = textField;
        [self showPicker];
        return NO;
    }
    else
    {
        self.tempTextField = textField;
        return YES;
    }
}

【讨论】:

    【解决方案2】:

    显示inputViewinputViewUIDatePicker 与显示键盘相比相对困难,但与您遇到的麻烦相比相对容易。

    我在您的代码中注意到的第一个问题是,对于 iOS/Mac 开发新手来说,这是一个非常常见的问题,即您正试图设置一个尚不存在的对象的属性。将“self.dueDate.inputView = datePicker;”放入您的initWithNibName:bundle: 将不起作用,因为视图尚未加载,而dueDate 是您视图的一部分。在 Objective-c 中,对象是用 alloc 和 init 实例化的。 Init 是对任何对象的第一个真正的方法调用。在你的视图控制器生命中的这一点上,视图还没有被创建。 self.dueDate.inputView = datePicker;所属的方法调用在viewDidLoad方法中。它在听起来像是被调用的时候被调用,并且您的 dueDate 属性将在此时正确加载。无需使用 UITextField 的自定义子类来为您的文本字段显示日期选择视图。这是自定义输入视图类的一个非常基本的示例:

    ExampleBasicDateInputView.h:

    #import <UIKit/UIKit.h>
    
    @interface ExampleBasicDateInputView : UIView
    @property (strong,nonatomic) UIDatePicker *datePicker;
    @end
    

    ExampleBasicDateInputView.m:

    #import "ExampleBasicDateInputView.h"
    
    @implementation ExampleBasicDateInputView{
        UITextField *_inputField; // ivar to store the textfield currently being edited
    }
    @synthesize datePicker = _datePicker;
    // TARGET METHODS
    -(void)pickerValueChanged:(UIDatePicker *)picker{
        _inputField.text = self.datePicker.date.description; // set text to date description
    }
    -(void)viewDoubleTapped:(UITapGestureRecognizer *)tapGR{
        [_inputField resignFirstResponder]; // upon double-tap dismiss picker
    }
    -(void)textFieldBeganEditing:(NSNotification *)note{
        _inputField = note.object; // set ivar to current first responder
    }
    -(void)textFieldEndedEditing:(NSNotification *)note{
        _inputField = nil; // the first responder ended editing CRITICAL:avoids retain cycle
    }
    // INITI METHODS
    -(void)initializationCodeMethod{
        _datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 0, 320, 0)];// All pickers have preset height
        self.bounds = _datePicker.frame; // Make our view same size as picker
        [self addSubview:_datePicker];
        [_datePicker addTarget:self action:@selector(pickerValueChanged:) forControlEvents:UIControlEventValueChanged]; // register to be notified when the value changes
            // As an example we'll use a tap gesture recognizer to dismiss on a double-tap
        UITapGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(viewDoubleTapped:)];
        tapGR.numberOfTapsRequired = 2; // Limit to double-taps
        [self addGestureRecognizer:tapGR];
        NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
        [center addObserver:self selector:@selector(textFieldBeganEditing:) name:UITextFieldTextDidBeginEditingNotification object:nil]; // Ask to be informed when any textfield begins editing
        [center addObserver:self selector:@selector(textFieldEndedEditing:) name:UITextFieldTextDidEndEditingNotification object:nil]; // Ask to be informed when any textfield ends editing
    }
    -(id)init{
        if ((self = [super init])){
            [self initializationCodeMethod];
        }
        return self;
    }
    -(id)initWithFrame:(CGRect)frame{
        if ((self = [super initWithFrame:frame])){
            [self initializationCodeMethod];
        }
        return self;
    }
    -(id)initWithCoder:(NSCoder *)aDecoder{
        if ((self = [super initWithCoder:aDecoder])){
            [self initializationCodeMethod];
        }
        return self;
    }
    -(void)dealloc{
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidBeginEditingNotification object:nil];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidEndEditingNotification object:nil];
    }
    @end
    

    然后在视图中确实加载了你会像这样使用这个类:

    ExampleBasicDateInputView *dateEntryView = [[ExampleBasicDateInputView alloc] init];
    self.dueDate.inputView = datePickerView;
    

    正如您在.h 文件中看到的,我们已将日期选择器实例公开为属性,以便您可以设置样式。诸如此类:

    dateEntryView.datePicker.datePickerMode = UIDatePickerModeDate;
    

    显然这是一个非常基本的例子,但我认为它展示了可以做什么。

    【讨论】:

      【解决方案3】:

      我在使用 Storyboard 时遇到了同样的问题。以下是我的解决方法:

      概述: 我在 viewDidLoad: 中分配并初始化我的 UIDatePicker 属性。然后我将我的文本字段的 inputView 属性设置为我的 datepicker 属性。

      这是我的代码: 在 TripViewController.h 中:

      @property (nonatomic,strong) IBOutlet UIDatePicker *datePicker;
      

      在 TripViewController.m 中:

      @synthesize datePicker;
      ...
      -(void)viewDidLoad {
      ...
      self.datePicker = [[UIDatePicker alloc]init];
      [self.datePicker addTarget:self action:@selector(dateChanged) forControlEvents:UIControlEventValueChanged];
      self.dateField.inputView = self.datePicker;
      }
      

      然后我实现我的方法 dateChanged 以便每当日期选择器轮停止移动时,我的文本字段就会更新。

      - (void)dateChanged
      {
      NSDate *date = self.datePicker.date;
      NSDateFormatter *dateFormat = [[NSDateFormatter alloc]init];
      [dateFormat setDateStyle:NSDateFormatterMediumStyle];
      self.dateField.text = [dateFormat stringFromDate:date];
      }
      

      【讨论】:

      • 是的,但问题是现在日期选择器显示并且无法隐藏它。
      • @JohnMerlino 尝试将此作为指南 [stackoverflow.com/questions/1262574/… 仅将 UIPickerView 更改为 UIDatePicker
      【解决方案4】:

      这很容易。在viewDidLoad.m中的.h中定义委托TextField(UITextFieldDelegate)

      myTextField.setDelegate = self;
      

      在同一个 viewDidLoad 中,将 datePicker 关联到 myTextField。

      myTextField.inputView = myDatePicker;
      

      你也可以做动漫,但这是最简单的方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-24
        相关资源
        最近更新 更多