2013-08-15 19 views
13

Ho un pulsante A e quando si fa clic sul pulsanteA, voglio che la tastiera mostri con un UITextField in inputAccessoryView. C'è un modo per avere lo show della tastiera manualmente e anche impostare l'inputAccessoryView senza avere inizialmente un UITextField?Mostra tastiera con UITextField nella vista accessi di input

Grazie.

risposta

1

Una soluzione hacker a questo problema sarebbe quella di avere un UITextField nella vista ma nascosto e quindi chiamare [textfield becomeFirstResponder] su di esso.

ho appena provato e funziona

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]; 

Bisogna avere che si tratti di una visualizzazione secondaria di vista altrimenti questo non funzionerà.

5

Un'altra soluzione è quella di aggiungere questi metodi per il vostro UIViewController implementazione:

- (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; 
} 

e aggiungere la variabile _textField alla vostra interfaccia:

@interface ViewController : UIViewController <UITextFieldDelegate> { 
    UITextField *_textField; 
} 
@end 
9

Non si può evocare la tastiera senza un oggetto che può diventare primo soccorritore. Ci sono due modi per aggirare:

  • Sottoclasse un UIView e implementare UIKeyInput protocollo in esso. Per esempio:

    Nel file .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 
    

    Nel file .m, implementare il protocollo:

    - (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]; 
    } 
    

Diciamo che si vuole evocare la tastiera nella vostra -viewDidAppear:, il codice è simile al seguente:

- (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 
    } 

quindi implementare il selettore di notifica nel controller della vista:

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

Questo è probabilmente ciò che si intende per "impostare l'inputAccessoryView senza avere un UITextField inizialmente"

  • Un'altra soluzione è quella di lasciare che il textField "fingere" di essere il inputAccessoryView sistemando attentamente la sua animazione. Ma questa soluzione ha bisogno del tuo campo di testo per essere il primo a rispondere.

In primo luogo, si osserva gli eventi di tastiera nella vostra -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]; 
    } 

In secondo luogo, impostare la struttura del vostro textField in -viewWillAppear:, al fine di garantire la sua cornice non saranno interessati dal ridimensionamento automatico:

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

E quindi, organizza l'animazione textField e lascia che sia sincronizzata con l'animazione della tastiera. La tastiera selettori notifica può essere simile a questo:

- (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]; 
    } 

Infine, chiamare [textField becomeFirstResponder] per attivare l'animazione.

1

Versione rapida utilizzando i vincoli di autolayout in base alla risposta di liuyaodong.

È necessario disporre di un vincolo di spazio verticale tra la parte inferiore dello schermo e la vista testo. Si noti che l'impostazione dell'offset deve avvenire al di fuori del contesto di animazione e solo il layout avviene all'interno del contesto di animazione.

@IBOutlet weak var textViewBottomOffsetConstraint: NSLayoutConstraint! 

override public func viewDidLoad() { 
    super.viewDidLoad() 
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIKeyboardWillShowNotification, object: nil) 
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIKeyboardWillHideNotification, object: nil) 
} 

func keyboardWillHide(notification: NSNotification) { 
    guard let userInfo = notification.userInfo else { 
     return 
    } 

    animateTextFieldOffset(0, userInfo: userInfo) 
} 

func keyboardWillShow(notification: NSNotification) { 
    guard let userInfo = notification.userInfo, var keyboardFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue() else { 
     return 
    } 

    keyboardFrame = view.convertRect(keyboardFrame, toView: view) 

    animateTextFieldOffset(keyboardFrame.size.height, userInfo: userInfo) 
} 

func animateTextFieldOffset(offset: CGFloat, userInfo: [NSObject: AnyObject]){ 
    guard let animationCurveInt = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? Int, let animationCurve = UIViewAnimationCurve(rawValue:animationCurveInt) else { return } 

    guard let animationDuration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? Double else { return } 

    self.loginViewBottomOffsetConstraint.constant = offset 

    UIView.beginAnimations(nil, context: nil) 
    UIView.setAnimationDuration(animationDuration) 
    UIView.setAnimationCurve(animationCurve) 
    UIView.setAnimationBeginsFromCurrentState(true) 
    self.view.layoutIfNeeded() 
    UIView.commitAnimations() 
} 
+0

Sto ancora lavorando qui, ma sembra che questo sia stato scritto usando una versione precedente di Swift. Per chi guarda questo, ecco un post su NotificationCenter addObserver per Swift 3 http://stackoverflow.com/a/38615219/937682 – Mathieson

Problemi correlati