在输入附件视图中显示带有UITextField的键盘

CLD*_*Dev 15 uitextfield ios

我有一个buttonA,当单击buttonA时,我希望键盘在inputAccessoryView中显示UITextField.有没有办法让键盘显示手动,并设置inputAccessoryView最初没有UITextField?

谢谢.

liu*_*ong 9

没有可以成为第一响应者的对象,您无法召唤键盘.有两种解决方法:

  • 子类a UIViewUIKeyInput在其中实现协议.例如:

    在你的.h文件中:

    @interface InputObject : UIView<UIKeyInput>
    @property (nonatomic, copy) NSString *text;
    @property (nonatomic, strong) UIView *inputAccessoryView; // You must override inputAccessoryView , since it's readonly by default
    @end
    
    Run Code Online (Sandbox Code Playgroud)

    在.m文件中,实现协议:

    - (BOOL)canBecomeFirstResponder
    {
        return YES;
    }
    
    - (BOOL)hasText
    {
        return [self.text length];
    }
    
    - (void)insertText:(NSString *)text
    {
        NSString *selfText = self.text ? self.text : @"";
        self.text = [selfText stringByAppendingString:text];
        [[NSNotificationCenter defaultCenter] postNotificationName:kInputObjectTextDidChangeNotification object:self];
    }
    
    - (void)deleteBackward
    {
        if ([self.text length] > 0)
            self.text = [self.text substringToIndex:([self.text length] - 1)];
        else
            self.text = nil;
        [[NSNotificationCenter defaultCenter] postNotificationName:kInputObjectTextDidChangeNotification object:self];
    }
    
    Run Code Online (Sandbox Code Playgroud)

假设你要在你的召唤键盘-viewDidAppear:,代码是这样的:

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // inputObject and textField are both your ivars in your view controller
        inputObject = [[InputObject alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
        textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 100, 30)];
        inputObject.inputAccessoryView = textField;
        [self.view addSubview:inputObject];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(inputObjectTextDidChange:) name:kInputObjectTextDidChangeNotification object:nil];

    }

    - (void)viewDidAppear:(BOOL)animated
    {
        [super viewDidAppear:animated];
        [inputObject becomeFirstResponder]; // This will summon the keyboard
    }
Run Code Online (Sandbox Code Playgroud)

然后在视图控制器中实现通知选择器:

    - (void)inputObjectTextDidChange:(NSNotification *)notification
    {
        // Just set the text here. notification.object is actually your inputObject.
        textField.text = ((InputObject *)(notification.object)).text;
    }
Run Code Online (Sandbox Code Playgroud)

这可能是你所说的"设置inputAccessoryView而没有最初的UITextField"

  • 另一个解决方法是让textField"假装" inputAccessoryView通过仔细安排其动画.但是这个解决方案需要你的textField成为第一个响应者.

首先,您将观察以下键盘事件-viewDidLoad:

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Init the textField and add it as a subview of self.view
        textField = [[UITextField alloc] init];
        textField.backgroundColor = [UIColor redColor];
        [self.view addSubview:textField];

        // Register keyboard events
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShowNotification:) name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHideNotification:) name:UIKeyboardWillHideNotification object:nil];
    }
Run Code Online (Sandbox Code Playgroud)

其次,设置你的框架textField-viewWillAppear:,以保证它的框架将不会被自动尺寸的影响:

    - (void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
        textField.frame = CGRectMake(0, CGRectGetMaxY(self.view.bounds), CGRectGetWidth(self.view.bounds), 50);
    }
Run Code Online (Sandbox Code Playgroud)

然后,排列textField动画并让它与键盘动画同步.您的键盘通知选择器可能如下所示:

    - (void)keyboardWillShowNotification:(NSNotification *)notification
    {
        NSDictionary *userInfo = notification.userInfo;
        UIViewAnimationCurve curve = [[userInfo valueForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];
        CGFloat duration = [[userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
        CGRect keyboardFrame = [[userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
        keyboardFrame = [self.view convertRect:keyboardFrame toView:self.view];

        [UIView animateWithDuration:duration delay:0.0f options:(UIViewAnimationOptions)curve animations:^{
            CGRect textFieldFrame = textField.frame;
            textFieldFrame.origin.y = keyboardFrame.origin.y - CGRectGetHeight(textFieldFrame);
            textField.frame = textFieldFrame;
        }completion:nil];
    }

    - (void)keyboardWillHideNotification:(NSNotification *)notification
    {
        NSDictionary *userInfo = notification.userInfo;
        UIViewAnimationCurve curve = [[userInfo valueForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];
        CGFloat duration = [[userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
        [UIView animateWithDuration:duration delay:0.0f options:(UIViewAnimationOptions)curve animations:^{
            textField.frame = CGRectMake(0, CGRectGetMaxY(self.view.bounds), CGRectGetWidth(self.view.bounds), 50);
        }completion:nil];
    }
Run Code Online (Sandbox Code Playgroud)

最后,调用[textField becomeFirstResponder]触发动画.


小智 7

另一种解决方案是将这些方法添加到您的UIViewController实现中:

- (void)viewDidLoad {
    [super viewDidLoad];
    [self reloadInputViews];
}

- (BOOL)canBecomeFirstResponder {
    return YES;
}

- (UIView *)inputAccessoryView {
    if (!_textField) {
        _textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
        _textField.backgroundColor = [UIColor whiteColor];
        _textField.delegate = self;
    }
    return _textField;
}

#pragma mark - UITextFieldDelegate

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    [textField resignFirstResponder];
    return YES;
}
Run Code Online (Sandbox Code Playgroud)

并将_textField变量添加到您的界面:

@interface ViewController : UIViewController <UITextFieldDelegate> {
    UITextField *_textField;
}
@end
Run Code Online (Sandbox Code Playgroud)


Ada*_*amG 1

解决此问题的一个巧妙的解决方案是在视图中有一个 UITextField 但隐藏,然后在其上调用 [textfieldBecomeFirstResponder]。

我刚刚测试了它,这有效

UITextField * randofield = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
[self.view addSubview:randofield];
// doesn't have to be hidden... but to be safe.
randofield.hidden = YES;
[randofield becomeFirstResponder];
Run Code Online (Sandbox Code Playgroud)

你必须让它成为视图的子视图,否则这将不起作用。