ios 限制 uitextview 中的字符数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2492247/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Limit number of characters in uitextview
提问by harshalb
I am giving a text view to tweet some string .
我给出了一个文本视图来推文一些字符串。
I am applying the following method to restrict the number of characters to 140 in length.
我正在应用以下方法将字符数限制为 140 个长度。
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
return [[textView text] length] <= 140;
}
The code is working nicely except the first condition that backspace is not working. suppose that I have reached the limit of 140 characters so that the method will give me false and the user can not insert more characters but after that when I try to delete some characters the text view behave as it is disabled .
除了退格键不起作用的第一个条件外,代码运行良好。假设我已达到 140 个字符的限制,因此该方法会给我错误,并且用户无法插入更多字符,但之后当我尝试删除某些字符时,文本视图的行为就像它被禁用一样。
So the question is: "How to delete characters from textview.textor re-enable the text view?"
所以问题是:“如何从textview.text文本视图中删除字符或重新启用文本视图?”
采纳答案by David Gelhar
You should be looking for an empty string instead, as the apple referencesays
你应该寻找一个空字符串,正如苹果参考所说
If the user presses the Delete key, the length of the range is 1 and an empty string object replaces that single character.
如果用户按下 Delete 键,则范围的长度为 1,并且一个空字符串对象替换该单个字符。
I think the check you actually want to make is something like [[textView text] length] - range.length + text.length > 140, to account for cut/paste operations.
我认为您实际想要进行的检查类似于[[textView text] length] - range.length + text.length > 140,以解释剪切/粘贴操作。
回答by Tim
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
return textView.text.length + (text.length - range.length) <= 140;
}
This accounts for users cutting text, or deleting strings longer than a single character (ie if they select and then hit backspace), or highlighting a range and pasting strings shorter or longer than it.
这说明用户剪切文本,或删除长于单个字符的字符串(即,如果他们选择然后按退格键),或突出显示范围并粘贴比它短或长的字符串。
Swift 4.0 Version
斯威夫特 4.0 版本
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
return textView.text.count + (text.count - range.length) <= 140
}
回答by Rohit Sisodia
for swift 4:
快速 4:
//MARK:- TextView Delegate
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
//300 chars restriction
return textView.text.count + (text.count - range.length) <= 300
}
回答by Saroj
However you can use below working code also..
但是,您也可以使用以下工作代码..
- (void)textViewDidChange:(UITextView *)textView{
NSInteger restrictedLength=140;
NSString *temp=textView.text;
if([[textView text] length] > restrictedLength){
textView.text=[temp substringToIndex:[temp length]-1];
}
}
回答by Imanou Petit
With Swift 5 and iOS 12, try the following implementation of textView(_:shouldChangeTextIn:replacementText:)method that is part of the UITextViewDelegateprotocol:
使用 Swift 5 和 iOS 12,尝试以下textView(_:shouldChangeTextIn:replacementText:)方法的实现,这是UITextViewDelegate协议的一部分:
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
guard let rangeOfTextToReplace = Range(range, in: textView.text) else {
return false
}
let substringToReplace = textView.text[rangeOfTextToReplace]
let count = textView.text.count - substringToReplace.count + text.count
return count <= 10
}
- The most important part of this code is the conversion from
range(NSRange) torangeOfTextToReplace(Range<String.Index>). See this video tutorialto understand why this conversion is important. - To make this code work properly, you should also set the
textField'ssmartInsertDeleteTypevalue toUITextSmartInsertDeleteType.no. This will prevent the possible insertion of an (unwanted) extra space when performing a paste operation.
- 这段代码最重要的部分是从
range(NSRange) 到rangeOfTextToReplace(Range<String.Index>)的转换。请参阅此视频教程以了解为什么这种转换很重要。 - 为了使此代码正常工作,您还应该将
textField的smartInsertDeleteType值设置为UITextSmartInsertDeleteType.no。这将防止在执行粘贴操作时可能插入(不需要的)额外空间。
The complete sample code below shows how to implement textView(_:shouldChangeTextIn:replacementText:)in a UIViewController:
下面的完整示例代码展示了如何textView(_:shouldChangeTextIn:replacementText:)在 a 中实现UIViewController:
import UIKit
class ViewController: UIViewController, UITextViewDelegate {
@IBOutlet var textView: UITextView! // Link this to a UITextView in Storyboard
override func viewDidLoad() {
super.viewDidLoad()
textView.smartInsertDeleteType = UITextSmartInsertDeleteType.no
textView.delegate = self
}
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
guard let rangeOfTextToReplace = Range(range, in: textView.text) else {
return false
}
let substringToReplace = textView.text[rangeOfTextToReplace]
let count = textView.text.count - substringToReplace.count + text.count
return count <= 10
}
}
回答by Ballu
ue this
你这个
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
int limit = 139;
return !([textField.text length]>limit && [string length] > range.length);
}
this will only enter 140 char and you can delete them if need
这只会输入 140 个字符,如果需要,您可以删除它们
回答by Alexander Volkov
Swift:
迅速:
// MARK: UITextViewDelegate
let COMMENTS_LIMIT = 255
func textView(textView: UITextView, shouldChangeTextInRange range:NSRange, replacementText text:String ) -> Bool {
return count(comments.text) + (count(text) - range.length) <= COMMENTS_LIMIT;
}
回答by Vaibhav Saran
Though I needed an if-elsecondition, so this worked for me:
虽然我需要一个if-else条件,所以这对我有用:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
BOOL status = textView.text.length + (text.length - range.length) <= 15;
if (status)
{
[self.btnShare setEnabled:YES];
[self.btnShare setAlpha:1];
}
else
{
[self.btnShare setEnabled:NO];
[self.btnShare setAlpha:0.25];
}
return status;
}
Intially the button is set to disabled. But if you want user cant post an empty test, simply put a condition on button click:
该按钮最初设置为禁用。但是,如果您希望用户不能发布空测试,只需在按钮单击时设置条件:
- (void)btnShare_click:(id)sender
{
NSString *txt = [self.txtShare.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([txt length] == 0)
{
[self.btnShare setEnabled:NO];
[self.btnShare setAlpha:0.25f];
[[[UIAlertView alloc]initWithTitle:nil message:@"Please enter some text to share." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
return;
}
.
.
.
.
.
.
// rest of your code
}
回答by Mojtaba Hosseini
Limit the overflow, not entire text!
限制溢出,而不是整个文本!
By returning falsein the ...shouldChangeTextInRange...delegate method, you are actually limiting the entire text and handling the following situations could be so hard:
通过false在...shouldChangeTextInRange...委托方法中返回,您实际上是在限制整个文本并且处理以下情况可能非常困难:
- Copy and pasting
- Select an area of the text and edit
- Using auto suggest
- Using voice input (voice command or dictation)
- 复制和粘贴
- 选择文本区域并编辑
- 使用自动建议
- 使用语音输入(语音命令或听写)
So you can:
这样你就可以:
Just limit the text overflow
只限制文本溢出
By removing extra characters:
通过删除多余的字符:
textView.text = String(textView.text.prefix(140))
You can do it even on the fly! by putting this code inside the actionof the textViewor textFieldwith the .editingChangedevent.
你甚至可以在飞行中做到!通过把这段代码里面行动的textView或textField与该.editingChanged事件。
回答by Daniel
If you're also looking to be able to paste code up to the max character count, while cutting off overflow, and updating a count label:
如果您还希望能够将代码粘贴到最大字符数,同时切断溢出并更新计数标签:
let maxChar: Int
let countLabel: UILabel
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
let oldChar = textView.text.count - range.length
let oldRemainingChar = maxChar - oldChar
let newChar = oldChar + text.count
let newRemainingChar = maxChar - newChar
let replaceChar = newRemainingChar > 0 ? text.count : oldRemainingChar
if
let textRange = textView.textRange(for: range),
replaceChar > 0 || range.length > 0
{
textView.replace(textRange, withText: String(text.prefix(replaceChar)))
countLabel.text = String(describing: maxChar - textView.text.count)
}
return false
}
With the extension:
随着扩展:
extension UITextInput {
func textRange(for range: NSRange) -> UITextRange? {
var result: UITextRange?
if
let start = position(from: beginningOfDocument, offset: range.location),
let end = position(from: start, offset: range.length)
{
result = textRange(from: start, to: end)
}
return result
}
}

