3

在我的项目中,我使用了一个 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 becomeFirstResponder]可以正常工作并使键盘出现。

但是,有趣的是,如果我像这样将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 的类型在每个案例的头文件中正确设置。唯一的区别是,在第一种情况下,我在 UIButton 和 UITextFiled 上有一个额外的包装 UIView。我不知道该怎么做才能使文本字段成为第一响应者。

非常感谢,罗马

4

3 回答 3

4

好的,我有解决方案。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 视图,我们可以简单地在 pointInside:withEvent 中返回 YES:

感谢大家为我指明正确的方向。

于 2010-12-29T13:40:56.237 回答
1

参考UIResponder 类

这个类有实例方法becomeFirstResponder:&isFirstResponder:

也不要忘记将 textfieldediting属性设置为YES

于 2010-12-29T11:05:34.493 回答
0

哦,你这样做是完全错误的。您应该将可拉伸图像添加到 UIImageView 并将其放在 UITextField 下方。

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

或者您可以尝试在 UIButton 中禁用 userInteraction。

于 2010-12-29T11:15:11.897 回答