Sejajarkan toolbar secara terprogram di atas keyboard iPhone

94

Dalam beberapa kasus, saya ingin menambahkan toolbar ke bagian atas keyboard iPhone (seperti di iPhone Safari saat Anda menavigasi elemen formulir, misalnya).

Saat ini saya menetapkan persegi panjang bilah alat dengan konstanta tetapi karena elemen antarmuka lainnya sedang berubah - bilah alat dan bilah navigasi di bagian atas layar - setiap kali kami membuat perubahan antarmuka kecil, bilah alat tidak sejajar.

Adakah cara untuk menentukan secara terprogram posisi keyboard dalam kaitannya dengan tampilan saat ini?

Rob Drimmie
sumber

Jawaban:

142

Mulai iOS 3.2, ada cara baru untuk mencapai efek ini:

UITextFieldsdan UITextViewsmemiliki inputAccessoryViewproperti, yang dapat Anda setel ke tampilan mana pun, yang secara otomatis ditampilkan di atas dan dianimasikan dengan keyboard.

Perhatikan bahwa tampilan yang Anda gunakan tidak boleh berada dalam hierarki tampilan di tempat lain, Anda juga tidak boleh menambahkannya ke beberapa superview, ini dilakukan untuk Anda.

tonklon.dll
sumber
biarkan aku mencoba . Padahal itu terlihat cara terbaik.
harshalb
Wow. Temukan apa! Terima kasih (Saya melakukannya dengan cara yang sulit dan berantakan)
levous
1
Saya memiliki UIToolbar dengan UITextField di dalam salah satu item tombol barnya, tetapi meskipun saya menyetel inputAccessoryView textFields ke toolbar tersebut pada saat pertama tekan, toolbar akan naik tetapi tidak ada keyboard yang muncul. Pada pers kedua keyboard muncul dengan toolbar punya ide tentang itu?
Ugur Kumru
Tetapi bagaimana cara menambahkan toolbar di UIWebView? :(
Dmitry
Saya telah melakukannya dengan mengganti tombol pada toolbar standar UIWebView (kode yang sama seperti untuk menghapusnya).
Dmitry
72

Jadi pada dasarnya:

Dalam metode init:

NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self selector:@selector(keyboardWillShow:) name: UIKeyboardWillShowNotification object:nil];
[nc addObserver:self selector:@selector(keyboardWillHide:) name: UIKeyboardWillHideNotification object:nil];

Dan kemudian memiliki metode yang disebutkan di atas untuk menyesuaikan posisi bilah:

-(void) keyboardWillShow:(NSNotification *) note
{
    CGRect r  = bar.frame, t;
    [[note.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue: &t];
    r.origin.y -=  t.size.height;
    bar.frame = r;
}

Bisa membuatnya cantik dengan menganimasikan perubahan posisi dengan membungkusnya

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3];
//...
    [UIView commitAnimations];

sumber
Saya melihat-lihat barang lama saya pagi ini dan memperhatikan bahwa ini adalah jawaban yang jauh lebih baik dan paling komprehensif. Terima kasih!
Rob Drimmie
Jawaban ini masih relevan sampai setahun kemudian. Ini membantu saya mengatasi punuk ketika mengembangkan sesuatu yang berhubungan dengan ini.
james_womack
2
Hanya peringatan bagi orang-orang yang tersandung pada pertanyaan ini sekarang: UIKeyboardBoundsUserInfoKey sekarang tidak digunakan lagi di iPhone OS 3.2. Ada yang lain, yang serupa seperti UIKeyboardFrameBeginUserInfoKeyyang memberikan informasi yang sama.
Stephen Darlington
9
Bahkan ada cara baru yang lebih baik untuk melakukannya di iOS3.2 yaitu properti inputAccessoryView di UITextField dan UITextView.
tonklon
6
Jawaban ini sangat membantu tetapi agak ketinggalan jaman. Anda harus menggunakan UIKeyboardFrameEndUserInfoKeyuntuk mendapatkan bingkai terakhir (dalam koordinat layar) dari keyboard. Anda juga dapat menggunakan UIKeyboardAnimationDurationUserInfoKeydan UIKeyboardAnimationCurveUserInfoKeyuntuk mendapatkan parameter lainnya yang Anda perlukan untuk benar-benar cocok dengan perilaku keyboard.
Dave Peck
60

Ini didasarkan pada jawaban yang ada dari tonklon - Saya hanya menambahkan cuplikan kode yang menunjukkan toolbar hitam semi transparan di atas keyboard, bersama dengan tombol "selesai" di sebelah kanan:

UIToolbar *toolbar = [[[UIToolbar alloc] init] autorelease];
[toolbar setBarStyle:UIBarStyleBlackTranslucent];
[toolbar sizeToFit];

UIBarButtonItem *flexButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *doneButton =[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(resignKeyboard)];

NSArray *itemsArray = [NSArray arrayWithObjects:flexButton, doneButton, nil];

[flexButton release];
[doneButton release];
[toolbar setItems:itemsArray];

[aTextField setInputAccessoryView:toolbar];

dan -resignKeyboardtampilannya seperti:

-(void)resignKeyboard {
  [aTextField resignFirstResponder];
}

Harapan yang membantu seseorang.

phi
sumber
2
Hanya menambahkan sedikit komentar untuk mendapatkan posisi sebelumnya. UISegmentedControl * segmentControl = [[UISegmentedControl alokasi] initWithItems: [NSArray arrayWithObjects: @ "Sebelumnya", @ "Berikutnya", nihil]]; [segmentControl setSegmentedControlStyle: UISegmentedControlStyleBar]; [segmentControl addTarget: self action: @selector (nextPrevious :) forControlEvents: UIControlEventValueChanged];
Trausti Thor
1
Tambahan untuk komentar @ TraustiThor: Anda harus membungkus kontrol tersegmentasi dalam UIBarButtonItem untuk menambahkannya ke toolbar.
Tim Büthe
Luar biasa - ini semua kode yang saya butuhkan. Terima kasih telah memposting :)
Regangkan
Tapi bagaimana dengan UIWebView? Bagaimana cara menambahkan toolbar ke dalamnya?
Dmitry
24

Jika Anda mendaftar untuk notifikasi keyboard, misalnya UIKeyboardWillShowNotification UIKeyboardWillHideNotification, dll., Notifikasi yang Anda terima akan berisi batas keyboard di userInfodict ( UIKeyboardBoundsUserInfoKey).

Lihat UIWindowreferensi kelas.

amrox
sumber
16

Di versi 3.0 dan di atasnya Anda bisa mendapatkan durasi animasi dan kurva dari userInfokamus notifikasi.

misalnya, untuk menganimasikan ukuran tampilan guna memberi ruang bagi keyboard, daftar ke UIKeyboardWillShowNotificationdan lakukan sesuatu seperti berikut:

- (void)keyboardWillShow:(NSNotification *)notification
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
    [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];

    CGRect frame = self.view.frame;
    frame.size.height -= [[[notification userInfo] objectForKey:UIKeyboardBoundsUserInfoKey] CGRectValue].size.height;
    self.view.frame = frame;

    [UIView commitAnimations];
}

Lakukan animasi serupa untuk UIKeyboardWillHideNotification.

David Beck
sumber
Sepertinya cara yang lebih baik untuk melakukannya di SDK 3.0 terima kasih telah memposting!
Hua-Ying
Terima kasih untuk kodenya. Ini sangat membantu. Tetapi ketika saya menyetel UITextView saya menjadi responden pertama di viewDidLoad, UIToolBar tidak bergerak dengan pengubahan ukuran self.view tersebut. Apakah kamu tahu kenapa?
RyanJM
1
@RyanJM: beFirstResponder dan resignFirstResponder memiliki perilaku aneh saat tampilan di luar layar. Anda harus memanggil beFirstResponder dari metode viewWillAppear Anda.
David Beck
0

Buat metode ini dan panggil di ViewWillLoad:

        - (void) keyboardToolbarSetup
{
    if(self.keyboardToolbar==nil)
        {
        self.keyboardToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)];

        UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:@"Cancel" style:UIBarButtonItemStylePlain target:self action:@selector(anyAction)];

        UIBarButtonItem *extraSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];

        UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(anyOtherAction)];


        NSArray *toolbarButtons = [[NSArray alloc]initWithObjects:cancelButton,extraSpace,doneButton, nil];

        [self.keyboardToolbar setItems:toolbarButtons];

        self.myTextView.inputAccessoryView=self.keyboardToolbar;
        }
}
Juan Sebastián López
sumber
-3

Tidak ada cara (AFAIK) untuk mendapatkan dimensi tampilan keyboard. Namun itu konstan, setidaknya di setiap versi iPhone sejauh ini.

Jika Anda menghitung posisi bilah alat sebagai penyeimbang dari BAWAH tampilan Anda, dan memperhitungkan ukuran tampilan Anda, maka Anda tidak perlu khawatir apakah bilah navigasi ada atau tidak.

Misalnya

#define KEYBOARD_HEIGHT 240 // example - can't remember the exact size
#define TOOLBAR_HEIGHT 30

toolBarRect.origin.y = viewRect.size.height - KEYBOARD_HEIGHT - TOOLBAR_HEIGHT;

// move toolbar either directly or with an animation

Alih-alih menentukan, Anda dapat dengan mudah membuat keyboardHeightfungsi yang mengembalikan ukuran berdasarkan apakah keyboard sedang ditampilkan, dan memindahkan pemosisian bilah alat ini ke dalam fungsi terpisah yang mengatur ulang tata letak Anda.

Juga dapat bergantung di mana Anda melakukan pemosisian ini karena mungkin saja ukuran tampilan Anda dapat berubah antara dimuat dan ditampilkan berdasarkan pengaturan navbar Anda. Saya yakin tempat terbaik untuk melakukannya adalah di viewWillAppear.

Andrew Grant
sumber
Ini bekerja dengan baik, terima kasih! Sejauh ini saya telah melakukan penghitungan ini di selektor yang dipicu oleh UIKeyboardDidShowNotification. Saya hanya menguji di beberapa tempat, tapi sepertinya tempat yang bagus.
Rob Drimmie
Mulai 5.0, ukuran keyboard tidak lagi statis.
Alastair Stuart