【问题标题】:Crash on textfield become first responder with pickerview文本字段上的崩溃成为pickerview的第一响应者
【发布时间】:2025-11-30 00:40:01
【问题描述】:

所以我一直试图让这个pickerview 工作,但我就是无法让它工作。当我运行应用程序时,它在没有任何堆栈跟踪的情况下崩溃,并在 [textField becomeFirstResponder] 上显示线程 1:EXC_BAD_ACCESS。 pickerArray 是正确的,所以这不是问题。

#import "TestViewController.h"
#import "FindClasses.h"

@interface TestViewController ()
@property UIPickerView *picker;
@property NSArray *pickerArray;
@property (nonatomic, strong) FindClasses *finder;
@end

@implementation TestViewController

@synthesize finder = _finder;

- (FindClasses *)finder
{
    if (!_finder) _finder = [[FindClasses alloc] init];
    return _finder;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    self.pickerArray = [self.finder findClassesInTimetable];

    self.classField.delegate = self;
    self.picker = [[UIPickerView alloc] init];
    self.picker.delegate = self;
    self.picker.dataSource = self;
    self.classField.inputView = self.picker;
    // Do any additional setup after loading the view.
}

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField  {
    [textField becomeFirstResponder];
    return YES;
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    return YES;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - UIPickerView method implementation

-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
    return 1;
}


-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
    return self.pickerArray.count;
}


-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
    return [self.pickerArray objectAtIndex:row];
}

谢谢。

【问题讨论】:

  • 只需从 - (BOOL)textFieldShouldBeginEditing:(UITextField *)textField 委托方法中删除 [textField becomeFirstResponder];
  • @SweetAngel 我这样做了,它不再崩溃,但也没有显示选择器视图。任何想法为什么?
  • Bcoz,默认情况下,此委托会自动将响应者设置为相应的 UITextField
  • 你只是想在用户点击 textField 时显示 pickerView 吗?
  • @GenieWanted 是的

标签: ios uitextfield uipickerview


【解决方案1】:

尝试从以下方法中删除[textField becomeFirstResponder];

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField  {
    [textField becomeFirstResponder];
    return YES;
}

错误与选择器字段无关。选择文本字段时会自动调用becomeFirstResponder。所以这里不需要调用它,因为当你点击文本字段时它已经被调用了。

基本上你告诉文本字段是活跃的,成为活跃的......试一试,让我知道结果是什么。


关于选择器视图未显示,如果使用故事板,请确保您已正确连接 IBOutlets,同时在您的 .m 文件顶部编辑以下内容,使其如下所示:

之前:

@interface TestViewController ()

之后:

@interface TestViewController () <UIPickerViewDataSource, UIPickerViewDataSource>

【讨论】:

  • 是的,它可以工作,但是没有显示pickerView,这就是我现在卡在的地方
  • 您能否更新您的问题以显示您的 .h 文件?确保您的 IBOutlets 连接正确,我还想确保您在 .h 文件中设置了 因为它们没有在上面的 .m 文件中指定。
【解决方案2】:

要将您的 pickerview 作为您的第一响应者,请使用

- (void)textFieldDidBeginEditing:(UITextField *)textField {

     if([textField isEqual:classField]) {

        [textField setInputView:picker]; //edited ones
        [picker becomeFirstResponder];

        }
    }

使用这个方法, 它会帮助你。

【讨论】:

  • 我添加了一个工具栏,它会显示,但是当我单击文本字段时,pickerView 仍然没有显示
  • 如果没有初始化你的选择器picker = [[UIPickerView alloc] initWithFrame:CGRectMake(x,y,width,height)];
  • 你在使用pickerview代表吗
【解决方案3】:
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
    if ([self.classField isEditing]) {
        [self.picker selectRow:0 inComponent:0 animated:YES]; //This is not necessary but I prefer it for my purpose
        [self.picker reloadAllComponents];
    }
}

并确保您的 TextField 代表正在调用... 意味着 &lt;UITextFieldDelegate&gt; 必须在您的 .h 文件中,例如 &lt;UITextFieldDelegate, UIPickerViewDelegate, UIPickerViewDataSource&gt; 希望这对您有所帮助...

如果这不起作用,那么试试这个

    self.picker = [[UIPickerView alloc]initWithFrame:CGRectZero];
    [self.picker setDataSource:self];
    [self.picker setDelegate:self];
    [self.classField setInputView:self.picker] 

【讨论】: