Pertanyaan Bagaimana saya bisa membuat UITextField naik ketika keyboard hadir?


Dengan SDK iOS:

Saya punya UIView dengan UITextFields yang memunculkan keyboard. Saya membutuhkannya agar dapat:

  1. Izinkan pengguliran konten dari UIScrollView untuk melihat bidang teks lain setelah keyboard dinyalakan

  2. Secara otomatis "melompat" (dengan menggulir ke atas) atau memendekkan

Saya tahu bahwa saya membutuhkan UIScrollView. Saya sudah mencoba mengubah kelas saya UIView ke a UIScrollView tetapi saya masih tidak dapat menggulir kotak teks ke atas atau ke bawah.

Apakah saya membutuhkan keduanya a UIView dan a UIScrollView? Apakah orang masuk ke dalam yang lain?

Apa yang perlu diterapkan agar dapat menggulir ke bidang teks aktif secara otomatis?

Idealnya sebanyak setup komponen mungkin akan dilakukan di Interface Builder. Saya hanya ingin menulis kode untuk apa yang membutuhkannya.

Catatan: UIView (atau UIScrollView) yang saya kerjakan dibesarkan oleh tabbar (UITabBar), yang perlu berfungsi seperti biasa.


Edit: Saya menambahkan scroll bar hanya ketika keyboard muncul. Meskipun tidak diperlukan, saya merasa seperti itu menyediakan antarmuka yang lebih baik karena kemudian pengguna dapat menggulir dan mengubah kotak teks, misalnya.

Saya telah membuatnya bekerja di mana saya mengubah ukuran frame UIScrollView saat keyboard naik dan turun. Saya hanya menggunakan:

-(void)textFieldDidBeginEditing:(UITextField *)textField { 
    //Keyboard becomes visible
    scrollView.frame = CGRectMake(scrollView.frame.origin.x, 
                     scrollView.frame.origin.y, 
scrollView.frame.size.width,
scrollView.frame.size.height - 215 + 50);   //resize
}

-(void)textFieldDidEndEditing:(UITextField *)textField {
   //keyboard will hide
    scrollView.frame = CGRectMake(scrollView.frame.origin.x, 
       scrollView.frame.origin.y, 
     scrollView.frame.size.width,
      scrollView.frame.size.height + 215 - 50); //resize
}

Namun, ini tidak secara otomatis "bergerak ke atas" atau pusat bidang teks yang lebih rendah di area yang terlihat, yang adalah apa yang benar-benar saya sukai.


1556


asal


Jawaban:


  1. Anda hanya akan membutuhkan ScrollView jika isi yang Anda miliki sekarang tidak muat di layar iPhone. (Jika Anda menambahkan ScrollView sebagai superview dari komponen. hanya untuk membuat TextField gulir ke atas ketika keyboard muncul, maka itu tidak diperlukan.)

  2. Untuk menunjukkan textfields tanpa disembunyikan oleh keyboard, cara standarnya adalah naik / turun tampilan dengan textfields setiap kali keyboard ditampilkan.

Berikut ini beberapa contoh kode:

#define kOFFSET_FOR_KEYBOARD 80.0

-(void)keyboardWillShow {
    // Animate the current view out of the way
    if (self.view.frame.origin.y >= 0)
    {
        [self setViewMovedUp:YES];
    }
    else if (self.view.frame.origin.y < 0)
    {
        [self setViewMovedUp:NO];
    }
}

-(void)keyboardWillHide {
    if (self.view.frame.origin.y >= 0)
    {
        [self setViewMovedUp:YES];
    }
    else if (self.view.frame.origin.y < 0)
    {
        [self setViewMovedUp:NO];
    }
}

-(void)textFieldDidBeginEditing:(UITextField *)sender
{
    if ([sender isEqual:mailTf])
    {
        //move the main view, so that the keyboard does not hide it.
        if  (self.view.frame.origin.y >= 0)
        {
            [self setViewMovedUp:YES];
        }
    }
}

//method to move the view up/down whenever the keyboard is shown/dismissed
-(void)setViewMovedUp:(BOOL)movedUp
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3]; // if you want to slide up the view

    CGRect rect = self.view.frame;
    if (movedUp)
    {
        // 1. move the view's origin up so that the text field that will be hidden come above the keyboard 
        // 2. increase the size of the view so that the area behind the keyboard is covered up.
        rect.origin.y -= kOFFSET_FOR_KEYBOARD;
        rect.size.height += kOFFSET_FOR_KEYBOARD;
    }
    else
    {
        // revert back to the normal state.
        rect.origin.y += kOFFSET_FOR_KEYBOARD;
        rect.size.height -= kOFFSET_FOR_KEYBOARD;
    }
    self.view.frame = rect;

    [UIView commitAnimations];
}


- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    // register for keyboard notifications
    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillShow)
                                             name:UIKeyboardWillShowNotification
                                           object:nil];

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

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    // unregister for keyboard notifications while not visible.
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                             name:UIKeyboardWillShowNotification
                                           object:nil];

    [[NSNotificationCenter defaultCenter] removeObserver:self
                                             name:UIKeyboardWillHideNotification
                                           object:nil];
}

970



Saya juga mengalami banyak masalah dengan UIScrollView menyusun beberapa UITextFields, yang, satu atau lebih dari mereka akan dikaburkan oleh keyboard ketika mereka sedang diedit.

Berikut beberapa hal yang perlu diperhatikan jika Anda UIScrollView tidak bergulir dengan benar.

1) Pastikan bahwa konten Anda berukuran lebih besar daripada UIScrollView ukuran bingkai. Cara memahami UIScrollViews Apakah itu UIScrollView seperti jendela tampilan pada konten yang didefinisikan dalam contentSize. Jadi ketika dalam rangka untuk UIScrollview untuk menggulir ke mana saja, contentSize harus lebih besar daripada UIScrollView. Lain, tidak ada scroll yang diperlukan karena semua yang didefinisikan dalam contentSize sudah terlihat. BTW, default contentSize = CGSizeZero.

2) Sekarang Anda mengerti bahwa UIScrollView sebenarnya adalah jendela ke "konten" Anda, cara untuk memastikan bahwa keyboard tidak menutupi Anda UIScrollView's melihat "jendela" akan mengubah ukuran UIScrollView sehingga ketika keyboard hadir, Anda memiliki UIScrollView jendela berukuran hanya aslinya UIScrollView frame.size.height minus tinggi keyboard. Ini akan memastikan bahwa jendela Anda hanya area kecil yang dapat dilihat.

3) Inilah tangkapannya: Ketika saya pertama kali menerapkan ini, saya pikir saya harus mendapatkan CGRect dari textfield yang diedit dan panggilan UIScrollView's metode scrollRecToVisible. Saya mengimplementasikan UITextFieldDelegate metode textFieldDidBeginEditing dengan panggilan ke scrollRecToVisible metode. Ini benar-benar bekerja dengan efek samping yang aneh yang akan bergulir jepret itu UITextField dalam posisi. Untuk waktu yang lama saya tidak tahu apa itu. Lalu saya berkomentar textFieldDidBeginEditing Metode delegasi dan semuanya bekerja !! (???). Ternyata, saya percaya UIScrollView sebenarnya secara implisit membawa yang saat ini diedit UITextField ke dalam jendela yang dapat dilihat secara implisit. Implementasi saya atas UITextFieldDelegate metode dan panggilan selanjutnya ke scrollRecToVisible adalah berlebihan dan merupakan penyebab dari efek samping yang aneh.

Jadi di sini adalah langkah-langkah untuk menggulir Anda dengan benar UITextField di sebuah UIScrollView pada tempatnya saat keyboard muncul.

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.

- (void)viewDidLoad 
{
    [super viewDidLoad];

    // register for keyboard notifications
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(keyboardWillShow:) 
                                                 name:UIKeyboardWillShowNotification 
                                               object:self.view.window];
    // register for keyboard notifications
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(keyboardWillHide:) 
                                                 name:UIKeyboardWillHideNotification 
                                               object:self.view.window];
    keyboardIsShown = NO;
    //make contentSize bigger than your scrollSize (you will need to figure out for your own use case)
    CGSize scrollContentSize = CGSizeMake(320, 345);
    self.scrollView.contentSize = scrollContentSize;
}

- (void)keyboardWillHide:(NSNotification *)n
{
    NSDictionary* userInfo = [n userInfo];

    // get the size of the keyboard
    CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;


    // resize the scrollview
    CGRect viewFrame = self.scrollView.frame;
    // I'm also subtracting a constant kTabBarHeight because my UIScrollView was offset by the UITabBar so really only the portion of the keyboard that is leftover pass the UITabBar is obscuring my UIScrollView.
    viewFrame.size.height += (keyboardSize.height - kTabBarHeight);

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [self.scrollView setFrame:viewFrame];
    [UIView commitAnimations];

    keyboardIsShown = NO;
}

- (void)keyboardWillShow:(NSNotification *)n
{
    // This is an ivar I'm using to ensure that we do not do the frame size adjustment on the `UIScrollView` if the keyboard is already shown.  This can happen if the user, after fixing editing a `UITextField`, scrolls the resized `UIScrollView` to another `UITextField` and attempts to edit the next `UITextField`.  If we were to resize the `UIScrollView` again, it would be disastrous.  NOTE: The keyboard notification will fire even when the keyboard is already shown.
    if (keyboardIsShown) {
        return;
    }

    NSDictionary* userInfo = [n userInfo];

    // get the size of the keyboard
    CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;

    // resize the noteView
    CGRect viewFrame = self.scrollView.frame;
    // I'm also subtracting a constant kTabBarHeight because my UIScrollView was offset by the UITabBar so really only the portion of the keyboard that is leftover pass the UITabBar is obscuring my UIScrollView.
    viewFrame.size.height -= (keyboardSize.height - kTabBarHeight);

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [self.scrollView setFrame:viewFrame];
    [UIView commitAnimations];
    keyboardIsShown = YES;
}
  1. Daftarkan pemberitahuan keyboard di viewDidLoad
  2. Batalkan pendaftaran untuk nofitikasi keyboard di viewDidUnload
  3. Pastikan bahwa contentSize diatur dan lebih besar dari Anda UIScrollView di viewDidLoad
  4. Menyusut itu UIScrollView ketika keyboard hadir
  5. Memulihkan kembali itu UIScrollView saat keyboard hilang.
  6. Gunakan ivar untuk mendeteksi apakah keyboard sudah ditampilkan di layar sejak pemberitahuan keyboard dikirim setiap kali a UITextField tab bahkan jika keyboard sudah hadir untuk menghindari penyusutan itu UIScrollView padahal sudah menyusut

Satu hal yang perlu diperhatikan adalah bahwa UIKeyboardWillShowNotification akan menyala bahkan ketika keyboard sudah ada di layar saat Anda tab di yang lain UITextField. Saya merawat ini dengan menggunakan ivar untuk menghindari mengubah ukuran UIScrollView saat keyboard sudah ada di layar. Secara tidak sengaja mengubah ukuran UIScrollView ketika keyboard sudah ada akan ada bencana!

Semoga kode ini menghemat sebagian dari Anda banyak sakit kepala.


437



Ini sebenarnya terbaik hanya untuk menggunakan implementasi Apple, seperti yang disediakan di dokumen. Namun, kode yang mereka berikan salah. Ganti porsi yang ditemukan di keyboardWasShown: tepat di bawah komentar berikut:

NSDictionary* info = [aNotification userInfo];
CGRect keyPadFrame=[[UIApplication sharedApplication].keyWindow convertRect:[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue] fromView:self.view];
CGSize kbSize =keyPadFrame.size;
CGRect activeRect=[self.view convertRect:activeField.frame fromView:activeField.superview];
CGRect aRect = self.view.bounds;
aRect.size.height -= (kbSize.height);

CGPoint origin =  activeRect.origin;
origin.y -= backScrollView.contentOffset.y;
if (!CGRectContainsPoint(aRect, origin)) {
    CGPoint scrollPoint = CGPointMake(0.0,CGRectGetMaxY(activeRect)-(aRect.size.height));
    [backScrollView setContentOffset:scrollPoint animated:YES];
}

Masalah dengan kode Apple adalah ini: (1) Mereka selalu menghitung apakah titik tersebut berada dalam bingkai tampilan, tetapi itu a ScrollView, jadi mungkin sudah digulir dan Anda perlu memperhitungkan offset tersebut:

origin.y -= scrollView.contentOffset.y

(2) Mereka menggeser contentOffset dengan ketinggian keyboard, tetapi kami menginginkan yang sebaliknya (kami ingin menggesernya contentOffset oleh ketinggian yang terlihat di layar, bukan yang tidak):

activeField.frame.origin.y-(aRect.size.height)

260



Di textFieldDidBeginEditting dan masuk textFieldDidEndEditing sebut fungsi tersebut [self animateTextField:textField up:YES] seperti ini:

-(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 = -130; // tweak as needed
    const float movementDuration = 0.3f; // tweak as needed

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

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

Saya harap kode ini akan membantu Anda.

Di Swift 2

func animateTextField(textField: UITextField, up: Bool) 
{
     let movementDistance:CGFloat = -130
     let movementDuration: Double = 0.3

     var movement:CGFloat = 0
     if up 
     {
         movement = movementDistance
     }
     else 
     {
         movement = -movementDistance
     }
     UIView.beginAnimations("animateTextField", context: nil)
     UIView.setAnimationBeginsFromCurrentState(true)
     UIView.setAnimationDuration(movementDuration)
     self.view.frame = CGRectOffset(self.view.frame, 0, movement)
     UIView.commitAnimations()
}


func textFieldDidBeginEditing(textField: UITextField) 
{
    self.animateTextField(textField, up:true)
}

func textFieldDidEndEditing(textField: UITextField) 
{
    self.animateTextField(textField, up:false)
}

SWIFT 3

 func animateTextField(textField: UITextField, up: Bool)
    {
        let movementDistance:CGFloat = -130
        let movementDuration: Double = 0.3

        var movement:CGFloat = 0
        if up
        {
            movement = movementDistance
        }
        else
        {
            movement = -movementDistance
        }
        UIView.beginAnimations("animateTextField", context: nil)
        UIView.setAnimationBeginsFromCurrentState(true)
        UIView.setAnimationDuration(movementDuration)
        self.view.frame = self.view.frame.offsetBy(dx: 0, dy: movement)
        UIView.commitAnimations()
    }


    func textFieldDidBeginEditing(textField: UITextField)
    {
        self.animateTextField(textField: textField, up:true)
    }

    func textFieldDidEndEditing(textField: UITextField)
    {
        self.animateTextField(textField: textField, up:false)
    }

238



Hanya menggunakan TextFields:

1a) Menggunakan Interface Builder: Pilih Semua TextFields => Edit => Embed In => ScrollView

1b) Secara manual menanamkan TextFields di UIScrollView yang disebut scrollView

2) Set UITextFieldDelegate

3) Tetapkan masing-masing textField.delegate = self; (atau membuat koneksi di Interface Builder)

4) Salin / Tempel:

- (void)textFieldDidBeginEditing:(UITextField *)textField {
    CGPoint scrollPoint = CGPointMake(0, textField.frame.origin.y);
    [scrollView setContentOffset:scrollPoint animated:YES];
}

- (void)textFieldDidEndEditing:(UITextField *)textField {
    [scrollView setContentOffset:CGPointZero animated:YES];
}

133



Untuk Solusi Universal, Inilah pendekatan saya untuk mengimplementasikan IQKeyboardManager.

enter image description here

Langkah 1:- Saya menambahkan pemberitahuan global UITextField, UITextView, dan UIKeyboard di kelas tunggal. Saya menyebutnya IQKeyboardManager.

Langkah 2:- Jika ketemu UIKeyboardWillShowNotification, UITextFieldTextDidBeginEditingNotification atau UITextViewTextDidBeginEditingNotification pemberitahuan, saya coba dapatkan topMostViewController contoh dari UIWindow.rootViewController hirarki. Untuk mengungkap dengan benar UITextField/UITextView di atasnya, topMostViewController.viewBingkainya perlu disesuaikan.

Step3: - Saya menghitung jarak pergerakan yang diharapkan topMostViewController.view sehubungan dengan tanggapan pertama UITextField/UITextView.

Step4: - aku pindah topMostViewController.view.frame naik / turun sesuai dengan jarak pergerakan yang diharapkan.

Step5: - Jika ketemu UIKeyboardWillHideNotification, UITextFieldTextDidEndEditingNotification atau UITextViewTextDidEndEditingNotification pemberitahuan, saya mencoba lagi untuk mendapatkannya topMostViewController contoh dari UIWindow.rootViewController hirarki.

Step6: - Saya menghitung jarak yang terganggu topMostViewController.view yang perlu dikembalikan ke posisi semula.

Step7: - Saya dipulihkan topMostViewController.view.frame turun sesuai dengan jarak yang terganggu.

Step8: - Saya instantiated tunggal IQKeyboardManager instance kelas pada beban aplikasi, jadi setiap UITextField/UITextView dalam aplikasi akan menyesuaikan secara otomatis sesuai dengan jarak pergerakan yang diharapkan.

Itu saja IQKeyboardManager lakukan untuk Anda dengan TIDAK ADA GARIS KODE sangat!! hanya perlu menyeret dan melepas file sumber yang terkait ke proyek. IQKeyboardManager juga mendukung Orientasi Perangkat, Manajemen UIToolbar Otomatis, KeybkeyboardDistanceFromTextField dan lebih dari yang Anda pikirkan.


106



Saya telah mengumpulkan universal, drop-in UIScrollView, UITableView dan bahkan UICollectionView subkelas yang menangani memindahkan semua bidang teks di dalamnya dari jalannya keyboard.

Ketika keyboard akan muncul, subclass akan menemukan subview yang akan diedit, dan menyesuaikan frame dan konten offset untuk memastikan bahwa tampilan terlihat, dengan animasi untuk mencocokkan pop-up keyboard. Ketika keyboard menghilang, itu mengembalikan ukuran sebelumnya.

Ini harus bekerja dengan setup pada dasarnya, baik a UITableViewantarmuka berbasis, atau yang terdiri dari tampilan yang ditempatkan secara manual.

Ini dia: solusi untuk memindahkan bidang teks dari jalannya keyboard


99



Untuk Cepat Programmer:

Ini akan melakukan segalanya untuk Anda, hanya menempatkan ini di kelas controller pandangan Anda dan mengimplementasikan UITextFieldDelegate ke pengontrol tampilan Anda & tetapkan delegasi textField menjadi self 

textField.delegate = self // Setting delegate of your UITextField to self

Terapkan metode panggilan balik delegasi:

func textFieldDidBeginEditing(textField: UITextField) {
    animateViewMoving(true, moveValue: 100)
}

func textFieldDidEndEditing(textField: UITextField) {
    animateViewMoving(false, moveValue: 100)
}

// Lifting the view up
func animateViewMoving (up:Bool, moveValue :CGFloat){
    let movementDuration:NSTimeInterval = 0.3
    let movement:CGFloat = ( up ? -moveValue : moveValue)
    UIView.beginAnimations( "animateView", context: nil)
    UIView.setAnimationBeginsFromCurrentState(true)
    UIView.setAnimationDuration(movementDuration )
    self.view.frame = CGRectOffset(self.view.frame, 0,  movement)
    UIView.commitAnimations()
}

84



Sudah ada banyak jawaban, tetapi masih tidak ada solusi di atas yang memiliki semua hal yang perlu diposisikan untuk animasi "sempurna" yang bebas bug, yang kompatibel ke belakang, dan bebas flicker. (bug saat menjiwai bingkai / batas dan contentOffset bersama-sama, orientasi antarmuka yang berbeda, keyboard split iPad, ...)
Biarkan saya berbagi solusi saya:
(dengan asumsi Anda sudah mengaturnya UIKeyboardWill(Show|Hide)Notification)

// Called when UIKeyboardWillShowNotification is sent
- (void)keyboardWillShow:(NSNotification*)notification
{
    // if we have no view or are not visible in any window, we don't care
    if (!self.isViewLoaded || !self.view.window) {
        return;
    }

    NSDictionary *userInfo = [notification userInfo];

    CGRect keyboardFrameInWindow;
    [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardFrameInWindow];

    // the keyboard frame is specified in window-level coordinates. this calculates the frame as if it were a subview of our view, making it a sibling of the scroll view
    CGRect keyboardFrameInView = [self.view convertRect:keyboardFrameInWindow fromView:nil];

    CGRect scrollViewKeyboardIntersection = CGRectIntersection(_scrollView.frame, keyboardFrameInView);
    UIEdgeInsets newContentInsets = UIEdgeInsetsMake(0, 0, scrollViewKeyboardIntersection.size.height, 0);

    // this is an old animation method, but the only one that retains compaitiblity between parameters (duration, curve) and the values contained in the userInfo-Dictionary.
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
    [UIView setAnimationCurve:[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];

    _scrollView.contentInset = newContentInsets;
    _scrollView.scrollIndicatorInsets = newContentInsets;

    /*
     * Depending on visual layout, _focusedControl should either be the input field (UITextField,..) or another element
     * that should be visible, e.g. a purchase button below an amount text field
     * it makes sense to set _focusedControl in delegates like -textFieldShouldBeginEditing: if you have multiple input fields
     */
    if (_focusedControl) {
        CGRect controlFrameInScrollView = [_scrollView convertRect:_focusedControl.bounds fromView:_focusedControl]; // if the control is a deep in the hierarchy below the scroll view, this will calculate the frame as if it were a direct subview
        controlFrameInScrollView = CGRectInset(controlFrameInScrollView, 0, -10); // replace 10 with any nice visual offset between control and keyboard or control and top of the scroll view.

        CGFloat controlVisualOffsetToTopOfScrollview = controlFrameInScrollView.origin.y - _scrollView.contentOffset.y;
        CGFloat controlVisualBottom = controlVisualOffsetToTopOfScrollview + controlFrameInScrollView.size.height;

        // this is the visible part of the scroll view that is not hidden by the keyboard
        CGFloat scrollViewVisibleHeight = _scrollView.frame.size.height - scrollViewKeyboardIntersection.size.height;

        if (controlVisualBottom > scrollViewVisibleHeight) { // check if the keyboard will hide the control in question
            // scroll up until the control is in place
            CGPoint newContentOffset = _scrollView.contentOffset;
            newContentOffset.y += (controlVisualBottom - scrollViewVisibleHeight);

            // make sure we don't set an impossible offset caused by the "nice visual offset"
            // if a control is at the bottom of the scroll view, it will end up just above the keyboard to eliminate scrolling inconsistencies
            newContentOffset.y = MIN(newContentOffset.y, _scrollView.contentSize.height - scrollViewVisibleHeight);

            [_scrollView setContentOffset:newContentOffset animated:NO]; // animated:NO because we have created our own animation context around this code
        } else if (controlFrameInScrollView.origin.y < _scrollView.contentOffset.y) {
            // if the control is not fully visible, make it so (useful if the user taps on a partially visible input field
            CGPoint newContentOffset = _scrollView.contentOffset;
            newContentOffset.y = controlFrameInScrollView.origin.y;

            [_scrollView setContentOffset:newContentOffset animated:NO]; // animated:NO because we have created our own animation context around this code
        }
    }

    [UIView commitAnimations];
}


// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillHide:(NSNotification*)notification
{
    // if we have no view or are not visible in any window, we don't care
    if (!self.isViewLoaded || !self.view.window) {
        return;
    }

    NSDictionary *userInfo = notification.userInfo;

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:[[userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
    [UIView setAnimationCurve:[[userInfo valueForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];

    // undo all that keyboardWillShow-magic
    // the scroll view will adjust its contentOffset apropriately
    _scrollView.contentInset = UIEdgeInsetsZero;
    _scrollView.scrollIndicatorInsets = UIEdgeInsetsZero;

    [UIView commitAnimations];
}

61



Shiun berkata "Ternyata, saya percaya UIScrollView secara implisit membawa UITextField yang diedit saat ini ke dalam jendela yang dapat dilihat secara implisit" Ini tampaknya benar untuk iOS 3.1.3, tetapi tidak 3.2, 4.0, atau 4.1. Saya harus menambahkan scrollRectToVisible eksplisit untuk membuat UITextField terlihat di iOS> = 3.2.


60



Ini dokumen detail solusi untuk masalah ini. Lihatlah kode sumber di bawah 'Pindah Konten Yang Terletak Di Bawah Keyboard'. Ini cukup mudah.

EDIT: Melihat ada kesalahan kecil dalam contoh. Anda mungkin ingin mendengarkannya UIKeyboardWillHideNotification dari pada UIKeyboardDidHideNotification. Jika tidak, tampilan gulir belakang keyboard akan diklip selama durasi animasi penutupan keyboard.


44