UITextView klavyesini dönüş tuşu ile nasıl kapatabilirim?


382

IB'nin kütüphanesinde, giriş bize returntuşa basıldığında klavyenin UITextViewkaybolacağını söyler . Ama aslında returnanahtar sadece '\ n' gibi davranabilir.

Bir düğme ekleyebilir [txtView resignFirstResponder]ve klavyeyi gizlemek için kullanabilirim .

Ancak, returnklavyedeki tuş için eylem eklemenin bir yolu var, böylece eklememe gerek yok UIButtonmu?


Bu blog gönderisindeki talimatları izleyin: iphonedevelopertips.com/cocoa/…
ManojN

Yanıtlar:


354

UITextViewkullanıcı dönüş tuşuna bastığında çağrılacak herhangi bir yöntem içermez. Kullanıcının yalnızca bir metin satırı ekleyebilmesini istiyorsanız a öğesini kullanın UITextField. Geri dönüşe basmak ve klavyeyi a için gizlemek UITextViewarayüz yönergelerine uymaz.

O zaman bile, bunu yapmak istiyorsanız , değiştirme metninin textView:shouldChangeTextInRange:replacementText:yöntemini uygulayın UITextViewDelegateve bu metinde \nklavyeyi gizleyin.

Başka yollar da olabilir ama farkında değilim.


1
Teşekkürler ve yöntem iyi çalışıyor. UITextView kullanmanın nedeni, metni birden çok satırda tutabilmesidir. Ve şimdi mesaj kutusu olarak kullanıyorum.
Chilly Zhong

28
Dönüş tuşunu kullanarak [textField setReturnKeyType: UIReturnKeyDone];veya arabirim oluşturucu kullanarak "tamamlandı" olarak değiştirmek kolaydır
Casebash

9
Tamam, şimdi anlıyorum ki Apple çok satırlı bir metin alanı ile bitirme yolunun menü çubuğuna
yapılanları eklemektir

8
Bu sorunu çözmek için iyi bir yol değildir, çünkü kullanıcıyı klavyeden çıkmak için enter kullanmasını kısıtlıyorsunuz. Muhtemelen en iyi yol, resignFirstResponder yöntemini yürüten bir düğme eklemektir.
Ele

5
@Casebash. Dönüş anahtarının "tamamlandı" olarak ayarlanması, Xcode 6.4, Swift 2.0'daki sorunu çözmüyor gibi görünüyor. Anahtarı IB kullanarak ayarladım.
MB_iOSDeveloper

505

Snippet'i tam burada yayınlayacağımı düşündüm:

UITextViewDelegateProtokol için destek beyan ettiğinizden emin olun .

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

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

    return YES;
}

Swift 4.0 güncellemesi:

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

75
Sorun şu ki, bu gerçekten kullanıcının dönüş tuşuna dokunduğunu tespit etmenin bir yolu değildir . Kullanıcı metin alanına bir dönüş karakteri yapıştırabilir ve aynı temsilci mesajını alırsınız. Temel olarak metin görünümünü kötüye kullanıyorsunuz. Klavyeyi kapatmanın yolu (1) bunu yapmamaktır (Posta uygulamasında bir ileti oluştururken olduğu gibi) veya (2) arayüzde başka bir yerde (Notlar uygulamasında olduğu gibi) bir Bitti düğmesine sahip olmaktır. Örneğin, klavyeye aksesuar görünümü gibi bir düğme ekleyebilirsiniz.
matt

@ Sam V snippet'i havalı bir adamdı. benim için çalışıyor. bir ton adam teşekkürler. Sayısal klavyenin devre dışı bırakılması için herhangi bir snippet var mı? Saygılarımızla shishir
Shishir.bobby

Muhteşem. Bazı durumlarda, klavyeden kurtulmak için satırları denemeyi hatırlatmak isteriz ... [self.view endEditing: YES];
Fattie

@Vojto, iPad'de iyi çalışıyor. Muhtemelen temsilciyi belirlemediniz.
Vincent

4
Sorun, klavyenin kapatmak için kullanılan arabirimin bir kısmını gizliyor olabileceğidir. IOS'un klavyeyi kapatmak için adanmış her klavyede bir düğmeye sahip olmaması gerçekten saçmadır, böylece kullanıcı isterse bunu yapabilir.
Sani Elfishawy

80

Bu zaten cevaplanmış biliyorum ama ben gerçekten newline için dize değişmezi kullanarak sevmiyorum bu yüzden burada ne yaptım.

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

    [txtView resignFirstResponder];
    return NO;
}

Swift 4.0 güncellemesi:

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
}

6
Bunu şu şekilde değiştirebilirim: NSRange resultsRange = [text rangeOfCharacterFromSet: [NSCharacterSet newlineCharacterSet] seçenekleri: NSBackwardsSearch]; Bu zaten bir saldırı olduğu için, dizenin sonunu bir dönüş için kontrol etmek daha güvenli bir yol olabilir.
maxpower

@maxpower Çok iyi yorum. Ayrıca, değiştirilen metne karşı kontrol etmek daha iyidir, örn NSString *replacedText = [textView.text stringByReplacingCharactersInRange:range withString:text].
Rudolf Adamkovič

Bir kullanıcının yeni bir satır içeren başka bir yerden kopyalanmış bir metni yapıştırdığını düşünün . Uygulama klavyeyi kapattığında metin eklemek yerine muhtemelen kafa karıştırırlardı.
Nikolai Ruhe

44

Bunun birçok kez yanıtlandığını biliyorum, ama işte bu konuyla ilgili iki sentim.

Ben tarafından cevap buldum samvermette ve ribeto gerçekten yararlı ve aynı zamanda yoluyla yorumunu maxpower içinde ribeto 'ın cevabı. Ancak bu yaklaşımlarla ilgili bir sorun var. Bu sorun mat bahsedildi samvermette 'ın cevabı ve kullanıcı içindeki bir satır sonu ile bir şeyler yapıştırmak istiyorsa, klavye şey yapıştırarak olmadan gizlemek olacağını bu.

Bu yüzden yaklaşımım, yukarıda belirtilen üç çözümün bir karışımıdır ve yalnızca girilen dizenin dize uzunluğu 1 olduğunda yeni bir satır olup olmadığını kontrol ederek kullanıcının yapıştırma yerine yazdığından emin oluruz.

İşte ne yaptım:

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

Bu, bu sorun için en iyi çözümdür. samvermette yanıtı kullanıcının metin yapıştırmak istediği durumu açıklamaz.
marcopaivaf

36

Daha zarif bir yol, kullanıcı klavyenin çerçevesinin dışında bir yere dokunduğunda klavyeyi kapatmaktır.

İlk olarak, ViewController görünümünüzü UIBuilder'daki kimlik denetçisindeki "UIControl" sınıfına ayarlayın. Görünümü, ViewController başlık dosyasına sürükleyip sürükleyin ve İçeride Rötuş olarak etkinlikle bir eylem olarak ilişkilendirin:

ViewController.h

-(IBAction)dismissKeyboardOnTap:(id)sender;

Ana ViewController dosyasında ViewController.m:

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

Benzer teknikleri kullanarak çift dokunma veya uzun dokunma gerekebilir. ViewController'ınızı bir UITextViewDelegate olarak ayarlamanız ve TextView'i ViewController'a bağlamanız gerekebilir. Bu yöntem hem UITextView hem de UITextField için çalışır.

Kaynak: Big Nerd Ranch

DÜZENLEME: Ayrıca bir UIScrollView kullanıyorsanız, yukarıdaki tekniğin Arayüz Oluşturucu aracılığıyla kolayca çalışmayabileceğini eklemek istiyorum. Bu durumda, bir UIGestureRecognizer kullanabilir ve bunun yerine [[self view] endEditing: YES] yöntemini çağırabilirsiniz. Örnek olarak şunlar verilebilir:

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

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

Kullanıcı klavyenin dışına dokunduğunda ve bir giriş alanına dokunmadığında, klavye kapanacaktır.


1
Fikir ile seviyorum GestureRecognizerama büyük sorun görünümünde tüm düğmeler veya kontrol artık tıklanabilir değildir.
uzman

35

Bu yöntemi görünüm denetleyicinize ekleyin.

Swift :

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

Bu yöntem de sizin için yararlı olabilir:

/**
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()
        }
    }
}

2
Protokolü onaylamayı unutmayın UITextViewDelegate :)
swiftBoy

Dokunmayı geçersiz kılmanın iyi bir fikir olduğunu sanmıyorumBegan ve aramayın super.touchesBegan(touches:withEvent:).
TGO

Bu kodun simetrik doğasını ifade etmek için yazmalısınız else { return true }.
Anlamı önemli

@ anlam önemli değil
Alexander Volkov

@AlexanderVolkov Simetrik bir durum olduğu konusunda hemfikir değilsiniz, ne demek istediğimi bilmiyorsunuz, anlamsal olarak doğru kodun değerine inanmıyorsunuz veya ...?
anlamı önemli

26
-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    if([text isEqualToString:@"\n"])
        [textView resignFirstResponder];
    return YES;
}

yourtextView.delegate=self;

Ayrıca ekle UITextViewDelegate

Protokolü onaylamayı unutmayın

Eğer eklemediyseniz if([text isEqualToString:@"\n"])düzenleyemezsiniz


2
-1 Bu samvermette'nin cevabının daha kötü bir versiyonudur. NOMetin eşitse geri dönmeyi kaçırdınız @"\n".
devios1

17

Uitextview ile kullanırken başka bir çözüm daha var, "textViewShouldBeginEditing" de araç çubuğunu InputAccessoryView olarak ekleyebilirsiniz ve bu araç çubuğunun bitmiş düğmesinden klavyeyi kapatabilirsiniz, bunun kodu aşağıdaki gibidir:

ViewDidLoad içinde

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

Textviewdelegate yönteminde

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

Araç çubuğunda bulunan Düğme Bitti eylemi aşağıdaki gibidir:

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

17

Josebama'nın cevabını bu konudaki en eksiksiz ve temiz cevap olarak buldum .

Bunun için Swift 4 sözdizimi aşağıdadır :

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
}

resultRangeMetin yalnızca sert kod "\ n" önler yeni satır içerip içermediğini test etmek amacı.
Qinghua

6

hızlı

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

ve yapılandır


Bu ekran nereden geliyor?
Sam

6

Klavyeyi kapatmak için bir çubuğa ev sahipliği yapmak üzere gezinme denetleyicisini kullanma:

.h dosyasında:

UIBarButtonItem* dismissKeyboardButton;

.m dosyasında:

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

5

Tıpkı samvermette yapılan mat yorumlarda olduğu gibi "\ n" yi de algılama fikrinden hoşlanmıyorum. "Dönüş" tuşu, UITextView'de bir sonraki satıra gitmek için bir nedenden dolayı var.

Bence en iyi çözüm, klavyeye araç çubuğu (ve düğme) eklemek olan iPhone mesaj uygulamasını taklit etmektir.

Aşağıdaki blog gönderisinden kod aldım:

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

Adımlar:

-Araç çubuğunu XIB dosyanıza ekleyin - yüksekliği 460 olarak ayarlayın

-Araç çubuğu düğmesi öğesi ekle (henüz eklenmediyse). Sağa hizalamanız gerekirse, XIB'ye esnek çubuk düğmesi öğesi ekleyin ve araç çubuğu düğme öğesini taşıyın

-Düğme öğenizi resignFirstResponder'a bağlayan eylemi aşağıdaki gibi oluşturun:

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

-Sonra:

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

Konu dışı. Çözümünüz zarif olsa da, asıl soruya yanıt vermiyor: "UITextView için klavyeyi dönüş tuşu ile nasıl kapatabilirim?". UITextField ifadesinin birden çok satır girmek yerine UITextField sözcük kaydırma işlevini taklit etmek için kullanıldığı durumlar vardır.
SwiftArchitect

2
Konu dışı olmasına rağmen, çok yararlıdır. Ayrıca bir UITextView birden çok satır ile girilmesini istiyorum ve istediğimde klavyeyi kapat.
Yeung

5

Bu sorunu farklı bir şekilde çözdüm.

  • Arka plana yerleştirilecek bir düğme oluşturun
  • Özellik Denetçisinden, düğme türünü özel olarak değiştirin ve düğmeyi saydam hale getirin.
  • Tüm görünümü kapsayacak şekilde düğmeyi genişletin ve düğmenin diğer tüm nesnelerin arkasında olduğundan emin olun. Bunu yapmanın kolay yolu, düğmeyi Görünüm'deki liste görünümünün üstüne sürüklemektir
  • Düğmeyi viewController.hdosyaya sürükleyin ve aşağıdaki gibi bir eylem (Gönderilen Etkinlik: İçeride Rötuş) oluşturun:

    (IBAction)ExitKeyboard:(id)sender;
  • In ViewController.mgibi görünmelidir:

    (IBAction)ExitKeyboard:(id)sender {
        [self.view endEditing:TRUE];
    }
  • Uygulamayı çalıştırın ve TextView'den uzağa tıkladığınızda klavye kaybolur

Ayrıca şunu da eklemelisiniz: - (void) textViewDidEndEditing: (UITextView *) textView {[self.TextView resignFirstResponder]; }
samouray

5

ViewDidLoad içine bir gözlemci ekleme

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

ve sonra "\ n" kontrol etmek için seçiciyi kullanın

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

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

"\ N" kullanır ve özellikle bir dönüş anahtarı kontrol etmez, ancak bunun iyi olduğunu düşünüyorum.

GÜNCELLEME

Ribto'nun [NSCharacterSet newlineCharacterSet]yerine aşağıdakileri kullanan cevabına bakınız .\n


Hata yapar \nve dönüş anahtarı dayalı olarak algılanır, \nböylece dönüş anahtarını kontrol eder. Tek fark, textViewDelegates kullanmak yerine bildirimleri kullanmanızdır.
GoodSp33d

Şimdi [NSCharacterSet newlineCharacterSet]\ n yerine kontrol etmek daha iyi bir yol olabilir diye düşünüyorum .
ToddB

5

Swift kodu

Sınıfınızda UITextViewDelegate uygulayın / Görünüm şöyle:

class MyClass: UITextViewDelegate  { ...

textView temsilcisini kendi kendine ayarla

myTextView.delegate = self

Ve sonra aşağıdakileri uygulayın:

  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 Kodu güncelledim çünkü bir metin alanındaki kullanıcı girişini bir çalışma alanı olarak değiştirmek ve kesmek kodu tamamlandıktan sonra durumu sıfırlamamak iyi bir fikir değildir.


4

Bunu dene :

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

    return YES;

}

4

// Bunu kullanabilirsiniz ...

Adım 1. İlk adım, UITextViewDelegateprotokol için destek beyan ettiğinizden emin olmaktır . Bu başlık dosyanızda yapılır, örneğin burada şu başlık denir:

EditorController.h:

@interface EditorController : UIViewController  {
  UITextView *messageTextView;
}

@property (nonatomic, retain) UITextView *messageTextView;

@end

2. Adım. Ardından, denetleyiciyi UITextView temsilcisi olarak kaydetmeniz gerekir. Yukarıdaki örnekten devam edersek burada ilklendir var nasıl UITextViewsahip EditorControllerdelegesi olarak ...

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

Adım 3. Ve şimdi bulmacanın son parçası, shouldCahngeTextInRangemesaja yanıt olarak aşağıdaki gibi harekete geçmektir:

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

3

Görünüm ekranında dokunurken klavyeyi de gizleyebilirsiniz:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
     UITouch * touch = [touches anyObject];
     if(touch.phase == UITouchPhaseBegan) {
        [txtDetail resignFirstResponder];
      }
 }

IMHO, bu çok iyi bir yaklaşım, tüm görünümü kapsayan düğmeden çok daha iyi.
WebOrCode

3

Hızlı cevap:

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

func tap(sender: UITapGestureRecognizer) {
    view.endEditing(true)
}

3

Yanıtlayıcıyı değiştirmek için bu kodu kullandım.

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

    }

neden [self.view endEditing: YES] kullanmıyorsunuz; bir Zamanlar??
ajay_nasa

3

Soru dönüş tuşu ile nasıl yapılacağını sorar, ancak bu sadece UITextView kullanırken klavyenin kaybolmasını amaçlayan birine yardımcı olabileceğini düşünüyorum:

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()
}

Çağrı () addToolBarForTextView içinde viewDidLoad veya başka yaşam döngüsü yöntemiyle.

Benim için mükemmel bir çözüm gibi görünüyor.

Alkış,

Murat


1
2019 için şimdi kopyala ve yapıştır, sözdizimi hatası ve geçerli adlandırma yok
Fattie

1
açık ara en iyi cevap. Basit sözdizimi hatasını düzelttim, tabii ki istediğiniz gibi düzenleyin. Teşekkürler!
Fattie

2

Tamam. Herkes hilelerle cevap verdi ama bence bunu başarmanın doğru yolu

Aşağıdaki eylemin " Bittiğinde Çıkış Yapıldı " etkinliğine bağlanıyorInterface Builder . (sağ tıklayın TextFieldve ' Çıkışta sona erdi ' seçeneğinden aşağıdaki yönteme cntrl tuşuna basıp sürükleyin .

-(IBAction)hideTheKeyboard:(id)sender
{
    [self.view endEditing:TRUE];
}

6
-1 Soru UITextView hakkında değil, UITextField arkadaşım
Yogi

2
bu cevapların çoğu burada oy kullanmaktadır çünkü farklı geliştiricilerin çeşitli senaryolarına uygundur.
carbonr

Bir UITextField kullanıyorsanız, bunu yapmanın yolu budur. BTW, DOĞRU / YANLIŞ yerine Objective-C BOOL'ları için EVET / HAYIR kullanmalısınız.
Jon Shier

1
@jshier: DOĞRU / YANLIŞ da TAMAM
Yogi

2

UITextViewDelegateAncak daha yeni bir hızlı arayüz kullanarak diğer cevaplara benzetilebilir isNewline:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    if let character = text.first, character.isNewline {
        textView.resignFirstResponder()
        return false
    }
    return true
}

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

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

0

Bu sorunun tam cevabı olmadığını biliyorum, ama bir cevap için interneti avladıktan sonra bu konuyu buldum. Başkalarının bu duyguyu paylaştığını varsayıyorum.

Bu güvenilir ve kullanımı kolay bulduğum UITapGestureRecognizer benim varyansı - sadece TextView temsilcisini ViewController için ayarlayın.

ViewDidLoad yerine TextView düzenleme için aktif hale geldiğinde UITapGestureRecognizer'ı ekliyorum:

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

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

TextView dışına dokunduğumda, görünüm düzenleme modunu sonlandırır ve görünümdeki diğer denetimlerle etkileşime devam edebilmem için UITapGestureRecognizer kendisini kaldırır.

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

Umarım bu yardımcı olur. Çok açık görünüyor ama bu çözümü web üzerinde hiç görmedim - yanlış bir şey mi yapıyorum?


0

TextView temsilcisini ayarlamayı unutmayın; aksi halde resignfirstresponder çalışmaz.


0

Bunu dene .

NSInteger lengthOfText = [[textView.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length];

0

Xcode 6.4., Swift 1.2 için. :

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

0

Kullanmak UIToolbaryerine kolaylaştırmak için üst UITextView'a eklemelisinizshouldChangeTextIn

Swift 4'te

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()
}

Şimdiye kadar en iyi çözüm. Çerçeveyi ayarlamak yerine sadece şunu kullanıntoolbar.sizeToFit()
Fattie
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.