使用自定义inputAccessoryView自定义uitextfield

时间:2014-02-17 16:06:30

标签: ios objective-c uitextfield

在所有堆栈溢出中对此问题毫无疑问是奇怪的,但我找不到它:(

让我解释一下。我有一个简单的UITextField应该提供自定义inputAccessoryView

预期的行为是:

  1. 点击文本字段(ACTextField)
  2. 显示带有文本字段和按钮(带取消标题)的键盘
  3. 输入一些文字(它必须出现在UITextFieldinputField
  4. 按Enter键并查看主文本字段中显示的文字
  5. 如果我按下取消,键盘应该消失并让主文本域取消替换

    非常类似Apple的消息应用程序

    所有作品都很好地解决了两件事:

    1. 如果我在键盘上点击垃圾键(只是为了输入随机文本;) )应用程序冻结和Xcode显示CPU为99%(无法恢复)
    2. 有时内存占用从之后的2/3 MB增长到40 MB 按回车键,应用程序再次冻结
    3. 让我们展示一些代码 .h

      #import <UIKit/UIKit.h>
      
      @interface ACTextField : UITextField
      
      @end
      

      .m

      #import "ACTextField.h"
      
      @interface ACTextField () <UITextFieldDelegate>
      
      @property (nonatomic, retain) UITextField *inputField;
      @property (nonatomic, assign) BOOL keyboardOpen; // to check if keyboard is open
      @property (nonatomic, retain) NSTimer *timer; //added after an answer
      
      @end
      
      @implementation ACTextField
      
      // method called when timer fire
      - (void) fireTimer:(NSTimer *) timer
      {
          [self.timer invalidate];
          self.timer = nil; // this line thoesen't change anyting so can be deleted
          [self.inputField becomeFirstResponder];
      }
      
      - (id)initWithFrame:(CGRect)frame
      {
          self = [super initWithFrame:frame];
          if (self) {
              // Initialization code
              [self awakeFromNib];
          }
          return self;
      }
      
      -(void)awakeFromNib
      {
          self.delegate = self;
          self.keyboardOpen = NO;
      }
      
      - (void)cancelPressed:(id)sender
      {
          [self.inputField resignFirstResponder];
          [self resignFirstResponder];
      
          self.keyboardOpen = NO;
      }
      
      - (void)dealloc
      {
          NSLog(@"dealloc ACTextField %@", self);
          self.inputField = nil;
          self.timer = nil;
      }
      
      - (void) designAccessoryView
      {
          if (self.inputAccessoryView == nil) {
      
              CGRect frame = [[UIScreen mainScreen] bounds];
      
              self.inputAccessoryView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, 44)];
      
              self.inputAccessoryView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
      
              int buttonWidth = 65;
              int padding = 5;
      
              UIButton *cancel = [UIButton buttonWithType:UIButtonTypeCustom];
              cancel.frame = CGRectMake(padding, 0, buttonWidth, 44);
              [cancel setTitle:@"cancel" forState:UIControlStateNormal];
              [cancel setTitle:@"cancel" forState:UIControlStateHighlighted];
              [cancel addTarget:self action:@selector(cancelPressed:) forControlEvents:UIControlEventTouchUpInside];
              [self.inputAccessoryView addSubview:cancel];
      
              self.inputField = [[UITextField alloc] initWithFrame:CGRectMake(buttonWidth + 2*padding, 2, frame.size.width - buttonWidth - 3*padding, 40)];
              self.inputField.borderStyle = UITextBorderStyleRoundedRect;
      
              self.inputField.delegate = self;
      
              [self.inputAccessoryView addSubview:self.inputField];
              self.inputAccessoryView.backgroundColor = [UIColor lightGrayColor];
          }
      }
      
      - (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
          return YES;
      }
      - (void)textFieldDidBeginEditing:(UITextField *)textField
      {
          if (!self.keyboardOpen && textField == self)
          {
              self.inputField.text = self.text;
              [self designAccessoryView];
      
              self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1
                                               target:self // modified to use the instance method fireTimer
                                             selector:@selector(fireTimer:)
                                             userInfo:nil
                                              repeats:NO];
      
              self.keyboardOpen = YES;
          }
      }
      - (BOOL)textFieldShouldEndEditing:(UITextField *)textField
      {
          return YES;
      }
      
      - (void)textFieldDidEndEditing:(UITextField *)textField
      {
      }
      
      - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
      {
          return YES;
      }
      
      - (BOOL)textFieldShouldClear:(UITextField *)textField
      {
          return YES;
      }
      
      - (BOOL)textFieldShouldReturn:(UITextField *)textField{
      
          self.text = self.inputField.text;
          [self cancelPressed:self];
      
          return YES;
      }
      
      @end
      

      非常感谢任何帮助

      编辑:我忘了指定我在IOS 7.0.4的iPhone 4s上进行测试

      EDIT2:我尝试使用UITextField Wrapper和几乎相同的代码,一切顺利。行为是预期的,键盘不再冻结,内存保持低位。好的,但我需要一个UITextField子类,而不是一个包装器:(

0 个答案:

没有答案