I have a UITextView. I have the delegate for myTextView set to self and, when I do normal editing, this method calls just fine:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
NSLog(#"Called");
}
In my app, I call in my code: [myTextView insertText:#"Hello World"];. When I do, I need to call textView:shouldChangeTextInRange:replacementText: after the text is inserted. How do I do this?
Call it explicitly. Call it before editing and only perform the edit if it returns YES. To call it explicitly you need to know the selected range (get the selected range with selectedTextRange), that's it. You already have the text to add and the text view.
Thanks for the answer, #Wain!
Here's what worked:
- (void)insertText
{
NSString *stringToAdd = #"Hello World";
NSString *replacementText = [myTextView.text stringByAppendingString:stringToAdd];
[napkinTextView insertText:stringToAdd];
[self textView:myTextView shouldChangeTextInRange:NSMakeRange(0, stringToAdd.length) replacementText:replacementText];
}
Related
I added a feedback box inside my IOS application, and I want it to take only text to submit the response from the user, but when I tried to enter a white spaces inside the box it took it as a text and accept the submitting! How can I prevent that?
Specify the UIViewController as the delegate to your text view (you can do this either programmatically or specify the delegate in Interface Builder); and
Your UITextViewDelegate method shouldChangeTextInRange needs to check to see if the string to be inserted contains a space:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if ([text rangeOfCharacterFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]].location != NSNotFound) {
return NO;
}
return YES;
}
I have a if/else statement in my objective-c code. The if/else statement runs like this:
-(void)textViewDidBeginEditing:(UITextView *)textView
{
if(textView==self.heardTextView)
{
NSString *string = textView.text;
if ([string rangeOfString:#"CLOSER"].location == NSNotFound)
{
NSLog(#"closest");
}
}
}
The premise of the if/else statement is - if the textview equals a certain word some code will run. But this code isn't running.
I have put a breakpoint on my code and a NSLOG and nothing.
check your text field delegate if you not set your delegate then it's not called..
In your Viewcontroller.H
select your textview give delegate on textview.
First you need to set the delegate of the text view. You can do this with Interface Builder, but if you prefer using code you can do this in the viewDidLoad method of your view controller:
myTextView.delegate = self;
Now, when do you want the NSLog statement to be executed? Right now it looks like it will be run only if you type "CLOSER", then make the text view lose focus and then click on it again.
If you want the NSLog to run as you type, you should use:
-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
And also be careful, you need to calculate the next string value in the text field before testing its contents:
NSString *finalText = [textField.text stringByReplacingCharactersInRange:range withString:string];
Check your delegates, you must not have made the delegate of your textview as self. Check it once again. Or you might have done to some other class.
When using a UITextView to gather user input in Objective-C, how can I limit the user from trying to do more than one line break at a time?
So, this would be fine:
This is my text.
Here is some more text.
But this would not be fine:
This is my text.
Here is some more text way down here.
In your ViewController.h add UITextViewDelegate:
YourViewController : UIViewController <UITextViewDelegate>
and in the ViewController.m implement the method textView:shouldChangeTextInRange:replacementText: this way:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if ([text isEqualToString:#"\n"]) {
NSMutableString *futureString = [textView.text mutableCopy];
[futureString insertString:text atIndex:range.location];
NSRange rangeOflineBreaks = [futureString rangeOfString:#"\n\n\n"];
if (rangeOflineBreaks.location != NSNotFound) {
return NO;
}
}
return YES;
}
This will be executed every time before the user wants to add some text to the textView and wont let him add another line break if it notices that he wants to add a line break and it finds, after trying adding it (that's why the futureString name) a triple line break mode. In that case he wont let the user add another line break.
Try it out, it should work :)
PS: Don't forget to set your textView delegate the viewController in the viewDidLoad (yourTextView.delegate = self)
I have a UITextView which I am using as text entry in a chat application. When the user presses return then I want to do some action e.g. save the chat message.
I haven't been able to find a solution that allows me to do this (lots for TextFields but not for TextView).
Here is the solution I am trying at the moment, which seems to be the most obvious I can find, but it isnt working, in debug I see that the method isn't touched:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if ([text isEqualToString:#"\n"]) {
NSLog(#"Return pressed");
} else {
NSLog(#"Other pressed");
}
return YES;
}
In my chat .h file:
#interface ChatTableViewController : UITableViewController <UITextViewDelegate>
and viewdidload .m file
- (void)viewDidLoad {
[super viewDidLoad];
enterText.delegate = self;
// more
}
Incidentally if there is a better field to use as input in a chat program than UITextView please let me know.
Many thanks
... but it isn't working, in debug I see that the method isn't touched
Your problem obviously is that the delegate method is not called. Fix the delegate and use the code you already have: it's good.
Try this way. No need to go with delegates.
Add this event responder at where you initialize the textView.
[theTextView addTarget:self
action:#selector(targetMethodToPerformCustomOperation)
forControlEvents:UIControlEventEditingDidEndOnExit];
Needing to present user a multiline text field for comment entry, I am using a UITextView instead of a UITextField. I would like to use textFieldShouldReturn on my UITextView to send the data to server. How might I do that? Based on my readings so far, the method is only applicable to UITextField. So what is the equivalent for UITextView?
By adding the UITextViewDelegate to your viewControllerHeader
#interface ViewController : UIViewController<UITextViewDelegate>
This'll allow you access to the UITextViewDelegate methods of which there are a couple of which should allow you to know when the user has either pressed return or let you know when they have finished editing, for example
- (void)textViewDidEndEditing:(UITextView *)textView{
//From here you can action your methods to send the data to your server as required etc.
}
There's also this method
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
//Which you can use to listen for the #"\" return action if you prefer.
}
I hope this helps