Answers:
UITextView
没有任何当用户按下返回键时将被调用的方法。如果您希望用户只能添加一行文本,请使用UITextField
。击中返回键并隐藏键盘以UITextView
不遵循界面准则。
即使这样,如果要执行此操作,请实施的textView:shouldChangeTextInRange:replacementText:
方法,UITextViewDelegate
并检查替换文本是否为\n
,隐藏键盘。
可能还有其他方法,但我不知道。
[textField setReturnKeyType: UIReturnKeyDone];
或使用界面生成器将返回键更改为“完成”非常简单
想通了,我会在此处发布代码段:
确保声明对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
}
NSString *replacedText = [textView.text stringByReplacingCharactersInRange:range withString:text]
。
我知道这个问题已经被回答很多次了,但这是我付给这个问题的两分钱。
我发现samvermette和ribeto的答案非常有用,并且maxpower在ribeto的答案中的评论也非常有用。但是这些方法存在问题。马特在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;
}
一种更优雅的方法是,当用户点击键盘框架之外的某个位置时,将其关闭。
首先,在UIBuilder的身份检查器中将ViewController的视图设置为“ UIControl”类。按住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];
}
当用户在键盘上轻击而未轻按输入空格时,键盘将关闭。
GestureRecognizer
大问题的想法,那就是视图上的所有按钮或控件都不再可单击。
在您的视图控制器中添加此方法。
斯威夫特:
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()
}
}
}
super.touchesBegan(touches:withEvent:)
。
else { return true }
。
-(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"])
,则无法编辑
NO
如果文字等于,您错过了返回的机会@"\n"
。
与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];
}
我找到了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
}
resultRange
测试的目的文本是否只包含避免硬编码“\ n”换行。
迅速
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
if text == "\n" {
textView.resignFirstResponder()
}
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];
}
只是以另一种方式解决了这个问题。
控制将按钮拖动到viewController.h
文件,然后创建一个动作(发送事件:Touch Up Inside),如下所示:
(IBAction)ExitKeyboard:(id)sender;
在ViewController.m
应该看起来像:
(IBAction)ExitKeyboard:(id)sender {
[self.view endEditing:TRUE];
}
在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”,而不是专门检查返回键,但是我认为这是可以的。
更新
参见下面的ribto答案,它[NSCharacterSet newlineCharacterSet]
代替了\n
\n
并基于返回键进行检测,\n
因此它会检查返回键。唯一的区别是您使用的是通知而不是textViewDelegates。
[NSCharacterSet newlineCharacterSet]
而不是\ n可能是更好的方法。
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()
}
}
}
}
编辑 我更新了代码,因为将文本字段中的用户输入更改为工作环境,并且在完成黑客代码后不重设状态永远不是一个好主意。
尝试这个 :
- (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
with 初始化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;
}
您也可以在查看屏幕中触摸时隐藏键盘:
- (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时使键盘消失:
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()
}
在viewDidLoad或其他生命周期方法中调用addToolBarForTextView()。
看来这对我来说是完美的解决方案。
干杯,
穆拉特
好。每个人都给出了技巧性的答案,但我认为实现这一目标的正确方法是
将以下操作连接到Windows中的“ 退出时结束 ”事件Interface Builder
。(右键单击TextField
和将cntrl拖动到' 出口是否结束 '到以下方法。
-(IBAction)hideTheKeyboard:(id)sender
{
[self.view endEditing:TRUE];
}
使用UITextViewDelegate
较新的swift界面与其他答案类似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
}
- (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;
}
}
我知道这不是这个问题的确切答案,但是在互联网上寻找答案后,我发现了这个话题。我认为其他人也有这种感觉。
这是我发现的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");
}
我希望这有帮助。看起来如此明显,但我从未在网络上的任何地方看到此解决方案-我做错了什么吗?
尝试这个 。
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()
}
}
您应该添加UIToolbar
到顶部UITextView来简化操作,而不是使用shouldChangeTextIn
在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()
}
toolbar.sizeToFit()