iphone - 如何用退貨鍵解除UITextView的鍵盤?




objective-c keyboard (20)

//你可以使用這個...

步驟1.第一步是確保您聲明支持UITextViewDelegate協議。 這是在你的頭文件中完成的,例如這裡是頭文件

EditorController.h:

@interface EditorController : UIViewController  {
  UITextView *messageTextView;
}

@property (nonatomic, retain) UITextView *messageTextView;

@end

第2步。接下來,您需要將控制器註冊為UITextView的代表。 從上面的例子繼續,這裡是我如何用EditorController作為委託來初始化UITextView ...

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

第3步。現在最後一部分的難題是響應shouldCahngeTextInRange消息採取行動,如下所示:

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

在IB的庫中,介紹告訴我們,當按下返回鍵時, UITextView的鍵盤將消失。 但實際上,返回鍵只能用作'\ n'。

我可以添加一個按鈕並使用[txtView resignFirstResponder]來隱藏鍵盤。

但有沒有辦法在鍵盤上添加返回鍵的操作,以便我不需要添加UIButton


SWIFT代碼

在你的類/視圖中實現UITextViewDelegate,如下所示:

class MyClass: UITextViewDelegate  { ...

將textView委託設置為self

myTextView.delegate = self

然後執行以下操作:

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

編輯我更新了代碼,因為它不是一個好主意,可以將文本字段中的用戶輸入更改為工作區,並且在完成黑客代碼後不會重置狀態。


使用導航控制器託管一個欄來關閉鍵盤:

在.h文件中:

UIBarButtonItem* dismissKeyboardButton;

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

剛剛以不同的方式解決了這個問題。

  • 創建一個將放置在後台的按鈕
  • 從Attribute Inspector中,將按鈕類型更改為自定義,並使按鈕變為透明。
  • 展開按鈕以覆蓋整個視圖,並確保按鈕位於所有其他對象之後。 簡單的方法是將按鈕拖到視圖中列表視圖的頂部
  • 控制拖動按鈕到viewController.h文件,並創建一個動作(發送事件:觸摸裡面),如:

    (IBAction)ExitKeyboard:(id)sender;
    
  • ViewController.m應該如下所示:

    (IBAction)ExitKeyboard:(id)sender {
        [self.view endEditing:TRUE];
    }
    
  • 運行應用程序,當您從TextView中單擊時,鍵盤消失

嘗試這個 。

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

嘗試這個 :

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

    return YES;

}

在你的視圖控制器中添加這個方法。

Swift

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

這種方法對你也有幫助:

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

在使用uitextview時還有另一種解決方案,您可以在“textViewShouldBeginEditing”中將工具欄添加為InputAccessoryView,並從此工具欄的完成按鈕中可以關閉鍵盤,其代碼如下:

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

在textviewdelegate方法中

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

在工具欄中按鈕完成的操作如下:

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

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

就像samvermette的暗淡評論一樣,我也不喜歡檢測“\ n”的想法。 “返回”鍵在UITextView中有一個原因,那就是轉到下一行。

我認為最好的解決方案是模仿iPhone消息應用程序 - 這是在鍵盤上添加工具欄(和按鈕)。

我從以下博客文章獲取代碼:

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

腳步:

- 將工具欄添加到XIB文件 - 將高度設置為460

- 添加工具欄按鈕項目(如果尚未添加)。 如果您需要將它右對齊,還可以將靈活的條形按鈕項添加到XIB,並移動工具欄按鈕項

創建將按鈕項鍊接​​到resignFirstResponder的操作,如下所示:

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

-然後:

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

我使用這段代碼來改變響應者。

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

    }

我發現josebama答案是這個主題中最完整,最乾淨的答案。

下面是它的Swift 3語法:

func textView(_ textView: UITextView, shouldChangeTextIn _: NSRange, replacementText text: String) -> Bool {
    let resultRange = text.rangeOfCharacter(from: CharacterSet.newlines, options: .backwards)
    if text.characters.count == 1 && resultRange != nil {
        textView.resignFirstResponder()
        // Do any additional stuff here
        return false
    }
    return true
}

我知道這不是這個問題的確切答案,但是我在找到答案後找到了這個線程。 我假設其他人分享這種感覺。

這是我對UITapGestureRecognizer的不同看法,我覺得它很可靠且易於使用 - 只需將TextView的委託設置為ViewController即可。

在TextView變為活動狀態進行編輯時,我添加了UITapGestureRecognizer而不是ViewDidLoad:

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

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

當我在TextView外部輕敲時,視圖結束編輯模式,UITapGestureRecognizer會自行移除,以便我可以繼續與視圖中的其他控件進行交互。

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

我希望這有幫助。 這似乎很明顯,但我從來沒有在網絡上的任何地方看到這種解決方案 - 我做錯了什麼?


我知道這已經回答了很多次,但這是我的兩分錢的問題。

我發現了samvermette和ribeto真正有用的答案,以及ribeto答案中samvermette的評論。 但這些方法存在問題。 matt在samvermette的回答中提到的問題是,如果用戶想要在內部粘貼換行符,鍵盤會隱藏而不粘貼任何東西。

所以我的方法是上述三種解決方案的混合,並且只在字符串的長度為1時檢查輸入的字符串是否為新行,以便確保用戶正在輸入而不是粘貼。

這是我所做的:

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

更優雅的方式是當用戶在鍵盤框架外部的某個地方點擊時關閉鍵盤。

首先,將您的ViewController視圖設置為UIBuilder身份檢查器中的類“UIControl”。 控制 - 將視圖拖到ViewController的頭文件中,並將其作為一個動作與作為Touch Up Inside的事件相鏈接,例如:

ViewController.h

-(IBAction)dismissKeyboardOnTap:(id)sender;

在主ViewController文件中,ViewController.m:

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

您可以使用類似的技術需要雙擊或長時間觸摸。 您可能需要將您的ViewController設置為UITextViewDelegate並將TextView連接到ViewController。 此方法適用於UITextView和UITextField。

來源:大書呆子牧場

編輯:我也想補充一點,如果你使用的是UIScrollView,上述技術可能無法通過界面生成器輕鬆工作。 在這種情況下,您可以使用UIGestureRecognizer並在其中調用[[self view] endEditing:YES]方法。 一個例子是:

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

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

當用戶輕敲鍵盤外部並且沒有點擊輸入空間時,鍵盤將被解除。


當用戶點擊返回鍵時, UITextView沒有任何方法。 如果您希望用戶只能添加一行文本,請使用UITextField 。 觸摸返回並隱藏UITextView的鍵盤不符合接口指南。

即使如此,如果您想要這樣做,請實現UITextViewDelegate textView:shouldChangeTextInRange:replacementText:方法,並檢查替換文本是否為\n ,隱藏鍵盤。

可能還有其他的方法,但我沒有意識到。


迅速

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


迅速回答:

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

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

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

-(BOOL)textFieldShouldReturn:(UITextField *)textField; // called from textfield (keyboard)

-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text; // good tester function - thanks




iphone-softkeyboard