iPhone Keyboard Cover UITextField

120

Mam aplikację, w której w Interface Builder skonfigurowałem UIViewpole tekstowe w dolnej części widoku. Kiedy uruchamiam aplikację i próbuję wprowadzić tekst w tym polu, klawiatura przesuwa się nad pole, więc nie widzę, co piszę, dopóki ponownie nie ukryję klawiatury.

Czy ktoś inny napotkał ten problem i znalazł dobry sposób rozwiązania go bez przewijania widoku rodzica lub przesuwania pola tekstowego dalej w górę ekranu?

Cruinh
źródło

Odpowiedzi:

290

Typowym rozwiązaniem jest przesunięcie pola (i wszystkiego nad nim) w górę z animacją, a następnie z powrotem w dół, gdy skończysz. Może być konieczne umieszczenie pola tekstowego i niektórych innych elementów w innym widoku i przesunięcie widoku jako jednostki. (Nazywam te rzeczy „płytami” jak „płytami tektonicznymi”, ale to tylko ja). Ale tutaj jest ogólny pomysł, jeśli nie potrzebujesz fantazji.

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


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

- (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];
}
Amagrammer
źródło
12
Podoba mi się to, że nie opublikowałeś linku do kodu, ale sam kod.
Ben Coffman
2
Świetny kawałek kodu. Nie musiałem go edytować, żeby działał czy coś. Dzięki ~
James
5
Przydatne jest pokrycie całego ekranu, jak poniżej: const int motionDistance = textField.frame.origin.y / 2; // dostosuj w razie potrzeby
conecon
3
Muszę wspomnieć, że „Jeśli piszesz aplikację na iOS 4 lub nowszy, powinieneś zamiast tego użyć metod blokowych do animowania treści”. Źródła źródłowe: developer.apple.com/library/ios/#documentation/windowsviews/…
Mathieu,
1
Znaleziono to i omawia ten sam problem developer.apple.com/Library/ios/documentation/StringsTextFonts/ ...
unom
38

To zdziałało cuda dla mnie przesuwające się pola uitextfields

W szczególności ma tę zaletę, że oblicza odległość animacji slajdu w zależności od położenia pola tekstowego.

haftowane
źródło
To jest świetne. Nie musisz wybierać stałej „odległości ruchu” dla każdego pola tekstowego - jest ona obliczana za Ciebie.
jlstrecker,
Zdecydowanie najlepsze rozwiązanie. Fenomenalny mechanizm!
Marchy
1
Działa również świetnie na iPadzie. Właśnie zaktualizowałem PORTRAIT_KEYBOARD_HEIGHT = 264 i LANDSCAPE_KEYBOARD_HEIGHT = 352. Świetny link. Dzięki.
Khon Lieu,
Powyższy link właśnie sprawił, że mój dzień! Tak prosty w implementacji, jak dotąd działa bez zarzutu!
JimmyJammed
1
To jest najlepsze wyjaśnienie tego tematu. Inne samouczki używają widoków tabel, widoków przewijania itp. To faktycznie działa bez wchodzenia w żadne inne zawiłości, proste i proste. Dzięki za udostępnienie tego źródła.
Renexandro
28

IQKeyboardManager zrobi to za Ciebie BEZ LINII KODU , wystarczy przeciągnąć i upuścić powiązany plik źródłowy do projektu. IQKeyboardManager obsługuje również orientację urządzenia , automatyczne zarządzanie paskiem narzędzi UIT , keyboardDistanceFromTextField i znacznie więcej niż myślisz.

wprowadź opis obrazu tutaj

Oto schemat kontroli: Schemat blokowy sterowania

Krok 1: - Dodano powiadomienia o globalne UITextField, UITextVieworaz UIKeyboardw klasie singleton. Nazwałem to IQKeyboardManager .

Krok 2: - W przypadku stwierdzenia UIKeyboardWillShowNotification, UITextFieldTextDidBeginEditingNotificationczy UITextViewTextDidBeginEditingNotificationpowiadomień, a następnie postarać się o topMostViewControllerwystąpienie z UIWindow.rootViewControllerhierarchii. Aby prawidłowo ją odsłonić UITextField/ UITextViewna niej topMostViewController.viewnależy wyregulować ramkę.

Krok 3: - Obliczona oczekiwana odległość ruchu topMostViewController.vieww odniesieniu do pierwszej odpowiedzi UITextField/ UITextView.

Krok 4: - Przesunięto w topMostViewController.view.framegórę / w dół zgodnie z oczekiwaną odległością ruchu.

Krok 5: - W przypadku stwierdzenia UIKeyboardWillHideNotification, UITextFieldTextDidEndEditingNotificationczy UITextViewTextDidEndEditingNotificationzgłoszenie, a następnie ponownie spróbować uzyskać topMostViewControllerwystąpienie z UIWindow.rootViewControllerhierarchii.

Krok 6: - Obliczona zakłócona odległość, topMostViewController.viewktórą należy przywrócić do pierwotnej pozycji.

Krok 7: - Przywrócenie topMostViewController.view.framezgodnie z zakłóconą odległością.

Krok 8: - Utworzono instancję pojedynczej instancji klasy IQKeyboardManager podczas ładowania aplikacji, więc każde UITextField/ UITextVieww aplikacji dostosuje się automatycznie zgodnie z oczekiwaną odległością ruchu.

To wszystko

Mohd Iftekhar Qurashi
źródło
Przyjęta odpowiedź nie działała dla mnie. Ale ten tak.
uczeń
@ZaEeMZaFaR IQKeyboardManager jest również zoptymalizowany dla iPada. Czy możesz otworzyć problem w repozytorium biblioteki Github i przesłać projekt demonstracyjny demonstrujący problem z iPadem?
Mohd Iftekhar Qurashi
Dzięki za odpowiedź. Zrobię to, jeśli problem będzie się powtarzał, zanim skomentujesz, myślałem, że IQKeyboardManager nie jest uniwersalnym urządzeniem.
ZaEeM ZaFaR
Badając więcej, działa dobrze z iPadem na symulatorze, ale nie na rzeczywistym urządzeniu iPad. Działa doskonale również na iPhonie (urządzenie + symulator). Co może być problemem ?
ZaEeM ZaFaR
Jak już powiedziałem, powinieneś zgłosić problem w repozytorium github z projektem demonstracyjnym ze szczegółami wersji iOS i urządzenia, abyśmy mogli przyjrzeć się temu problemowi.
Mohd Iftekhar Qurashi
7

Aby rozwinąć odpowiedź Amagrammera, oto przykładowa klasa:

LoginViewController.h

@interface LoginViewController : UIViewController <UITextFieldDelegate> {

}

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

Zauważ, że implementujemy „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];
}
stebooks
źródło
+1 za wspomnienie UIApplicationDidEnterBackgroundNotification, w przeciwnym razie przesunie się bardziej w dół, jeśli naciśniesz przycisk Home i ponownie wejdziesz do aplikacji, powodując, że będzie brzydka i błędna.
Adil Soomro,
7

A co z oficjalnym rozwiązaniem: przenoszeniem treści umieszczonych pod klawiaturą

Dostosowywanie zawartości zazwyczaj obejmuje tymczasową zmianę rozmiaru jednego lub więcej widoków i umieszczenie ich tak, aby obiekt tekstowy pozostał widoczny. Najprostszym sposobem zarządzania obiektami tekstowymi za pomocą klawiatury jest osadzenie ich wewnątrz obiektu UIScrollView (lub jednej z jego podklas, takich jak UITableView). Po wyświetleniu klawiatury wystarczy zresetować obszar zawartości widoku przewijania i przewinąć żądany obiekt tekstowy na miejsce. W związku z tym w odpowiedzi na UIKeyboardDidShowNotification metoda obsługi wykona następujące czynności:

  1. Uzyskaj rozmiar klawiatury.
  2. Dopasuj dolną wstawkę treści widoku przewijania za pomocą wysokości klawiatury.
  3. Przewiń docelowe pole tekstowe do widoku.
// Call this method somewhere in your view controller setup code.
- (void)registerForKeyboardNotifications
{
    [[NSNotificationCenter defaultCenter] addObserver:self
            selector:@selector(keyboardWasShown:)
            name:UIKeyboardDidShowNotification object:nil];

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

}

// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
    scrollView.contentInset = contentInsets;
    scrollView.scrollIndicatorInsets = contentInsets;

    // If active text field is hidden by keyboard, scroll it so it's visible
    // Your app might not need or want this behavior.
    CGRect aRect = self.view.frame;
    aRect.size.height -= kbSize.height;
    if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) {
        [self.scrollView scrollRectToVisible:activeField.frame animated:YES];
    }
}

// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    UIEdgeInsets contentInsets = UIEdgeInsetsZero;
    scrollView.contentInset = contentInsets;
    scrollView.scrollIndicatorInsets = contentInsets;
}
Mars
źródło
To oficjalne rozwiązanie jest teraz zapakowane w kontrolę, patrz tutaj: - stackoverflow.com/a/17707094/1582217
Mohd Iftekhar Qurashi
Pomysł jest dobry, ale właściwość „contentInset” nie pomaga, coz contentInset zapewni tylko efekt wypełnienia: stackoverflow.com/a/10049782/260665
Raj Pawan Gumdal
@Raj, To może być przypadek, który mogę sprawdzić na IQKeyboardManager, ale nadal nikt nie otwiera żadnych problemów w oficjalnym repozytorium github IQKeyboardManager dotyczących problemu z właściwością contentInset, więc zakładam, że działa.
Mohd Iftekhar Qurashi,
7

Mam ten sam problem w UITableView komórkach textField. Rozwiązuję ten problem, wdrażając następującą metodę odsłuchiwania powiadomienia z klawiatury.

Obserwator powiadomień tutaj:

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

Obsługuj te powiadomienia, korzystając z poniższej funkcji:

(void)keyboardWasShown:(NSNotification*)aNotification 
(void)keyboardWillBeHidden:(NSNotification*)aNotification 
Boobalan
źródło
1
Link jest uszkodzony. Rozważ uwzględnienie w przyszłości niezależnego rozwiązania!
miek
5

Sprawdź to. Nie ma dla ciebie kłopotów.

To bardzo fajne rozwiązanie. Wszystko, co musisz zrobić, to dodać pola tekstowe w a UIScrollViewi zmienić jego klasę na TPKeyboardAvoidingScollView, jeśli używasz scenorysów. Widok przewijania jest rozszerzony w taki sposób, że wykrywałby widoczność klawiatury i przesuwał się nad klawiaturą w rozsądnej odległości. Jest to idealne rozwiązanie, ponieważ jest niezależne od Twojego UIViewController. Wszystko, co niezbędne, jest wykonywane w ramach wyżej wymienionej klasy. Dzięki Michael Tyson i wszystkim.

TPKeyboard Unikanie

Aruna
źródło
@NANNAV - Prosimy o komentarze, gdy zgłaszasz sugestie dotyczące modyfikacji odpowiedzi.
Security Hound
5

Poniżej znajduje się szybka wersja odpowiedzi Amagrammera. Również odmiana wykorzystująca zdarzenie UIKeyboardWillShowNotification, ponieważ potrzebowałem znać rozmiar klawiatur przed przeniesieniem widoku z drogi.

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)
}
Justin Domnitz
źródło
4

Był świetny przewodnik po edytowaniu pól tekstowych bez zasłaniania (link martwy, tutaj jest link Wayback: https://web.archive.org/web/20091123074029/http://acts-as-geek.blogspot.com/2009/ 11 / edit-textfields-without-obscuring.html ). Pokazuje, jak przenieść istniejący UIViewdo a UIScrollViewi przewijać go automatycznie, gdy pojawi się klawiatura.

Zaktualizowałem go nieco, aby obliczyć prawidłową wysokość dla UIScrollViewkontrolek (takich jak a UITabBar) poniżej UIScrollBar. Zobacz post aktualizujący uiview .

GargantuChet
źródło
2

Oto rozwiązanie wykorzystujące Xcode5, iOS7:

Użyj bloków UITextfieldDelegate i animacji.

To jest prawie cały kod dla ViewController, ale chciałem dołączyć kod delegata dla tych, którzy wciąż nie znają wzorca delegata (jak ja). Dołączyłem również kod, aby ukryć klawiaturę po dotknięciu z dala od widoku tekstu.

Możesz przesuwać widoki (przyciski, pola tekstowe itp.) Tak wysoko, jak chcesz, po prostu pamiętaj, aby umieścić je z powrotem na miejscu (+100, a następnie -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];
}
Ethan Parker
źródło
1

Myślę, że jednym ze sposobów byłoby przesunięcie całej pozycji widoku z (x, y) do (x, y-keybaardHeight) po kliknięciu pola tekstowego i umieszczenie go z powrotem po zamknięciu klawiatury, może wyglądać trochę dziwnie, ponieważ widok po prostu pojawi się (może nie byłoby źle, gdybyś go animował).

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    CGRect frame=self.view.frame;
    frame.origin=CGPointMake(x...//set point here
    self.view.frame=frame;
}
Daniel
źródło
Nie, nie jest. Jeśli użytkownik dotknie pierwszego pola tekstowego, pojawi się ono nad widocznym obszarem.
lolol
0

Oprócz rozwiązania Amagrammera, jeśli używasz cocos2d w trybie portretowym, zmień tę linię:

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

do tego:

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

Jeśli używasz cocos2d w trybie poziomym, dokonaj powyższej zmiany i przełącz upwartości w textFieldDidBeginEditing:itextFieldDidEndEditing:

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

- (void)textFieldDidEndEditing:(UITextField *)textField {
    [self animateTextField:textField up:YES];
}
Żelazny Mike
źródło
0

Miałem ten sam problem i stwierdziłem, że GTKeyboardHelper jest łatwym wyjściem.

Po przeciągnięciu i upuszczeniu struktury w projekcie, dołącz plik nagłówkowy. Pobierz i otwórz przykładowy projekt, a następnie przeciągnij obiekt „Pomocnik klawiatury” z sekcji obiektów w xib do sekcji obiektów w kreatorze interfejsów projektu.

Przeciągnij i upuść wszystkie swoje widoki, aby być dziećmi „Pomocnika klawiatury”.

Andrei Nagy
źródło
0

Przeciągnij i upuść framework, którego używam w moich projektach. Obsługuje automatyczne zwalnianie po dotknięciu poza pierwszą osobą reagującą lub podczas przewijania.

GTKeyboardHelper

mackross
źródło
0

Po prostu przesuń widok w górę iw dół, jeśli to konieczne:

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

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    [self.currentTextField resignFirstResponder];
    return YES;
}

- (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 animateWithDuration:movementDuration animations:^{
        self.view.frame = CGRectOffset(self.view.frame, 0, movement);
    }];
}

Nie zapomnij ustawić selfjako UITextFieldDelegatei jako rzeczywistego pola tekstowego delegate.

(Dzięki Ammagrammer to po prostu krótsza odpowiedź wykorzystująca bloki do animacji)

dulgan
źródło
0

Mam coś innego, jeśli chcesz. Chodzi o to, że chcesz ustawić środek UIView na polu tekstowym, które edytujesz.

Wcześniej musisz zapisać swoje INITIAL_CENTER jako CGPoint z self.view.center i INITIAL_VIEW jako CGRect z self.view.frame we właściwości const.

Możesz utworzyć taką metodę:

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

Następnie na swoim UITextFieldDelegate musisz zadzwonić do centrum telefonicznegoOn : (CGRect) w następujących metodach:

textFieldDidBeginEditing: (UITextField *) z parametrem ramką pola tekstowego, na którym chcesz wyśrodkować.

I musisz to wywołać w swoim programie obsługi zdarzeń, gdzie zamykasz klawiaturę,

textFieldDidEndEditing: (UITextField *) może być jednym ze sposobów, aby to zrobić, umieszczając INITIAL_VIEW jako parametr centerOn: (CGRect) .

Jissay
źródło
0

Uważam, że w nowszych wersjach iOS (6.1+, być może nawet wcześniej), podstawowy widok, przynajmniej dla UITableView, automatycznie się zmniejsza, gdy pojawia się klawiatura. Musisz więc tylko pokazać pole tekstowe w tym widoku. W init:

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

następnie:

- (void)keyboardWasShown:(NSNotification*)notification
{
    // Scroll the text field into view so it's not under the keyboard.
    CGRect rect = [self.tableView convertRect:inputView.bounds fromView:inputView];
    [self.tableView scrollRectToVisible:rect animated:YES];
}
Lawrence Kesteloot
źródło
0

https://github.com/ZulwiyozaPutra/Shift-Keyboard-Example Mam nadzieję, że to rozwiązanie pomogło. Wszystkie są napisane w języku 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)
    }
    
}

Zulwiyoza Putra
źródło