文字列をツイートするためのテキストビューを提供しています。
次の方法を適用して、文字数を140文字に制限しています。
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
if([text isEqualToString:@"\b"]){
DLog(@"Ohoooo");
return YES;
}else if([[textView text] length] > 140){
return NO;
}
return YES;
}
バックスペースが機能しないという最初の条件を除いて、コードはうまく機能しています。メソッドがfalseを返し、ユーザーがそれ以上文字を挿入できないように140文字の制限に達したと仮定しますが、その後、いくつかの文字を削除しようとすると、テキストビューは無効になったまま動作します。
したがって、質問はどのようにしてtextview.text
から文字を削除するか、テキストビューを再度有効にするかです。
Apple reference が言うように、代わりに空の文字列を探す必要があります
ユーザーがDeleteキーを押すと、範囲の長さは1になり、空の文字列オブジェクトがその単一の文字を置き換えます。
実際に確認したいチェックは[[textView text] length] - range.length + text.length > 140
、カット/ペースト操作を考慮します。
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
return textView.text.length + (text.length - range.length) <= 140;
}
これは、ユーザーがテキストをカットするか、1文字より長い文字列を削除する(つまり、選択してバックスペースを押す)か、範囲を強調表示してそれより短いまたは長い文字列を貼り付けることを考慮します。
Swift 4.0バージョン
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
return textView.text.count + (text.count - range.length) <= 140
}
for Swift 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
}
ただし、以下の作業コードも使用できます。
- (void)textViewDidChange:(UITextView *)textView{
NSInteger restrictedLength=140;
NSString *temp=textView.text;
if([[textView text] length] > restrictedLength){
textView.text=[temp substringToIndex:[temp length]-1];
}
}
これを
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
int limit = 139;
return !([textField.text length]>limit && [string length] > range.length);
}
これは140文字のみを入力し、必要に応じて削除できます
迅速:
// 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;
}
Swift 5およびiOS 12)では、UITextViewDelegate
プロトコルの一部である textView(_:shouldChangeTextIn:replacementText:)
メソッドの以下の実装を試してください。
_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
}
_
range
(NSRange
)からrangeOfTextToReplace
(_Range<String.Index>
_)への変換です。この変換が重要である理由を理解するには、この ビデオチュートリアル をご覧ください。textField
の- smartInsertDeleteType
値を_UITextSmartInsertDeleteType.no
_に設定する必要もあります。これにより、貼り付け操作の実行時に(不要な)余分なスペースが挿入される可能性がなくなります。以下の完全なサンプルコードは、UIViewController
にtextView(_:shouldChangeTextIn:replacementText:)
を実装する方法を示しています。
_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
}
}
_
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;
}
最初は、ボタンは無効に設定されています。ただし、ユーザーが空のテストを投稿できないようにするには、ボタンのクリックに条件を設定するだけです。
- (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
}
ここで最適なものを探します。残りの文字数を表示: 'n'文字が残っています。
var charCount = 0;
let maxLength = 150
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
if text == "" // Checking backspace
{
if textView.text.characters.count == 0
{
charCount = 0
characterCount.text = String(format: "%i Characters Left", maxLength - charCount)
return false
}
charCount = (textView.text.characters.count - 1)
characterCount.text = String(format: "%i Characters Left", maxLength - charCount)
return true
}
else
{
charCount = (textView.text.characters.count + 1)
characterCount.text = String(format: "%i Characters Left", maxLength - charCount)
if charCount >= maxLength + 1
{
charCount = maxLength
characterCount.text = String(format: "%i Characters Left", maxLength - charCount)
return false;
}
}
return true
}
これを試してください:-
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
print("chars \(textView.text.characters.count) \( text)")
if(textView.text.characters.count > 20 && range.length == 0) {
print("Please summarize in 20 characters or less")
return false;
}
return true;
}
@Tim GostonyのSwiftバージョン:
// restrict the input for textview to 500
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
return count(textView.text) + (count(text) - range.length) <= 500;
}
オーバーフローをカットし、カウントラベルを更新しながら、最大文字数までコードを貼り付けられるようにしたい場合:
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
}
拡張子付き:
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
}
}
上記の回答のいくつかの問題は、たとえば、テキストフィールドがあり、15文字の入力制限を設定する必要がある場合、15番目の文字を入力した後に停止することです。ただし、削除は許可されません。それは削除ボタンも機能しないということです。私は同じ問題に直面していたので。以下に示すソリューションを使用しました。私にぴったりの作品
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if(textField.tag==6)
{
if ([textField.text length]<=30)
{
return YES;
}
else if([@"" isEqualToString:string])
{
textField.text=[textField.text substringToIndex:30 ];
}
return NO;
}
else
{
return YES;
}
}
私は「6」を設定したタグのテキストフィールドを持ち、最大文字数制限= 30を制限しています。どんな場合でもうまくいく
Use the following code...
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if(text.length == 0)
{
return YES;
}
else if(self.txtViewComments.text.length > 255)
{
return NO;
}
else
{
return YES;
}
}
以下のコードをtextView:shouldChangeTextInRange:replacementText:
方法 :
if ([textView.text length]>=3 && ![text isEqualToString:@""]) {
return NO;
}
return YES;