iphone setting UITextView delegate breaks auto completion - iphone

I have a UITextField that I would like to enable auto completion on by:
[self.textView setAutocorrectionType:UITextAutocorrectionTypeYes];
This works normally, except when I give the UITextView a delegate. When a delegate is set, auto complete just stops working. The delegate has only the following method:
- (void)textViewDidChange:(UITextView *)textView
{
self.textView.text = [self.textView.text stringByReplacingOccurrencesOfString:#"\n" withString:#""];
int left = LENGTH_MAX -[self.textView.text length];
self.characterCountLabel.text = [NSString stringWithFormat:#"%i",abs(left)];
}
Does anyone know how to have both auto complete enabled and a delegate set?
Thanks!Tristan

It's probably breaking autocompletion because you're simultaneously modifying the text in the UITextView.

NSRange r= [self.textView.text rangeOfString:#"\n"];
if(r.location!=NSNotFound) //must check before replacing new lines right away, otherwise spellcheck gets broken
{
self.textView.text = [self.textView.text stringByReplacingOccurrencesOfString:#"\n" withString:#""];
}
The problem was caused by doing something that potentially modifies the text every time it was changed (ie calling replace method). The solution was to only call the replace method when it was necessary.

Get this: All you need to do is remove UITextViewDelegate from your interface (.h) file.
You can still set the delegate to the textView in the nib.
Odd, right? Worked for me, I hope it would solve your problem as well.

Related

how to insert text at any cursor position in uitextview?

i want to implement Code by which i can start to insert text at any position of cursor in UITextView in iphone sdk
any idea?
thank you in advance..
i refereed this link: iPhone SDK: How to create a UITextView that inserts text where you tap?
But not Getting it.
Dan's answer is manually changing the text. It's not playing well with UITextView's UndoManager.
Actually it's very easy to insert text with UITextInput protocol API, which is supported by UITextView and UITextField.
[textView replaceRange:textView.selectedTextRange withText:insertingString];
Note: It's selectedTextRange in UITextInput protocol, rather than selectedRange
This is what I use with a custom keyboard, seems to work ok, there may be a cleaner approach, not sure.
NSRange range = myTextView.selectedRange;
NSString * firstHalfString = [myTextView.text substringToIndex:range.location];
NSString * secondHalfString = [myTextView.text substringFromIndex: range.location];
myTextView.scrollEnabled = NO; // turn off scrolling
NSString * insertingString = [NSString stringWithFormat:#"your string value here"];
myTextView.text = [NSString stringWithFormat: #"%#%#%#",
firstHalfString,
insertingString,
secondHalfString];
range.location += [insertingString length];
myTextView.selectedRange = range;
myTextView.scrollEnabled = YES; // turn scrolling back on.
The simplest way (but it won't replace selected text) is to use the insertText: method:
[textView insertText:#"some text you want to insert"];
UITextView conforms to UITextInput which itself conforms to UIKeyInput.
Here is the Glorfindel's answer in Swift3. The text its inserting here it pulls out of the clipboard.
if let textRange = myTextView.selectedTextRange {
myTextView.replace(textRange, withText:UIPasteboard.general.string!)
}

UITextField settext not working

This is frustrating the hell out of me. I am a beginner programmer and cannot figure out why the text is not being changed.
Here is my method which is supposed to set the text of a UITextField:
-(void)updateDays:(NSInteger)days
{
NSString* daysString = [[NSString alloc] initWithFormat:#"%d", days];
[daysTextField setText:daysString];
[daysString release];
}
For whatever reason nothing is happening.
Help appreaciated!
Anytime you have a frustration along the lines of "why isn't this line working", use the debugger or just add an NSLog before it to print out the relevant data:
NSLog(#"updateDays: %# %# <= %#", daysTextField, daysTextField.text, daysString);
Then you know the line (a) is getting executed, (b) the variables are the ones you think they are, and (c) the values are reasonable.
I have experienced this several times, but I think all of them was reasoned by that the UITextField was not initialized at that point.
Set a breakpoint and use debugger to make sure that your UITextField is not nil. You should also check the connection between the .xib file and your code.
Check if the method is called. If yes check if the textfield is set up properly. Cross check to see if the IBOutlet connections are made to the correct object.
I meet this problem too .
It's my code:(in viewdidload)
UITextView *tv = [[UITextView alloc]initWithFrame:CGRectMake(0,0,320,50)]];
tv.text = #"12345";
tv.textColor=[UIColor blackColor];
[self.view addSubView:tv];
And the text(12345) doesn't show;
Lastly,I found that when i set textColor to gray,or any color not black,it works;
I think that it's a bug of the simulator.
I use xcode 4.2 and the iphone5.0simulator.

UITextView inputView

I'm making a custom input method for the iPad, I want to be able to replace the system keyboard with my input method and enter text via that input method.
According to the documentation all I need to do is to set the inputView property with my view and it will be used instead of the system keyboard. I did that and it works, as far as showing the keyboard but how do I actually enter text into the text view?
Supposedly the text view needs to adopt the UIKeyInput and I can use the protocol's methods to enter the text but in reality UITextView doesn't adopt this protocol. conformsToProtocol:#protocol(UIKeyInput) returns NO and "deleteBackwards" is not implemented (insertText and hasText are implemented. In addition to that, "insertText" doesn't cause the textViewDidChange: delegate method to be invoked. Obviously I need to send the UIKeyInput method to some other object (a field editor?) but how do I get it?
Any ideas?
Assuming your keyboard has some buttons, why cant you just set a selector for your keys, and append to the textViews text when each button is clicked, I have done this an it works fine...Here is the method that actually does the "writing" to the UITextView, this method is part of a custom protocol defined by the inputView and is called on the delegate whenever a button is pressed, hope it helps, note: i submit ret when the return key is pushed and <- when backspace is pushed.
-(void)userDidInputString:(NSString*)s
{
NSRange r=padView.textView.selectedRange;
if([s isEqualToString:#"ret"])
s=#"\n";
if([s isEqualToString:#"<-"])
{
NSString *text=padView.textView.text;
if(r.location>0)
{
r.location=r.location-1;
r.length+=1;
}
[padView.textView setScrollEnabled:YES];
padView.textView.text=[text stringByReplacingCharactersInRange:r withString:#""];
[padView.textView setScrollEnabled:NO];
r.length=0;
[padView.textView setSelectedRange:r];
[note setNoteText:padView.textView.text];
}
else {
NSString *text=padView.textView.text;
[padView.textView setScrollEnabled:YES];
padView.textView.text=[text stringByReplacingCharactersInRange:r withString:s];
[padView.textView setScrollEnabled:NO];
r.location=r.location+[s length];
//whenever you modify the text by setting the UITextViews text property it resets the cursor to the end of the text view, we have this line below to go back to where the user left off
[padView.textView setSelectedRange:r];
}
}

UITextField - [textField becomesFirstResponder] - remember text

NSString *tmpTxt = textField.text;
BOOL result = [textField becomeFirstResponder];
textField.text = tmpTxt;
This works 80% of the time, but occasionally:
The whole app will crash.
The text will still be deleted whatever happens.
Whats the best way for a textField to becomeFirstResponder and still retain its text value.
If its clearing when it becomesFirstResponder, I guess is that you have #property(nonatomic) BOOL clearsOnBeginEditing set to YES.
Maybe, where ever you care creating textField, add textField.clearsOnBeginEditing = NO ;
If you are using interface builder there is a check box in the properties for the textfield.
As to why its crashing most of the time...
the text property is defined as: #property(nonatomic, copy) NSString *text
The copy means when you assign a value to it, it will release the previous value, and then make a copy of the value passed in.
Your first line you are keeping a pointer around of the NSString object without calling retain on it. So when you call becomeFirstResponder with clearsOnBeginEditing is called it will set the new value to an empty NSString, which will release the old NSString that the UITextField had reference to. Since its the only thing that had ownership of it, that release call will call dealloc on the NSString, invalidating it.
Then you reassign it back to the text property where it attempts to copy the object that has been freed.
So to do it the way you have it, you will need to call retain and release:
NSString *tmpTxt = [textField.text retain];
BOOL result = [textField becomeFirstResponder];
textField.text = tmpTxt;
[tmpTxt release];
However all you need to do is set clearsOnBeginEdit to NO and you won't need that code.

Contents of UITextField and UITextView to NSString

I have a UITextView and 2 UITextField set up. UITextView resigns first responder status when empty part of the screen is tapped, the same for the 2 UITextField, plus for these 2, the return key also resigns first responder status. All 3 are declared in interface.
I would like to get the contents of all of these to individual NSString and/or learn how to enter them directly into something like:
NSString *urlstr = [[NSString alloc] initWithFormat:#"http://server.com/file.php?var1=%#&var2=%#&var3=%#", *content of UITextView*, *content of UITextField*, *content of UITextField*];
This is a very basic question, i know, but i'm pretty much a novice. If i learn how to do this i'll probably be able to pick up from there.
cheers
(edited)
UITextField and UITextView both have a text property that you can use to retrieve the string values. For example,
NSString *string = [NSString stringWithFormat:#"%#, %#", textField.text, textView.text];
Keep in mind you'll probably want to examine the strings to make sure they're not empty or contain invalid characters before putting them into a URL.
The accepted answer is good, I just wanted to add the following for an expanded look at grabbing text in iOS.
See the textInRange: aspect of the below code that I devised to use one function to determine the text whether it's a UITextField, UITextView or any other class that complies with the UITextInput protocol.
//handle text container object length whether it's a UITextField, UITextView et al
NSUInteger LengthOfStringInTextInput(NSObject<UITextInput> *textContainer)
{
UITextPosition *beginningOfDocument = [textContainer beginningOfDocument];
UITextPosition *endOfDocument = [textContainer endOfDocument];
UITextRange *fullTextRange = [textContainer textRangeFromPosition:beginningOfDocument
toPosition:endOfDocument];
return [textContainer textInRange:fullTextRange].length;
}
By changing the return type to NSString and removing .length you could have the functionality of the text property on any class.