Bagaimana cara menghilangkan keyboard untuk UITextView dengan tombol kembali?

382

Di perpustakaan IB, pengantar memberitahu kita bahwa ketika returntombol ditekan, keyboard untuk UITextViewakan hilang. Tetapi sebenarnya returnkuncinya hanya dapat bertindak sebagai '\ n'.

Saya dapat menambahkan tombol dan gunakan [txtView resignFirstResponder]untuk menyembunyikan keyboard.

Tetapi apakah ada cara untuk menambahkan aksi untuk returntombol di keyboard sehingga saya tidak perlu menambahkan UIButton?

Zhong Dingin
sumber
Ikuti petunjuk di posting blog ini: iphonedevelopertips.com/cocoa/…
ManojN

Jawaban:

354

UITextViewtidak memiliki metode apa pun yang akan dipanggil ketika pengguna menekan tombol kembali. Jika Anda ingin pengguna hanya dapat menambahkan satu baris teks, gunakan a UITextField. Menekan tombol kembali dan menyembunyikan keyboard untuk UITextViewtidak mengikuti panduan antarmuka.

Bahkan jika Anda ingin melakukan ini, terapkan textView:shouldChangeTextInRange:replacementText:metode UITextViewDelegatedan di periksa apakah teks pengganti \n, sembunyikan keyboard.

Mungkin ada cara lain tapi saya tidak tahu.

hilangInTransit
sumber
1
Terima kasih dan metodenya bekerja dengan baik. Alasan untuk menggunakan UITextView adalah karena ia dapat menyimpan teks dalam banyak baris. Dan sekarang saya menggunakannya sebagai kotak pesan.
Chilly Zhong
28
Cukup mudah untuk mengubah kunci kembali ke "selesai" menggunakan salah satu [textField setReturnKeyType: UIReturnKeyDone];atau menggunakan pembangun antarmuka
Casebash
9
Oke, saya sekarang mengerti bahwa cara Apple menyelesaikan dengan bidang teks multiline adalah menambahkan dilakukan ke menu bar
Casebash
8
Ini bukan cara yang baik untuk menyelesaikan ini karena Anda membatasi pengguna untuk menggunakan enter untuk keluar dari keyboard. Mungkin cara terbaik adalah menambahkan tombol yang menjalankan metode resignFirstResponder.
Ele
5
@Casebash. Tampaknya pengaturan kunci kembali ke "selesai" tidak menyelesaikan masalah di Xcode 6.4, Swift 2.0. Saya mengatur kunci menggunakan IB.
MB_iOSDeveloper
505

Kupikir aku akan memposting snippet di sini:

Pastikan Anda menyatakan dukungan untuk UITextViewDelegateprotokol.

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {

    if([text isEqualToString:@"\n"]) {
        [textView resignFirstResponder];
        return NO;
    }

    return YES;
}

Pembaruan Swift 4.0:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    if text == "\n" {
        textView.resignFirstResponder()
        return false
    }
    return true
}
samvermette
sumber
75
Masalahnya adalah bahwa ini bukan benar-benar cara mendeteksi bahwa pengguna telah mengetuk kembali kunci . Pengguna dapat menempelkan karakter kembali ke bidang teks dan Anda akan mendapatkan pesan delegasi yang sama. Pada dasarnya Anda menyalahgunakan tampilan teks. Cara untuk mengabaikan keyboard adalah (1) tidak melakukannya sama sekali (seperti ketika menulis pesan di aplikasi Mail) atau (2) memiliki tombol Selesai di tempat lain di antarmuka (seperti pada aplikasi Notes). Anda bisa memasang tombol seperti tampilan aksesori ke keyboard, misalnya.
matt
@ Sam V cuplikan itu pria keren. ini bekerja untuk saya. terima kasih banyak. Apakah ada cuplikan untuk penolakan keyboard numerik. salam shishir
Shishir.bobby
Indah. Hanya pengingat bahwa dalam beberapa situasi, untuk menyingkirkan keyboard, coba di sepanjang baris ... [self.view endEditing: YES];
Fattie
@ Vojto, berfungsi dengan baik di iPad. Anda mungkin belum mengatur delegasi.
Vincent
4
Masalahnya adalah bahwa keyboard mungkin menyembunyikan bagian dari antarmuka yang digunakan untuk mengabaikan. Benar-benar tidak masuk akal bahwa iOS tidak memiliki tombol pada setiap keyboard yang didedikasikan untuk mengabaikan keyboard sehingga pengguna dapat melakukannya jika dia mau.
Sani Elfishawy
80

Saya tahu ini sudah dijawab tetapi saya tidak begitu suka menggunakan string literal untuk baris baru jadi inilah yang saya lakukan.

- (BOOL)textView:(UITextView *)txtView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    if( [text rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet]].location == NSNotFound ) {
        return YES;
    }

    [txtView resignFirstResponder];
    return NO;
}

Pembaruan Swift 4.0:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if (text as NSString).rangeOfCharacter(from: CharacterSet.newlines).location == NSNotFound {
    return true
}
txtView.resignFirstResponder()
return false
}
ribeto
sumber
6
Saya mungkin memodifikasinya seperti ini: NSRange resultRange = [text rangeOfCharacterFromSet: [NSCharacterSet newlineCharacterSet] pilihan: NSBackwardsSearch]; Karena ini adalah retasan, sepertinya memeriksa akhir string untuk pengembalian mungkin merupakan rute yang lebih aman.
maks.
@maxpower Komentar yang sangat bagus. Juga, lebih baik untuk memeriksa terhadap teks yang diganti, misalnya NSString *replacedText = [textView.text stringByReplacingCharactersInRange:range withString:text].
Rudolf Adamkovič
Bayangkan seorang pengguna menempelkan beberapa teks yang disalin dari tempat lain yang berisi baris baru. Mereka mungkin akan bingung ketika alih-alih menambahkan teks aplikasi hanya menolak keyboard.
Nikolai Ruhe
44

Saya tahu ini telah dijawab berkali-kali, tetapi inilah dua sen saya untuk masalah ini.

Saya menemukan jawaban oleh samvermette dan ribeto sangat berguna, dan juga komentar oleh maxpower dalam jawaban ribeto . Tetapi ada masalah dengan pendekatan itu. Masalah yang matt sebutkan dalam jawaban samvermette dan jika pengguna ingin menempelkan sesuatu dengan garis putus di dalamnya, keyboard akan bersembunyi tanpa menempelkan apa pun.

Jadi pendekatan saya adalah campuran dari tiga solusi yang disebutkan di atas dan hanya memeriksa apakah string yang dimasukkan adalah baris baru ketika panjang string adalah 1 sehingga kami memastikan pengguna mengetik bukannya menempel.

Inilah yang telah saya lakukan:

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    NSRange resultRange = [text rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet] options:NSBackwardsSearch];
    if ([text length] == 1 && resultRange.location != NSNotFound) {
        [textView resignFirstResponder];
        return NO;
    }

    return YES;
}
Yosebama
sumber
Ini adalah solusi terbaik untuk masalah ini. jawaban samvermette tidak memperhitungkan situasi di mana pengguna ingin menempelkan teks.
marcopaivaf
36

Cara yang lebih elegan adalah dengan mengabaikan keyboard saat pengguna mengetuk suatu tempat di luar bingkai keyboard.

Pertama, atur tampilan ViewController Anda ke kelas "UIControl" di inspektur identitas di UIBuilder. Kontrol-seret tampilan ke dalam file header ViewController dan tautkan sebagai tindakan dengan acara tersebut sebagai Touch Up Inside, seperti:

ViewController.h

-(IBAction)dismissKeyboardOnTap:(id)sender;

Dalam file ViewController utama, ViewController.m:

-(IBAction)dismissKeyboardOnTap:(id)sender
    {
         [[self view] endEditing:YES];
    }

Anda dapat meminta ketuk dua kali atau sentuhan panjang menggunakan teknik serupa. Anda mungkin perlu mengatur ViewController Anda menjadi UITextViewDelegate dan menghubungkan TextView ke ViewController. Metode ini berfungsi untuk UITextView dan UITextField.

Sumber: Peternakan Nerd Besar

EDIT: Saya juga ingin menambahkan bahwa jika Anda menggunakan UIScrollView, teknik di atas mungkin tidak bekerja dengan mudah melalui Interface Builder. Dalam hal itu, Anda bisa menggunakan UIGestureRecognizer dan memanggil metode [[tampilan sendiri] endEditing: YES] sebagai gantinya. Contohnya adalah:

-(void)ViewDidLoad{
    ....
    UITapGestureRecognizer *tapRec = [[UITapGestureRecognizer alloc] 
        initWithTarget:self action:@selector(tap:)];
    [self.view addGestureRecognizer: tapRec];
    ....
}

-(void)tap:(UITapGestureRecognizer *)tapRec{
    [[self view] endEditing: YES];
}

Ketika pengguna mengetuk di luar keyboard dan tidak mengetuk ruang entri, keyboard akan diberhentikan.

TMilligan
sumber
1
Saya suka ide dengan GestureRecognizertetapi masalah besar adalah bahwa semua tombol atau kontrol pada tampilan tidak lagi dapat diklik.
ahli
35

Tambahkan metode ini di pengontrol tampilan Anda.

Cepat :

func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
    if text == "\n" {
        textView.resignFirstResponder()
        return false
    }
    return true
}

Metode ini juga dapat membantu Anda:

/**
Dismiss keyboard when tapped outside the keyboard or textView

:param: touches the touches
:param: event   the related event
*/
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    if let touch = touches.anyObject() as? UITouch {
        if touch.phase == UITouchPhase.Began {
            textField?.resignFirstResponder()
        }
    }
}
Alexander Volkov
sumber
2
Jangan lupa untuk mengkonfirmasi protokol UITextViewDelegate :)
swiftBoy
Saya tidak berpikir itu ide yang baik untuk mengesampingkan sentuhan Mulai dan tidak menelepon super.touchesBegan(touches:withEvent:).
TGO
Untuk mengekspresikan sifat simetris dari kode ini, Anda harus menulis else { return true }.
maknanya penting
@ artinya-tidak penting sama sekali
Alexander Volkov
@AlexanderVolkov Anda tidak setuju ini situasi yang simetris, Anda tidak tahu maksud saya, Anda tidak percaya pada nilai kode yang benar secara semantik, atau, ...?
maknanya penting
26
-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    if([text isEqualToString:@"\n"])
        [textView resignFirstResponder];
    return YES;
}

yourtextView.delegate=self;

Juga tambahkan UITextViewDelegate

Jangan lupa untuk mengkonfirmasi protokol

JIKA Anda tidak menambahkan if([text isEqualToString:@"\n"])Anda tidak dapat mengedit

Vineesh TP
sumber
2
-1 Ini hanyalah versi yang lebih buruk dari jawaban samvermette. Anda melewatkan kembali NOjika teks sama dengan @"\n".
devios1
17

Ada solusi lain saat menggunakan dengan uitextview, Anda dapat menambahkan toolbar sebagai InputAccessoryView di "textViewShouldBeginEditing", dan dari tombol selesai toolbar ini Anda dapat mengabaikan keyboard, kode untuk ini adalah sebagai berikut:

Di viewDidLoad

toolBar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 44)]; //toolbar is uitoolbar object
toolBar.barStyle = UIBarStyleBlackOpaque;
UIBarButtonItem *btnDone = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(btnClickedDone:)];
[toolBar setItems:[NSArray arrayWithObject:btnDone]];

Dalam metode textviewdelegate

- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
     [textView setInputAccessoryView:toolBar];
     return YES;
}

Dalam aksi Button Done yang ada di toolbar adalah sebagai berikut:

-(IBAction)btnClickedDone:(id)sender
{
    [self.view endEditing:YES];
}
g212gs
sumber
17

Saya menemukan jawaban oleh josebama sebagai jawaban paling lengkap dan bersih yang tersedia di utas ini.

Di bawah ini adalah sintaks Swift 4 untuknya:

func textView(_ textView: UITextView, shouldChangeTextIn _: NSRange, replacementText text: String) -> Bool {
    let resultRange = text.rangeOfCharacter(from: CharacterSet.newlines, options: .backwards)
    if text.count == 1 && resultRange != nil {
        textView.resignFirstResponder()
        // Do any additional stuff here
        return false
    }
    return true
}
Puneet Kohli
sumber
The resultRangebertujuan untuk menguji apakah teks hanya berisi baris yang menghindari hard-code "\ n".
Qinghua
6

cepat

func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
    if text == "\n" {
        textView.resignFirstResponder()
    }
    return true
}

dan konfigurasikan

Eduardo Oliveros Acosta
sumber
Dari mana tangkapan layar itu?
Sam
6

Menggunakan pengontrol navigasi untuk meng-host bar untuk mengabaikan keyboard:

dalam file .h:

UIBarButtonItem* dismissKeyboardButton;

dalam file .m:

- (void)viewDidLoad {
    dismissKeyboardButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(dismissKeyboard)];
}

-(void)textViewDidBeginEditing:(UITextView *)textView {
    self.navigationItem.rightBarButtonItem = dismissKeyboardButton;
}

-(void)textFieldDidBeginEditing:(UITextField *)textField {
    self.navigationItem.rightBarButtonItem = dismissKeyboardButton;
}

-(void)dismissKeyboard {
    [self.textField resignFirstResponder];
    [self.textView resignFirstResponder];
    //or replace this with your regular right button
    self.navigationItem.rightBarButtonItem = nil;
}
Alex Stone
sumber
5

Sama seperti komentar matt untuk samvermette, saya juga tidak menyukai gagasan mendeteksi "\ n". Kunci "kembali" ada karena suatu alasan di UITextView, yaitu untuk pergi ke baris berikutnya tentu saja.

Solusi terbaik menurut saya adalah meniru aplikasi pesan iPhone - yaitu menambahkan bilah alat (dan tombol) pada keyboard.

Saya mendapat kode dari posting blog berikut:

http://www.iosdevnotes.com/2011/02/iphone-keyboard-toolbar/

Langkah:

-Tambahkan bilah alat ke file XIB Anda - atur tingginya menjadi 460

-Tambahkan item tombol bilah alat (jika belum ditambahkan). Jika Anda perlu meluruskannya, tambahkan item tombol bilah fleksibel ke XIB, dan pindahkan item tombol bilah alat

Tindakan -Buat yang menautkan item tombol Anda untuk mengundurkan diriFirstResponder sebagai berikut:

- (IBAction)hideKeyboard:(id)sender {
    [yourUITextView resignFirstResponder];
}

-Kemudian:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    [[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];

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

- (void)keyboardWillShow:(NSNotification *)notification {
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3];

    CGRect frame = self.keyboardToolbar.frame;
    frame.origin.y = self.view.frame.size.height - 260.0;
    self.keyboardToolbar.frame = frame;

    [UIView commitAnimations];
}

- (void)keyboardWillHide:(NSNotification *)notification {
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3];

    CGRect frame = self.keyboardToolbar.frame;
    frame.origin.y = self.view.frame.size.height;
    self.keyboardToolbar.frame = frame;

    [UIView commitAnimations];
}
teman
sumber
Keluar topik. Meskipun solusi Anda elegan, itu tidak menanggapi pertanyaan awal: "Bagaimana cara mengabaikan keyboard untuk UITextView dengan tombol kembali?". Ada beberapa situasi ketika UITextView digunakan untuk mensimulasikan kata pembungkus UITextField, untuk tidak memasukkan banyak baris.
SwiftArchitect
2
Meskipun di luar topik, ini sangat berguna. Saya juga ingin UITextView dimasukkan dengan beberapa baris dan abaikan keyboard saat saya mau.
Yeung
5

Baru saja menyelesaikan masalah ini dengan cara yang berbeda.

  • Buat tombol yang akan ditempatkan di latar belakang
  • Dari Inspektur Atribut, ubah jenis tombol ke kustom, dan buat tombol transparan.
  • Rentangkan tombol untuk menutupi seluruh tampilan, dan pastikan tombol ada di belakang semua objek lainnya. Cara mudah untuk melakukan ini adalah dengan menyeret tombol ke atas tampilan daftar di tampilan
  • Kontrol seret tombol ke viewController.hfile dan buat tindakan (Acara Terkirim: Sentuh Di Dalam) seperti:

    (IBAction)ExitKeyboard:(id)sender;
  • Dalam ViewController.makan terlihat seperti:

    (IBAction)ExitKeyboard:(id)sender {
        [self.view endEditing:TRUE];
    }
  • Jalankan aplikasi, dan ketika Anda mengklik jauh dari TextView, keyboard menghilang
Uvichy
sumber
Anda juga harus menambahkan: - (void) textViewDidEndEditing: (UITextView *) textView {[self.TextView resignFirstResponder]; }
samouray
5

Tambahkan pengamat di viewDidLoad

[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(textViewKeyPressed:) name: UITextViewTextDidChangeNotification object: nil];

dan kemudian gunakan pemilih untuk memeriksa "\ n"

-(void) textViewKeyPressed: (NSNotification*) notification {

  if ([[[notification object] text] hasSuffix:@"\n"])
  {
    [[notification object] resignFirstResponder];
  }
}

Itu menggunakan "\ n" dan tidak secara khusus memeriksa kunci kembali, tapi saya pikir ini OK.

MEMPERBARUI

Lihat jawaban ribto di bawah ini yang digunakan [NSCharacterSet newlineCharacterSet]sebagai pengganti\n

ToddB
sumber
Kesalahan itu memang menggunakan \ndan kembali kunci dideteksi berdasarkan \njadi itu memeriksa kunci kembali. Satu-satunya perbedaan adalah bahwa Anda menggunakan notifikasi daripada menggunakan textViewDelegates.
GoodSp33d
Sekarang saya pikir memeriksa [NSCharacterSet newlineCharacterSet]daripada mungkin cara yang lebih baik untuk pergi.
ToddB
5

Tukar Kode

Terapkan UITextViewDelegate di kelas Anda / Lihat seperti ini:

class MyClass: UITextViewDelegate  { ...

atur delegasi textView ke diri sendiri

myTextView.delegate = self

Dan kemudian implementasikan hal berikut:

  func textViewDidChange(_ textView: UITextView) {
    if textView.text.characters.count >= 1 {

        if let lastChar = textView.text.characters.last {

            if(lastChar == "\n"){

              textView.text = textView.text.substring(to: textView.text.index(before: textView.text.endIndex))
              textView.resignFirstResponder()
            }
        }
    }
}

EDIT Saya memperbarui kode karena tidak pernah merupakan ide yang baik untuk mengubah input pengguna di bidang teks menjadi untuk workarround dan tidak mengatur ulang negara setelah kode hack selesai.

Frithjof Schaefer
sumber
4

Coba ini :

 - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
    if ([text isEqualToString:@"\n"]) {
        [self.view endEditing:YES];
    }

    return YES;

}
Nabil El
sumber
4

// Kamu bisa menggunakan ini ...

Langkah 1. Langkah pertama adalah memastikan bahwa Anda menyatakan dukungan untuk UITextViewDelegateprotokol. Ini dilakukan di file header Anda, seperti contoh di sini adalah header yang disebut

EditorController.h:

@interface EditorController : UIViewController  {
  UITextView *messageTextView;
}

@property (nonatomic, retain) UITextView *messageTextView;

@end

Langkah 2. Selanjutnya Anda harus mendaftarkan controller sebagai delegasi UITextView. Melanjutkan dari contoh di atas, berikut adalah bagaimana saya menginisialisasi UITextViewdengan EditorControllersebagai delegasi ...

- (id) init {
    if (self = [super init]) {
        // define the area and location for the UITextView
        CGRect tfFrame = CGRectMake(10, 10, 300, 100);
        messageTextView = [[UITextView alloc] initWithFrame:tfFrame];
        // make sure that it is editable
        messageTextView.editable = YES;

        // add the controller as the delegate
        messageTextView.delegate = self;
    }

Langkah 3. Dan sekarang bagian terakhir dari teka-teki adalah untuk mengambil tindakan sebagai respons terhadap shouldCahngeTextInRangepesan sebagai berikut:

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range 
  replacementText:(NSString *)text
{
    // Any new character added is passed in as the "text" parameter
    if ([text isEqualToString:@"\n"]) {
        // Be sure to test for equality using the "isEqualToString" message
        [textView resignFirstResponder];

        // Return FALSE so that the final '\n' character doesn't get added
        return FALSE;
    }
    // For any other character return TRUE so that the text gets added to the view
    return TRUE;
}
Abhishek Pathak
sumber
3

Anda juga dapat menyembunyikan keyboard saat menyentuh di layar tampilan:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
     UITouch * touch = [touches anyObject];
     if(touch.phase == UITouchPhaseBegan) {
        [txtDetail resignFirstResponder];
      }
 }
Hitesh Vaghela
sumber
IMHO, ini pendekatan yang sangat bagus, jauh lebih baik daripada dengan tombol yang menutupi seluruh tampilan.
WebOrCode
3

Jawaban cepat:

override func viewDidLoad() {
    super.viewDidLoad()
    let tapGestureReconizer = UITapGestureRecognizer(target: self, action: "tap:")
    view.addGestureRecognizer(tapGestureReconizer)
}

func tap(sender: UITapGestureRecognizer) {
    view.endEditing(true)
}
Glauco Neves
sumber
3

Saya menggunakan kode ini untuk mengubah responden.

 - (BOOL)textView:(UITextView*) textView shouldChangeTextInRange: (NSRange) range replacementText: (NSString*) text
    {
        if ([text isEqualToString:@"\n"]) {
            //[textView resignFirstResponder];
            //return YES;
            NSInteger nextTag = textView.tag + 1;
            // Try to find next responder
            UIResponder* nextResponder = [self.view viewWithTag:nextTag];
            if (nextResponder) {
                // Found next responder, so set it.
                [nextResponder becomeFirstResponder];
            } else {
                // Not found, so remove keyboard.
                [textView resignFirstResponder];
            }
            return NO; 


            return NO;
        }
        return YES;

    }
Avijit Nagare
sumber
mengapa tidak menggunakan [self.view endEditing: YES]; sekali??
ajay_nasa
3

Pertanyaannya menanyakan bagaimana cara melakukannya dengan tombol kembali tetapi saya pikir ini bisa membantu seseorang dengan maksud untuk menghilangkan keyboard saat menggunakan UITextView:

private func addToolBarForTextView() {
    let textViewToolbar: UIToolbar = UIToolbar()
    textViewToolbar.barStyle = .default
    textViewToolbar.items = [
        UIBarButtonItem(title: "Cancel", style: .done,
                  target: self, action: #selector(cancelInput)),
        UIBarButtonItem(barButtonSystemItem: .flexibleSpace,
                  target: self, action: nil),
        UIBarButtonItem(title: "Post Reply", style: .done,
                  target: self, action: #selector(doneInput))
    ]
    textViewToolbar.sizeToFit()
    yourTextView.inputAccessoryView = textViewToolbar
}

@objc func cancelInput() { print("cancel") }
@objc func doneInput() { print("done") }

override func viewDidLoad() {
    super.viewDidLoad()
    addToolBarForTextView()
}

Panggil addToolBarForTextView () di viewDidLoad atau metode siklus hidup lainnya.

Sepertinya itu adalah solusi sempurna bagi saya.

Bersulang,

Murat

Murat Yasar
sumber
1
Untuk 2019 sekarang salin dan tempel, tidak ada kesalahan sintaks dan penamaan saat ini
Fattie
1
sejauh ini jawaban terbaik di sini. Saya baru saja memperbaiki kesalahan sintaksis sederhana, tentu saja edit sesuai keinginan. Terima kasih!
Fattie
2

Baik. Semua orang telah memberikan jawaban dengan trik tetapi saya pikir cara yang tepat untuk mencapainya adalah dengan

Menghubungkan tindakan berikut ke acara " Did End On Exit " di Interface Builder. (klik kanan TextFielddan cntrl-drag dari ' Did end on exit ' ke metode berikut.

-(IBAction)hideTheKeyboard:(id)sender
{
    [self.view endEditing:TRUE];
}
carbonr
sumber
6
-1 Pertanyaannya adalah tentang UITextView dan bukan UITextField teman saya
Yogi
2
sebagian besar jawaban ini ada di sini dengan suara karena cocok dengan berbagai skenario pengembang yang berbeda.
carbonr
Jika Anda menggunakan UITextField, ini adalah cara untuk melakukannya. BTW, Anda harus menggunakan YA / TIDAK untuk Objective-C BOOLs, bukan TRUE / FALSE.
Jon Shier
1
@jshier: BENAR / SALAH juga OK
Yogi
2

Serupa dengan jawaban lain menggunakan UITextViewDelegatetetapi antarmuka swift yang lebih baru isNewlineadalah:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    if let character = text.first, character.isNewline {
        textView.resignFirstResponder()
        return false
    }
    return true
}
BROK3N S0UL
sumber
1
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range  replacementText:(NSString *)text
{
    if (range.length==0) {
        if ([text isEqualToString:@"\n"]) {
            [txtView resignFirstResponder];
            if(textView.returnKeyType== UIReturnKeyGo){

                [self PreviewLatter];
                return NO;
            }
            return NO;
        }
    }   return YES;
}
Rinju Jain
sumber
1
+ (void)addDoneButtonToControl:(id)txtFieldOrTextView
{
    if([txtFieldOrTextView isKindOfClass:[UITextField class]])
    {
        txtFieldOrTextView = (UITextField *)txtFieldOrTextView;
    }
    else if([txtFieldOrTextView isKindOfClass:[UITextView class]])
    {
        txtFieldOrTextView = (UITextView *)txtFieldOrTextView;
    }

    UIToolbar* numberToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0,
                                                                          0,
                                                                          [Global returnDeviceWidth],
                                                                          50)];
    numberToolbar.barStyle = UIBarStyleDefault;


    UIBarButtonItem *btnDone = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"btn_return"]
                                                                style:UIBarButtonItemStyleBordered
                                                               target:txtFieldOrTextView
                                                               action:@selector(resignFirstResponder)];

    numberToolbar.items = [NSArray arrayWithObjects:btnDone,nil];
    [numberToolbar sizeToFit];

    if([txtFieldOrTextView isKindOfClass:[UITextField class]])
    {
         ((UITextField *)txtFieldOrTextView).inputAccessoryView = numberToolbar;
    }
    else if([txtFieldOrTextView isKindOfClass:[UITextView class]])
    {
         ((UITextView *)txtFieldOrTextView).inputAccessoryView = numberToolbar;
    }
}
Venu Gopal Tewari
sumber
0

Saya tahu itu bukan jawaban yang tepat untuk pertanyaan ini, tetapi saya menemukan utas ini setelah mencari jawabannya di internet. Saya berasumsi orang lain berbagi perasaan itu.

Ini adalah varian saya dari UITapGestureRecognizer yang saya temukan andal dan mudah digunakan - cukup atur delegasi dari TextView ke ViewController.

Alih-alih ViewDidLoad saya menambahkan UITapGestureRecognizer ketika TextView menjadi aktif untuk mengedit:

-(void)textViewDidBeginEditing:(UITextView *)textView{
    _tapRec = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tap:)];

    [self.view addGestureRecognizer: _tapRec];
    NSLog(@"TextView Did begin");
}

Ketika saya mengetuk di luar TextView, tampilan mengakhiri mode pengeditan dan UITapGestureRecognizer menghapus sendiri sehingga saya dapat terus berinteraksi dengan kontrol lain dalam tampilan.

-(void)tap:(UITapGestureRecognizer *)tapRec{
    [[self view] endEditing: YES];
    [self.view removeGestureRecognizer:tapRec];
    NSLog(@"Tap recognized, tapRec getting removed");
}

Saya harap ini membantu. Tampaknya begitu jelas tetapi saya belum pernah melihat solusi ini di mana pun di web - apakah saya melakukan sesuatu yang salah?

BGC
sumber
0

Jangan lupa untuk mengatur delegasi untuk textView - jika tidak, resignfirstresponder tidak akan berfungsi.

Ron Holmes
sumber
0

Coba ini .

NSInteger lengthOfText = [[textView.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length];
Hiren Panchal
sumber
0

Untuk Xcode 6.4., Swift 1.2. :

   override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent)
    {
        super.touchesBegan(touches, withEvent: event)
        if let touch = touches.first as? UITouch
        {
            self.meaningTextview.resignFirstResponder()
        }
    }
MB_iOSDeveloper
sumber
0

Anda harus menambahkan UIToolbarke atas UITextView agar lebih mudah daripada menggunakanshouldChangeTextIn

Dalam Swift 4

let toolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
        toolbar.barStyle = .default
        toolbar.items = [
            UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil),
            UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(doneAction))
        ]
        textView.inputAccessoryView = toolbar
@objc func doneAction(){
 self.textView.resignFirstResponder()
}
Giang
sumber
Sejauh ini solusi terbaik. Perhatikan bahwa alih-alih mengatur bingkai, gunakan sajatoolbar.sizeToFit()
Fattie