UITextField, встроенный в UIView, не реагирует на сенсорные события - PullRequest
3 голосов
/ 29 декабря 2010

В моем проекте я использую UITextField, который встроен в простой белый UIButton с закругленными углами, чтобы создать «красивое» текстовое поле.Этот код используется несколько раз в разных представлениях, поэтому я решил создать пользовательский UIView для этой цели.Код для этого пользовательского UIView:

BSCustomTextField.h

#import <Foundation/Foundation.h>

@interface BSCustomTextField : UIView {
  UIButton* btnTextFieldContainer;
  UITextField* textField;
  NSString* text;
}

@property (retain, nonatomic) UIButton* btnTextFieldContainer;
@property (retain, nonatomic) UITextField* textField;
@property (retain, nonatomic) NSString* text;

-(id)initWithPosition:(CGPoint)position;
@end

BSCustomTextField.m

#import "BSCustomTextField.h"
#import <QuartzCore/QuartzCore.h>

@implementation BSCustomTextField
@synthesize btnTextFieldContainer, textField, text;

-(id)initWithPosition:(CGPoint)position{
   if (self == [super init]) {
      btnTextFieldContainer = [[UIButton alloc] initWithFrame:CGRectMake(position.x, position.y, 260, 50)];
      btnTextFieldContainer.backgroundColor = [UIColor whiteColor];
      [[btnTextFieldContainer layer] setCornerRadius:3.];
      [[btnTextFieldContainer layer] setMasksToBounds:YES];
      [[btnTextFieldContainer layer] setBorderWidth:0.];

      textField = [[UITextField alloc] initWithFrame:CGRectMake(10, 10, 240, 30)];

      textField.backgroundColor = [UIColor whiteColor];
      textField.clearButtonMode = UITextFieldViewModeAlways;
      textField.returnKeyType   = UIReturnKeySend;
      textField.keyboardType    = UIKeyboardTypeEmailAddress;
      textField.font               = [UIFont fontWithName:@"Helvetica-Bold" size:20.];

      [btnTextFieldContainer addSubview:textField];
      [self addSubview:btnTextFieldContainer];
   }
   return self;
}

-(void)dealloc{
   [btnTextFieldContainer release];
   [textField release];
   [super dealloc];
}
@end

Итак, при использовании этого представления в viewDidLoad вида контейнера (см. Код ниже) вид должным образом отображается в нужной позиции и выглядит точно так, как указано, но он не реагирует на события касания и, таким образом, не становится первым респондентом при касании.

Код:

searchTextField = [[BSCustomTextField alloc] initWithPosition:CGPointMake(30, 150)];
searchTextField.textField.placeholder       = NSLocalizedString(@"lsUserName", @"");
[[(BSPlainHeaderWithBackButtonView*)self.view contentView] addSubview:searchTextField];

Вызов [searchTextField.textField intoFirstResponder] программно работает правильно и заставляет клавиатуру появляться.

Но интересная часть, если я встраиваюкод BSCustomTextField , встроенный в мой контейнер, примерно так:

UIButton* btnTextFieldContainer = [[UIButton alloc] initWithFrame:CGRectMake(30, 150, 260, 50)];
btnTextFieldContainer.backgroundColor = [UIColor whiteColor];
[[btnTextFieldContainer layer] setCornerRadius:3.];
[[btnTextFieldContainer layer] setMasksToBounds:YES];
[[btnTextFieldContainer layer] setBorderWidth:0.];

searchTextField = [[UITextField alloc] initWithFrame:CGRectMake(10, 10, 240, 30)];

searchTextField.backgroundColor = [UIColor whiteColor];
searchTextField.clearButtonMode = UITextFieldViewModeAlways;
searchTextField.returnKeyType   = UIReturnKeySend;
searchTextField.keyboardType    = UIKeyboardTypeEmailAddress;
searchTextField.font            = [UIFont fontWithName:@"Helvetica-Bold" size:20.];
searchTextField.placeholder     = NSLocalizedString(@"lsUserName", @"");

[btnTextFieldContainer addSubview:searchTextField];
[[(BSPlainHeaderWithBackButtonView*)self.view contentView] addSubview:btnTextFieldContainer];
[btnTextFieldContainer release];

все работает как положено, и текстовое поле реагирует на прикосновения.Тип searchTextField правильно устанавливается в заголовочном файле для каждого случая.Единственная разница в том, что в первом случае у меня есть дополнительная упаковка UIView на UIButton и UITextFiled.Я понятия не имею, что нужно сделать, чтобы текстовое поле стало первым респондентом при прикосновении.

Заранее большое спасибо, Роман

Ответы [ 3 ]

4 голосов
/ 29 декабря 2010

Хорошо, у меня есть решение.Точка зрения raaz на класс UIResponder подтолкнула меня к мысли, что в цепочке респондента должно быть что-то не так, поэтому я провел небольшое исследование и нашел эту тему: Разрешение взаимодействия с UIView под другим UIView , в которомТочно такая же проблема обсуждается.
Вот новый рабочий код для BSCustomTextField.m

#import "BSCustomTextField.h"
#import <QuartzCore/QuartzCore.h>


@implementation BSCustomTextField
@synthesize btnTextFieldContainer, textField, text;

-(id)initWithPosition:(CGPoint)position{
  if (self == [super init]) {
    btnTextFieldContainer = [[UIButton alloc] initWithFrame:CGRectMake(position.x, position.y, 260, 50)];
    btnTextFieldContainer.backgroundColor = [UIColor whiteColor];
    [[btnTextFieldContainer layer] setCornerRadius:3.];
    [[btnTextFieldContainer layer] setMasksToBounds:YES];
    [[btnTextFieldContainer layer] setBorderWidth:0.];

    textField = [[UITextField alloc] initWithFrame:CGRectMake(10, 10, 240, 30)];

    textField.backgroundColor = [UIColor whiteColor];
    textField.clearButtonMode = UITextFieldViewModeAlways;
    textField.returnKeyType   = UIReturnKeySend;
    textField.keyboardType    = UIKeyboardTypeEmailAddress;
    textField.font             = [UIFont fontWithName:@"Helvetica-Bold" size:20.];

    [btnTextFieldContainer addSubview:textField];
    [self addSubview:btnTextFieldContainer];
  }
  return self;
}

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    // UIView will be "transparent" for touch events if we return NO
    return YES;
}

-(void)dealloc{
  [btnTextFieldContainer release];
  [textField release];
  [super dealloc];
}
@end 

Поскольку область, на которую можно кликнуть, заполняет все представление BSCustomTextField, мы можем просто вернуть YES в pointInside: withEvent:

Спасибо всем, что указали мне правильное направление.

1 голос
/ 29 декабря 2010

См. UIResponder класс

В этом классе есть метод экземпляра becomeFirstResponder: & isFirstResponder:

Также не забудьте установить свойство textfield editing в YES

0 голосов
/ 29 декабря 2010

О, вы совершенно не правы, поступая таким образом. Вы должны добавить растягиваемое изображение в UIImageView и поместить его ниже UITextField.

UIImage *backgroundImage = [[UIImage imageNamed:@"fieldBackground.png"] stretchableImageWithLeftCapWidth:12.0 topCapHeight:0.0];

Или вы можете попробовать отключить userInteraction в UIButton.

...