IBの図書館では、序文は、 return キーを押すと、UITextView
name__のキーボードが消えます。しかし実際には return キーは '\ n'としてのみ機能できます。
ボタンを追加してキーボードを隠すために[txtView resignFirstResponder]
を使うことができます。
しかしのためのアクションを追加する方法はありますか return 私はUIButton
name__を追加する必要がないようにキーボードのキーを押しますか?
UITextView
には、ユーザーがリターンキーを押したときに呼び出されるメソッドはありません。ユーザーが1行のテキストしか追加できないようにするには、UITextField
を使用します。リターンキーを押してUITextView
のキーボードを隠しても、インターフェースのガイドラインには従いません。
それでもこれをしたいのであれば、UITextViewDelegate
のtextView:shouldChangeTextInRange:replacementText:
メソッドを実装し、そのチェックで置換テキストが\n
であるかどうか、キーボードを隠してください。
他の方法があるかもしれませんが私は知りません。
代わりにここにスニペットを投稿することにしました。
UITextViewDelegate
プロトコルのサポートを宣言してください。
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if([text isEqualToString:@"\n"]) {
[textView resignFirstResponder];
return NO;
}
return YES;
}
Swift 4.0アップデート:
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if text == "\n" {
textView.resignFirstResponder()
return false
}
return true
}
私はこれがすでに答えられていることを知っていますが、改行に文字列リテラルを使うのはあまり好きではないので、ここで私がしたことがあります。
- (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アップデート:
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
}
私はこれが何度も答えられてきたことを知っています、しかしここに問題への私の2セントがあります。
私は samvermette と ribeto による答えを本当に見つけました、そしてまた ribeto の答えの中の maxpower でコメントする。しかし、これらのアプローチには問題があります。 matt が samvermette の答えに言及している問題、それがそれですユーザーが改行を入れて何かを貼り付けたい場合、キーボードは何も貼り付けずに非表示になります。
したがって、私のアプローチは上記の3つの解決策を組み合わせたもので、文字列の長さが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;
}
より洗練された方法は、ユーザーがキーボードのフレームの外側のどこかをタップしたときにキーボードを閉じることです。
まず、UIBuilderのアイデンティティインスペクタで、ViewControllerのビューをクラス "UIControl"に設定します。 ViewをControlキーを押しながら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を使用している場合、私はまた上記のテクニックがInterface Builderを通して容易には働かないかもしれないことを付け加えたい。その場合は、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];
}
ユーザーがキーボードの外側をタップして入力スペースをタップしないと、キーボードは消えます。
このメソッドをView Controllerに追加してください。
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()
}
}
}
-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if([text isEqualToString:@"\n"])
[textView resignFirstResponder];
return YES;
}
yourtextView.delegate=self;
UITextViewDelegate
も追加する
プロトコルの確認を忘れないでください
if([text isEqualToString:@"\n"])
を追加しなかった場合は編集できません
Uitextviewを使用している間に別の解決策があります、あなたは "textViewShouldBeginEditing"でInputAccessoryViewとしてツールバーを追加することができます、そしてこのツールバーのdoneボタンからあなたはキーボードを閉じることができます、このためのコードは以下の通りです:
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;
}
ツールバーにあるButton Doneの動作は次のとおりです。
-(IBAction)btnClickedDone:(id)sender
{
[self.view endEditing:YES];
}
私は josebama による答えがこのスレッドで利用可能な最も完全できれいな答えであることを見つけました。
下記はSwift 4構文です。
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
}
ナビゲーションコントローラを使用してバーをホストし、キーボードを閉じる。
.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;
}
Samvermetteへのマットなコメントと同じように、 "\ n"を検出するという考えも嫌いです。 UITextViewには "return"キーがあります。それはもちろん次の行に行くことです。
私の考えでは、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];
}
ViewDidLoadにオブザーバを追加する
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(textViewKeyPressed:) name: UITextViewTextDidChangeNotification object: nil];
そしてセレクタを使って "\ n"をチェックします
-(void) textViewKeyPressed: (NSNotification*) notification {
if ([[[notification object] text] hasSuffix:@"\n"])
{
[[notification object] resignFirstResponder];
}
}
これは "\ n"を使用し、リターンキーを特にチェックしませんが、これは問題ないと思います。
UPDATE
[NSCharacterSet newlineCharacterSet]
の代わりに\n
を使用する下記のribtoの回答を参照してください。
この問題を別の方法で解決しただけです。
ボタンをviewController.h
ファイルにドラッグして、次のようなアクションを作成します(Sent Event:Touch Up Inside)。
(IBAction)ExitKeyboard:(id)sender;
ViewController.m
では次のようになります。
(IBAction)ExitKeyboard:(id)sender {
[self.view endEditing:TRUE];
}
これを試して :
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
if ([text isEqualToString:@"\n"]) {
[self.view endEditing:YES];
}
return YES;
}
//これを使うことができます...
ステップ1.最初のステップは、UITextViewDelegate
プロトコルのサポートを宣言していることを確認することです。これはあなたのヘッダファイルで行われます。
EditorController.h:
@interface EditorController : UIViewController {
UITextView *messageTextView;
}
@property (nonatomic, retain) UITextView *messageTextView;
@end
ステップ2.次に、コントローラをUITextViewのデリゲートとして登録する必要があります。上記の例から続けて、デリゲートとしてUITextView
を使用してEditorController
を初期化する方法を次に示します。
- (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;
}
スウィフトコード
あなたのクラス/ビューに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()
}
}
}
}
EDITテキストフィールドのユーザー入力を次のように変更して、その後で状態をリセットしないことをお勧めしますハックコードが完成しました。
OK。誰もがトリックを使って答えを出していますが、私はこれを達成するための正しい方法だと思います
次のアクションをInterface Builder
の "終了時に終了しました"イベントに関連付けます。 (TextField
を右クリックし、 '終了時に終了しました'から次の方法にcntrl-ドラッグします。
-(IBAction)hideTheKeyboard:(id)sender
{
[self.view endEditing:TRUE];
}
素早い答え:
override func viewDidLoad() {
super.viewDidLoad()
let tapGestureReconizer = UITapGestureRecognizer(target: self, action: "tap:")
view.addGestureRecognizer(tapGestureReconizer)
}
func tap(sender: UITapGestureRecognizer) {
view.endEditing(true)
}
ビュー画面でタッチしたときにキーボードを隠すこともできます。
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch * touch = [touches anyObject];
if(touch.phase == UITouchPhaseBegan) {
[txtDetail resignFirstResponder];
}
}
私はレスポンダを変更するためにこのコードを使いました。
- (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;
}
問題はリターンキーでどのようにそれをするかを尋ねます、しかし私はこれがUITextViewを使うときただキーボードを消すことを意図する誰かを助けるかもしれないと思います:
@IBOutlet weak var textView: UITextView!
private func addToolBarForTextView() {
let textViewToolbar: UIToolbar = UIToolbar()
textViewToolbar = UIBarStyle.Default
textViewToolbar = [
UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.Done, target: self, action: #selector(self.cancelInput)),
UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: self, action: nil),
UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Done, target: self, action: #selector(self.doneInput))
]
textViewToolbar()
self.textView.inputAccessoryView = textViewToolbar //do it for every relevant textView if there are more than one
}
func doneInput() {
self.textView.resignFirstResponder()
}
func cancelInput() {
self.textView.text = ""
self.textView.resignFirstResponder()
}
addToolBarForTextView()またはviewDidLoadまたはその他のライフサイクルメソッドを呼び出します。
それは私にとって完璧な解決策だったようです。
乾杯、
ムラット
- (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;
}
+ (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;
}
}
UIToolbar
を使用するのではなく、簡単にするためにshouldChangeTextIn
を先頭のUITextViewに追加する必要があります。
スウィフト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()
}
私はそれがこの質問に対する正確な答えではないことを知っています、しかし私は答えを求めてインターネットを探し出した後にこのスレッドを見つけました。私は他人がその気持ちを共有すると思います。
これは私が信頼できるUITapGestureRecognizerの私の変化であり、それは私が信頼できて使いやすいと思う - ちょうどTextControlのデリゲートをViewControllerに設定する。
ViewDidLoadの代わりに、TextViewが編集用にアクティブになったときにUITapGestureRecognizerを追加します。
-(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");
}
これが役に立つことを願っています。それはそれほど明白なようですが、私はウェブ上のどこにもこの解決策を見たことがありません - 私は何か間違ったことをしていますか?
TextViewのデリゲートを設定することを忘れないでください - そうでなければresignfirstresponderは動作しません。
これを試して 。
NSInteger lengthOfText = [[textView.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length];
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()
}
}