Обложки iPhone для iPhone UITextField



Answers

Это сработало чудеса для меня, скольжения uitextfields

В частности, это позволяет рассчитывать расстояние анимации слайда в зависимости от положения текстового поля.

Question

У меня есть приложение, где в интерфейсе Builder я настроил UIView , у которого есть текстовое поле в нижней части представления. Когда я запускаю приложение и пытаюсь ввести текст в это поле, клавиатура сдвигает верхнюю часть поля, поэтому я не вижу, что я набираю, пока не скрою клавиатуру.

Кто-нибудь еще столкнулся с этой проблемой и нашел хороший способ ее решить, не заставляя родительское представление прокручиваться или перемещать текстовое поле дальше экрана?




Я сталкиваюсь с той же проблемой в ячейках UITableView textField. Я решаю эту проблему, применяя следующий метод для прослушивания уведомления клавиатуры.

Наблюдатель для уведомлений здесь:

[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWillBeHidden:) name:UIKeyboardWillHideNotification object:nil];

Обращайтесь с этими уведомлениями с помощью функции ниже:

(void)keyboardWasShown:(NSNotification*)aNotification 
(void)keyboardWillBeHidden:(NSNotification*)aNotification 



https://github.com/ZulwiyozaPutra/Shift-Keyboard-Example Я надеюсь, что это решение помогло. Все они написаны Swift 3.

//
//  ViewController.swift
//  Shift Keyboard Example
//
//  Created by Zulwiyoza Putra on 11/23/16.
//  Copyright © 2016 Zulwiyoza Putra. All rights reserved.
//

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {
    
    
    //connecting textfield from storyboard
    @IBOutlet weak var textField: UITextField!
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        subscribeToKeyboardNotifications()
    }
    
    override func viewDidAppear(_ animated: Bool) {
        self.textField.delegate = self
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        unsubscribeFromKeyboardNotifications()
    }
    
    //Hide keyboard after finished editing
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }
    
    //Setup view before keyboard appeared
    func keyboardWillAppear(_ notification:Notification) {
        view.frame.origin.y = 0 - getKeyboardHeight(notification)
    }
    
    //Setup view before keyboard disappeared
    func keyboardWillDisappear(_ notification: Notification) {
        view.frame.origin.y = 0
    }
    
    //Getting keyboard height
    func getKeyboardHeight(_ notification:Notification) -> CGFloat {
        let userInfo = notification.userInfo
        let keyboardSize = userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue // of CGRect
        return keyboardSize.cgRectValue.height
    }
    
    //Subscribing to notifications to execute functions
    func subscribeToKeyboardNotifications() {
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillAppear(_:)), name: .UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillDisappear(_:)), name: .UIKeyboardWillHide, object: nil)
    }
    
    //Unsubscribing from notifications
    func unsubscribeFromKeyboardNotifications() {
        NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil)
        NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil)
    }
    
}




Как вы справляетесь с ситуацией, когда клавиатура вставлена, а кадр изменен с помощью анимации и прокручивается, поэтому текстовое поле не покрывается, оттуда, когда я выбираю другое текстовое поле (все еще редактируя первое текстовое поле), как я не могу воспроизвести анимацию снова и просто прокрутите немного дальше, если это необходимо? Проблема заключается в повторном воспроизведении всей анимации, когда она не нужна. благодаря




Чтобы расширить ответ от Amagrammer, вот пример класса:

LoginViewController.h

@interface LoginViewController : UIViewController <UITextFieldDelegate> {

}

@property (nonatomic, retain) IBOutlet UITextField    *emailTextField;
@property (nonatomic, retain) IBOutlet UITextField    *passwordTextField;

Обратите внимание, что мы реализуем «UITextFieldDelegate»

LoginViewController.m

@implementation LoginViewController
@synthesize emailTextField=_emailTextField;
@synthesize passwordTextField=_passwordTextField;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        //Register to receive an update when the app goes into the backround
        //It will call our "appEnteredBackground method
        [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(appEnteredBackground)
                                                 name:UIApplicationDidEnterBackgroundNotification
                                               object:nil];
    }
    return self;
}


- (void) animateTextField: (UITextField*) textField up: (BOOL) up
{
    const int movementDistance = 80; // tweak as needed
    const float movementDuration = 0.3f; // tweak as needed

    int movement = (up ? -movementDistance : movementDistance);

    [UIView beginAnimations: @"anim" context: nil];
    [UIView setAnimationBeginsFromCurrentState: YES];
    [UIView setAnimationDuration: movementDuration];
    self.view.frame = CGRectOffset(self.view.frame, 0, movement);
    [UIView commitAnimations];
}

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    [self animateTextField: textField up: YES];
}


- (void)textFieldDidEndEditing:(UITextField *)textField
{
    [self animateTextField: textField up: NO];
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [textField resignFirstResponder];
    return YES;
}
//This is called when the app goes into the background.
//We must reset the responder because animations will not be saved
- (void)appEnteredBackground{
    [self.emailTextField resignFirstResponder];
    [self.passwordTextField resignFirstResponder];
}



Вот решение, использующее Xcode5, iOS7:

Используйте блоки UITextfieldDelegate и анимации.

Это почти весь код для ViewController, но я хотел включить код делегата для тех, кто еще несколько не знаком с шаблоном делегата (например, я). Я также включил код, чтобы скрыть клавиатуру, когда вы касаетесь текста.

Вы можете перемещать представления (кнопки, текстовые поля и т. Д.) Настолько высоко, насколько вам хотелось бы просто позаботиться о том, чтобы они были на месте (+100, а затем - 100).

@interface ViewController () <UITextFieldDelegate>
@property (strong, nonatomic) IBOutlet UITextField *MyTextField;

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.MyTextField.delegate = self;

}

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
      NSLog(@"text began editing");

      CGPoint MyPoint = self.MyTextField.center;

      [UIView animateWithDuration:0.3
                    animations:^{

                    self.MyTextField.center = CGPointMake(MyPoint.x, MyPoint.y - 100);
                                }];
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
     NSLog(@"text ENDED editing");

     CGPoint MyPoint = self.MyTextField.center;

     [UIView animateWithDuration:0.3
                 animations:^{

     self.MyTextField.center = CGPointMake(MyPoint.x, MyPoint.y + 100);
                             }];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
     [self.view endEditing:YES];
}



У меня есть что-то еще, если хочешь. Дело в том, что вы хотите установить центр UIView в текстовое поле, которое вы редактируете.

До этого вам нужно сохранить INITIAL_CENTER , как CGPoint , из self.view.center и вашего INITIAL_VIEW как CGRect из self.view.frame в свойстве const.

Вы можете создать такой метод:

- (void) centerOn: (CGRect) fieldFrame {

    // Set up the center by taking the original view center
    CGPoint center = CGPointMake(INITIAL_CENTER.x,
                             INITIAL_CENTER.y - ((fieldFrame.origin.y + fieldFrame.size.height/2) - INITIAL_CENTER.y));


    [UIView beginAnimations:@"centerViewOnField" context:nil];
    [UIView setAnimationDuration:0.50];

    if (CGRectEqualToRect(fieldFrame,INITIAL_VIEW)) {
        self.view.frame = INITIAL_VIEW;
        [self.view setCenter:INITIAL_CENTER];
    } else {
        [self.view setCenter:center];
    }


    [UIView commitAnimations];
}

Затем, в UITextFieldDelegate , вы должны вызвать centerOn: (CGRect) следующими способами:

textFieldDidBeginEditing: (UITextField *) , в качестве параметра, кадр текстового поля, на котором вы хотите сосредоточиться .

И вы должны называть его в своем обработчике событий, где вы закрываете клавиатуру,

textFieldDidEndEditing: (UITextField *) может быть одним из способов сделать это, поставив INITIAL_VIEW в качестве параметра centerOn: (CGRect) .




Ниже приведена краткая версия ответа Аматоммера. Кроме того, вариант с использованием события UIKeyboardWillShowNotification, так как мне нужно было знать размер клавиатуры, прежде чем перемещать представление в сторону.

var keyboardHeight:CGFloat = 0

override func viewDidLoad() {
    super.viewDidLoad()
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillChange:", name: UIKeyboardWillShowNotification, object: nil)
}

func textFieldDidBeginEditing(textField: UITextField) {
    //keyboardWillChange (below) is used instead of textFieldDidBeginEditing because textFieldDidBeginEditing
    //is called before the UIKeyboardWillShowNotification necessary to determine the keyboard height.
}

func textFieldDidEndEditing(textField: UITextField) {
    animateTextField(false)
}

func animateTextField(textFieldUp:Bool) {
    let movementDistance:CGFloat = keyboardHeight
    let movementDuration = 0.3

    let movement:CGFloat = (textFieldUp ? -movementDistance : movementDistance)

    UIView.beginAnimations("anim", context: nil)
    UIView.setAnimationBeginsFromCurrentState(true)
    UIView.setAnimationDuration(movementDuration)
    self.view.frame = CGRectOffset(self.view.frame, 0, movement)
    UIView.commitAnimations()
}

func keyboardWillChange(notification:NSNotification) {
    let keyboardRect:CGRect = ((notification.userInfo![UIKeyboardFrameEndUserInfoKey])?.CGRectValue)!
    keyboardHeight = keyboardRect.height
    animateTextField(true)
}



В дополнение к решению Amagrammer, если вы используете cocos2d в портретном режиме, измените эту строку:

self.view.frame = CGRectOffset(self.view.frame, 0, movement);

к этому:

[CCDirector sharedDirector].openGLView.frame = CGRectOffset([CCDirector sharedDirector].openGLView.frame, movement, 0);

Если вы используете cocos2d в ландшафтном режиме, сделайте вышеуказанное изменение и переключите значения up в textFieldDidBeginEditing: и textFieldDidEndEditing:

- (void)textFieldDidBeginEditing:(UITextField *)textField {
    [self animateTextField:textField up:NO];
}

- (void)textFieldDidEndEditing:(UITextField *)textField {
    [self animateTextField:textField up:YES];
}








Links