InputAccessoryView merapat di bawah

I'm mencoba untuk mencapai posisi yang sama perilaku sebagai dasar input teks bar di Apple's aplikasi Pesan.

Saya telah mencoba banyak pendekatan, mencari tinggi dan rendah dan ada banyak pertanyaan yang serupa, tapi tidak satupun yang memuaskan.

Untuk menentukan:

  1. Ada UIToolbar di bagian bawah tampilan
  2. Toolbar ini untuk mengikuti keyboard sebagai keyboard muncul dan menghilang
  3. Toolbar harus tetap di atas keyboard ketika keyboard terlihat
  4. Ketika keyboard tersembunyi, toolbar tetap ("merapat") di bagian bawah tampilan

Solusi yang diusulkan:

Manual menghidupkan toolbar dalam menanggapi keyboard penampilan pemberitahuan

Solusi ini tidak memenuhi kasus khusus dari kedua persyaratan (toolbar adalah untuk mengikuti keyboard sebagai keyboard muncul dan menghilang):

Di iOS 7, UIScrollViewKeyboardDismissMode diperkenalkan. Hal ini memungkinkan interaktif gerakan untuk menolak keyboard. Sebagai pengguna panci lalu tepi atas keyboard, keyboard frame secara bertahap berikut. Solusi ini tidak apa-apa untuk mengakomodasi perilaku ini dan hanya meninggalkan toolbar terdampar di it's animasi posisi.

Selain itu, solusi ini juga gagal untuk memenuhi suatu kasus khusus dari ketiga persyaratan (toolbar harus tetap di atas keyboard ketika keyboard terlihat):

  • Rotasi. Solusi ini panggilan untuk tambahan, mengganggu asing kode (seperti yang akan kita lihat di bagian berikutnya diusulkan solusi) untuk memutar toolbar dalam menanggapi rotasi perangkat.

Lain masalah dengan solusi ini:

  • Ketinggian Keyboard. Dengan solusi ini, toolbar ini tidak diasumsikan untuk menjadi bagian dari ketinggian keyboard, sehingga tambahan kode yang harus ditulis untuk dukungan yang tepat insetting konten.

Selanjutnya solusi yang diusulkan:

Gunakan UIResponder's inputAccessoryView

Solusi ini tampaknya menjadi cara Apple dimaksudkan untuk mendukung perilaku semacam ini, karena memecahkan semua kekurangan dari manual menghidupkan toolbar. Tapi solusi ini benar-benar merindukan keempat persyaratan (ketika keyboard tersembunyi, toolbar tetap ("merapat") di bagian bawah tampilan).


Tampaknya solusinya adalah dengan menggunakan UIResponder's inputAccessoryView, tapi entah bagaimana membuat inputAccessoryView tidak bergerak di bawah tampilan. I'm mencari kode yang bersih untuk mencapai hal ini. Ada yang rumit, hampir semua yang mulia, upaya lain, tapi seperti yang disebutkan, mereka tidak memenuhi persyaratan.

Dalam kasus tertentu, saya ingin menggunakan UINavigationController's toolbar yang memerlukan tambahan masalah seperti ini tidak dimaksudkan perilaku untuk UINavigationController. Tidak peduli, aku'm. bersedia untuk memperkenalkan beberapa hacky perbaikan untuk mencapai itu.

Larutan

Aku hanya menunjukkan "" solusi oleh Jason Mandor (@threeve). Pada view controller (ya, view controller) tambahkan inputAccessoryView: dan kembali ke tampilan yang anda inginkan untuk dock di bagian bawah dan bergerak dengan keyboard. Ini hanya bekerja. Lihat doesn't benar-benar perlu untuk melihat hirarki ini akan dimasukkan oleh view controller secara otomatis.

edit: juga menerapkan canBecomeFirstResponder dan kembali YA (seperti dicatat oleh Max Seelemann). reloadInputViews dapat berguna juga.

Komentar (14)

Jonathan Badeen's tersebut solusi bekerja untuk saya. Berikut ini's kode dari Arik yang menunjukkan bagaimana untuk menerapkannya (harus pergi pada anda sesuai view controller):

    - (BOOL)canBecomeFirstResponder{

        return YES;

    }

    - (UIView *)inputAccessoryView{

        return self.inputAccessoryToolbar;  
     // where inputAccessoryToolbar is your keyboard accessory view

    }
Komentar (1)

Bagi mereka yang mencari untuk Swift versi:

Hubungkan toolbar (dalam kasus saya 'myToolBar') pada view controller. Kemudian menimpa canBecomeFirstResponder metode dan menimpa getter inputAccessoryView variabel. Juga don't lupa untuk menambahkan diri.myToolBar.removeFromSuperview() atau yang lain xcode akan mengeluh.

class ViewController: UIViewController {

    @IBOutlet var myToolBar: UIToolbar!

    override func canBecomeFirstResponder() -> Bool {
        return true
    }

    override var inputAccessoryView:UIView{
        get{
            return self.myToolBar
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        self.myToolBar.removeFromSuperview()
    }
}
Komentar (4)

Ada's yang sangat baik, mudah-untuk-melaksanakan, open-source solusi untuk hal ini dari orang-orang baik di Slack: SlackTextViewController.

Berikut ini's cara menerapkan tampilan dengan toolbar merapat dalam empat langkah:

  1. Menginstal pod ke dalam proyek anda. (http://cocoapods.org/?q=SlackTextViewController)
  2. Jika anda're menulis sebuah aplikasi di Swift, membuat header untuk menjembatani antara anda kode Swift dan mereka Obj-C kelas. Di sini's nice langkah-langkah cepat itu. (Bridging header won't perlu sekali kelas-kelas yang diterjemahkan ke Swift, siapa pun yang ingin berkolaborasi itu?)
  3. Membuat MessageViewController yang mewarisi dari SLKTextViewController, tidak perlu menulis kode yang lebih dari ini:

impor Yayasan impor UIKit

kelas MessageViewController: SLKTextViewController {

diperlukan init(coder aDecoder: NSCoder!) { super.init(coder: aDecoder) } }

  1. Dalam Storyboard, membuat View Controller yang mewarisi dari MessageViewController.
  2. Menguji aplikasi pada perangkat atau emulator, anda'll melihat indah merapat textbar itu juga (sebagai bonus) memperluas sebagai pengguna menulis baris tambahan teks.

Alat peraga untuk tim di Slack untuk penggalian tersebut berguna pod.

Komentar (1)

Jadi saya tahu ini adalah sebuah posting lama dan saya tidak yakin jika anda memutuskan ini atau tidak, tapi aku menemukan cara untuk mendapatkan kerja ini. Saya percaya ada bug di inputAccessoryView, tapi saya buat hacky solusi untuk berperilaku dengan cara aplikasi pesan tidak. Saya pikir saya memberikan semua kode yang diperlukan untuk melaksanakan pekerjaan di sekitar. Saya akan mencoba dan mendapatkan yang lebih sesuai dengan posting blog yang dibuat kadang-kadang di masa depan, dengan lebih mendalam deskripsi dengan temuan saya. Pertanyaan, biarkan aku tahu.

@property(nonatomic,assign)BOOL isFirstKeyboard; //workaround for keyboard bug

@property(nonatomic,assign)BOOL isViewAppear;

@property(nonatomic,strong)ChatBarView *chatView; //custom chat bar view

@property(nonatomic,strong)UIView *footerPadView; //just to add some nice padding
////////////////////////////////////////////////////////////////////////////////////////////////////
//in the view did load
- (void)viewDidLoad
{
    //more app specific code...
    self.tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;
    self.chatView.textView.inputAccessoryView = self.chatView;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
-(void)done
{
    self.isFirstKeyboard = YES;
    [self.chatView.textView becomeFirstResponder];
}
////////////////////////////////////////////////////////////////////////////////////////////////////
- (void) moveTextViewForKeyboard:(NSNotification*)aNotification up:(BOOL)up
{
    if(!self.isViewAppear)
        return;
    //NSLog(@"keyboard is: %@", up ? @"UP" : @"Down");
    if(!up && !self.isFirstKeyboard)
        [self performSelector:@selector(done) withObject:nil afterDelay:0.01];
    else if(!up & self.isFirstKeyboard)
    {
        self.isFirstKeyboard = NO;
        [self.view addSubview:self.chatView];
        CGRect frame = self.chatView.frame;
        frame.origin.y = self.view.frame.size.height - self.chatView.frame.size.height;
        self.chatView.frame = frame;
    }
    else
    {
        NSDictionary* userInfo = [aNotification userInfo];
        NSTimeInterval animationDuration;
        UIViewAnimationCurve animationCurve;
        CGRect keyboardEndFrame;

        [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
        [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
        [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];

        // Animate up or down
        [UIView beginAnimations:nil context:nil];
        if(up)
            [UIView setAnimationDuration:0.2];
        else
            [UIView setAnimationDuration:0.3];
        [UIView setAnimationCurve:animationCurve];

        CGRect frame = self.footerPadView.frame;
        CGRect keyboardFrame = [self.view convertRect:keyboardEndFrame toView:nil];
        if (up)
            frame.size.height = keyboardFrame.size.height - self.chatView.frame.size.height;
        else
            frame.size.height = 0;
        self.footerPadView.frame = frame;
        self.tableView.tableFooterView = self.footerPadView;
        [UIView commitAnimations];
    }
}
////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)keyboardWillShow:(NSNotification *)aNotification {
    [self moveTextViewForKeyboard:aNotification up:YES];
}
////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)keyboardWillHide:(NSNotification *)aNotification
{
    [self moveTextViewForKeyboard:aNotification up:NO];
}
////////////////////////////////////////////////////////////////////////////////////////////////////
Komentar (0)