iOS5 > app freezes when Editing Changed function is fired on UITextField - ios5

I am firing the following function on "Editing Changed" on a UITextField. The purpose is to format the number as the user types in.
It is working fine on iOS6+ but the app freezes on iOS5 just as the user types the first character in that field. Can somebody help to find out what might be the issue with this 3 line function.
It freezes on the third line where NSNumberFormatter is being used.
-(IBAction)formatNumber:(UITextField*)sender
{
if(sender.text!=NULL)
{
NSCharacterSet *notAllowedChars = [[NSCharacterSet characterSetWithCharactersInString:#"0123456789"] invertedSet];
NSString *currentVal=[[sender.text componentsSeparatedByCharactersInSet:notAllowedChars] componentsJoinedByString:#""];
sender.text=[NSNumberFormatter localizedStringFromNumber:[NSNumber numberWithInt:[currentVal intValue]]
numberStyle:NSNumberFormatterDecimalStyle];
}
}

The problem is that event UIControlEventEditingChanged is called every time something is changed in the sender.
By setting new text:
sender.text=[NSNumberFormatter localizedStringFromNumber:[NSNumber numberWithInt:[currentVal intValue]]
numberStyle:NSNumberFormatterDecimalStyle];
you are actually sending event UIControlEventEditingChanged again and again, causing endless recursion.

Related

Textview with Suggestions List in iOS

I am trying to implement a textView in which when user starts typing(Let's say names) it would show up the suggestions and when they click them it gets added to the textView than user presses comma and again the same functionality for another name....
And at the end the text in the textView should look like this...
Aron,Maria,Alex,Cassie
Can any one suggest me How can I achieve this?
(Its somewhat similar to adding the "Tags" while posting this question!!!)
Thanks.
You can use a NSTokenField replacement there is some libraries here :
tokenField libraries
Following link may help you:
http://www.raywenderlich.com/336/how-to-auto-complete-with-custom-values
Follow the same flow. To get autocomplete suggestions after comma modify the delegate method as found below.
- (BOOL)textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string {
autocompleteTableView.hidden = NO;
NSString *names = [NSString stringWithString:textField.text];
NSArray* arr = [names componentsSeparatedByString:#","];
NSString *subString = [arr lastObject];
substring = [substring
stringByReplacingCharactersInRange:range withString:string];
[self searchAutocompleteEntriesWithSubstring:substring];
return YES;
}
Provide a NSMutableArray named 'allNames' which contains all the names you want to display in the suggestion list and use it as the following:
- (void)searchAutocompleteEntriesWithSubstring:(NSString *)substring {
[autocompleteUrls removeAllObjects];
for(NSString *curString in allNames) {
NSRange substringRange = [curString rangeOfString:substring];
if (substringRange.location == 0) {
[autocompleteUrls addObject:curString];
}
}
[autocompleteTableView reloadData];
}
When the user clicks the suggestions display the name by appending with previously entered names.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// set the textField.text by appending this name to already entered names
}
I didn't see anything like this in mobile app. You can look for libraries. But if you want to make it yourself I would advice you to use invisible tableView. When user starts typing name you should fetchData and show in tableView under textView. It's not hard.
A relatively easy way I can think of to achieve this functionality would be to add an input accessory view to your keyboard, which will offer suggestions.
You wouldn't have to tamper with the TextField itself, nor would you need to incorporate the suggestions into the remainder of your apps layout.
The accessory view could, for example, be given a reference to the textfield and listen to input by:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(textChanged) name:UITextFieldTextDidChangeNotification object:textFieldWithSuggestions];
It would feature a method -(void)textChanged; in which you would have the opportunity to split the existing text into components, using comma or whatever symbol as a separator, and then use the last text fragment to perform your search for possible completions.
It may present these suggestions as a row of buttons for example (maybe even in a side-scrolling scrollview to allow for many suggestions) and if one gets pushed, update the textfields text by replacing the last text segment with the completed string.
To keep track of which button stands for which suggestion, just give them tags according to the indices of your search results. This way, you'll need only one method as a target for the buttons, too.
If you want to some library code then you can go for this
https://github.com/hoteltonight/HTAutocompleteTextField which will help you

iPhone : Textfields and NSNumberFormatter

I am making an app with multiple textfields. I would like when the user enters a number in the textfield, to automatically add the percent symbol when editing ends. Right now, the only way i know how to do that is to convert the text value to float, then use NSNumberFormatterPercentStyle and then send back the value. I guess that there should be a simpler and faster way to do that for multiple textfileds. Does anyone know?
You could use the UITextFieldDelegate's textFieldDidEndEditing: method.
For example:
- (void)textFieldDidEndEditing:(UITextField *)textField {
NSString *oldTextFieldValue = textField.text;
textField.text = [NSString stringWithFormat:#"%# %%",oldTextFieldValue];
}
Note the double "%" in the stringWithFormat: method: this is because a single % on its own is a "format specifier" and will not be taken into account and xcode will give you a warning, so you need to protect it with a second %.

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];
}
}

iphone setting UITextView delegate breaks auto completion

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.

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.