UITextView insert text in the textview text - iphone

I want to have to occasionally insert text into the UITextView text object. For example, if the user presses the "New Paragraph" button I would like to insert a double newline instead of just the standard single newline.
How can I go about such? Do i have to read the string from UITextView, mutate it, and write it back? Then how would I know where the pointer was?
Thanks

Since the text property of UITextView is immutable, you have to create a new string and set the text property to it. NSString has an instance method (-stringByAppendingString:) for creating a new string by appending the argument to the receiver:
textView.text = [textView.text stringByAppendingString:#"\n\n"];

UITextview has an insertText method and it respects cursor position.
- (void)insertText:(NSString *)text
for example:
[myTextView insertText:#"\n\n"];

Here's how I implemented it and it seems to work nicely.
- (void) insertString: (NSString *) insertingString intoTextView: (UITextView *) textView
{
NSRange range = textView.selectedRange;
NSString * firstHalfString = [textView.text substringToIndex:range.location];
NSString * secondHalfString = [textView.text substringFromIndex: range.location];
textView.scrollEnabled = NO; // turn off scrolling or you'll get dizzy ... I promise
textView.text = [NSString stringWithFormat: #"%#%#%#",
firstHalfString,
insertingString,
secondHalfString];
range.location += [insertingString length];
textView.selectedRange = range;
textView.scrollEnabled = YES; // turn scrolling back on.
}

For Swift 3.0
You can append text by calling method insertText of UITextView Instance.
Example:
textView.insertText("yourText")

This is a correct answer!
The cursor position is also right.
A scroll position is also right.
- (void) insertString: (NSString *) insertingString intoTextView: (UITextView *) textView
{
[textView replaceRange:textView.selectedTextRange withText:insertingString];
}

- (void)insertStringAtCaret:(NSString*)string {
UITextView *textView = self.contentCell.textView;
NSRange selectedRange = textView.selectedRange;
UITextRange *textRange = [textView textRangeFromPosition:textView.selectedTextRange.start toPosition:textView.selectedTextRange.start];
[textView replaceRange:textRange withText:string];
[textView setSelectedRange:NSMakeRange(selectedRange.location + 1, 0)];
self.changesDetected = YES; // i analyze the undo manager in here to enabled/disable my undo/redo buttons
}

Related

Is it possible to highlight a NSString or draw some color to a string

i am having this code to get the text between "." for example i am having lots of text like .1 this is first.2 this is second.3 this is fourth etc etc.when i tap the first ext it displays the first text in log .the code is
- (void)textViewDidBeginEditing:(UITextView *)textView
{
[NSTimer scheduledTimerWithTimeInterval:0.001 target:maintextview selector:#selector(resignFirstResponder) userInfo:nil repeats:NO];
}
- (void)textViewDidEndEditing:(UITextView *)textView
{
NSRange selectedRange = [textView selectedRange];
NSString *backString = [maintextview.text substringToIndex:selectedRange.location];
NSRange backRange = [backString rangeOfString:#"." options:NSBackwardsSearch];
NSRange backRangee = [backString rangeOfString:#"." options:NSBackwardsSearch];
int myRangeLenght = backRangee.location - backRange.location;
NSRange myStringRange = NSMakeRange (backRange.location, myRangeLenght);
NSString *forwardString = [maintextview.text substringFromIndex:backRange.location];
NSLog(#"%#",[[forwardString componentsSeparatedByString:#"."] objectAtIndex:1]);
}
forwadString contains the tapped text,i just want to highlight this string or draw a color above this text using core graphics or something like that.is out possible?
thanks in advance
Much to my and many other's disappointment, Apple chose not to implement NSAttributedString until iOS 3.2, and even then, all standard UI elements are incapable of rendering them!
Luckily, the few, the proud, and the brave have answered the call and DTCoreText was born.
As for an actual selection, because UITextView conforms to UITextInput as of iOS 3.2, you can use and set the selectedTextRange.
It's impossible to 'colour' an NSString, a string is just a representation of characters, it holds no font, colour or style properties. Instead you need to colour the UI element that draws the text to the screen.
If forwardString is in a UILabel or UITextView you can colour the text inside these by setting the textColor property. For example if you had a UILabel called lbl you could set the colour by using:
lbl.textColor = [UIColor redColor];

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!)
}

Adding an uneditable text suffix to a UITextField

I have a UITextField that I'd like to add a "?" suffix to all text entered.
The user should not be able to remove this "?" or add text to the right hand side of it.
What's the best way to go about this?
Use the UITextFieldDelegate protocol to alter the string whenever the field is being edited. Here's a quick stab at it; this will need work, but it should get you started.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString * currentText = [textField text];
if( [currentText characterAtIndex:[currentText length] - 1] != '?' ){
NSMutableString * newText = [NSMutableString stringWithString:currentText];
[newText replaceCharactersInRange:range withString:string];
[newText appendString:#"?"];
[textField setText:newText];
// We've already made the replacement
return NO;
}
// Allow the text field to handle the replacement
return YES;
}
You'll probably need to subclass UITextField and override its drawText: method to draw an additional "?" character to the right of the actual text. (Rather than actually add a "?" to the text of the view.
I had this issue and I wrote a subclass to add this functionality: https://github.com/sbaumgarten/UIPlaceholderSuffixField.
Hopefully you have found a solution by now but if you haven't, this should work.
I realize this answer is late, but I found most of these did not work for my scenario. I have a UITextField that I simply want to force to have a suffix that the user cannot edit. However, I don't want to subclass UITextView, modify how it handles drawing, etc. I just want to prevent the user from modifying the suffix.
First, I ensure the suffix is set in the textfield when editing takes place. This could be done any number of ways depending upon your scenario. For mine, I wanted it there from the start, so I simply set the textfield's text property equal to the suffix when the view loads and store off the length of the suffix for later. For example:
- (void)viewDidLoad {
[super viewDidLoad];
myTextField.text = "suffix";
_suffixLength = myTextField.text.length;
}
Then I used the UITextFieldDelegate protocol as Josh suggested above, but use the length of the string and the range to ensure nothing edits the suffix:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
// Determine starting location of the suffix in the current string
int suffixLocation = textField.text.length - _suffixLength;
// Do not allow replacing anything in/past the suffix
if (range.location + range.length > suffixLocation)
{
return NO;
}
// Continue with delegate code...
}
This should work for any suffix value you assign to the textfield.
For a single-line UITextField you should be able to measure the size of the NSString (it has a measurement function in there, somewhere) and move a UILabel to the right position.
I would add a method that is called when edit finishes:
`- (void)editDidFinish {
NSString* str=[[NSString alloc] init];
str=myEdit.text;
[str stringByAppendingString:#"?"];
myEdit.text=str;
}`
OK, im definitly too late, but maybe i can help someone out either way:
The intended way to accomplish this is by using a custom NSFormatter. Heres the docs:
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSFormatter_Class/Reference/Reference.html
The basic idea is this: you create a subclass of NSFormatter, and the override at least the two worker methods:
-stringObjectForValue:
this will produce the dipsplay-String from the value stored in the object (i.e. add your questionmark here)
-objectValue:ForString:errorDescription
here, you need to transform the display-string into an object you want to store, i.e. remove the questionmark
The formatter can then be used to convert the data from the stored objects into strings that are suitable for presentation to the user.
The big advantage is that you can use formatters wherever your string will appear in the UI. It is not limited to certain UI-Elements like the solution where you override -drawText in UITextField. Its just hella convenient.
This class method I have written in Objective-C, helps you to add a suffix text to a UITextField.
I order to make it work, you need to initialize the UILabel to the prefix or suffix in your UITextFieldLabel as follow:
myTextField.rightView = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 0.0f, myTextField.frame.size.height)];
myTextField.rightViewMode = UITextFieldViewModeAlways;
[MyClass UpdateUITextFieldSuffix:myTextField withString:#"My Suffix!"];
Once we have the UILabel attached to the UITextField, you can use this class method to update the text, and this text will be automatically resized to fit in the field.
+ (BOOL)UpdateUITextFieldSuffix:(UITextField*)textField withString:(NSString*)string
{
BOOL returnUpdateSuffix = NO;
if (string != nil && [string respondsToSelector:#selector(length)] && [string length] > 0)
{
NSObject *labelSuffix = textField.rightView;
if (labelSuffix != nil && [labelSuffix respondsToSelector:#selector(setText:)])
{
[(UILabel*)labelSuffix setTextAlignment:NSTextAlignmentRight];
[(UILabel*)labelSuffix setText:string];
[(UILabel*)labelSuffix setBackgroundColor:[UIColor redColor]];
{
NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
((UILabel*)labelSuffix).font, NSFontAttributeName,nil];
CGRect frame = [((UILabel*)labelSuffix).text boundingRectWithSize:CGSizeMake(0.0f, CGFLOAT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributesDictionary
context:nil];
CGSize size = frame.size;
CGRect newFrame = [(UILabel*)labelSuffix frame];
newFrame.size.width = size.width;
[(UILabel*)labelSuffix setFrame:newFrame];
[(UILabel*)labelSuffix setNeedsLayout];
[(UILabel*)labelSuffix layoutIfNeeded];
}
returnUpdateSuffix = YES;
}
}
return returnUpdateSuffix;
}
I have written the following method to achieve the above task of placing non-editable suffix to UITextField:
- (void)setSuffixText:(NSString *)suffix
{
UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
[label setBackgroundColor:[UIColor clearColor]];
[label setFont:[UIFont fontWithName:self.tfdDistance.font.fontName size:self.tfdDistance.font.pointSize]];
[label setTextColor:self.tfdDistance.textColor];
[label setAlpha:.5];
[label setText:suffix];
CGSize suffixSize = [suffix sizeWithFont:label.font];
label.frame = CGRectMake(0, 0, suffixSize.width, self.tfdDistance.frame.size.height);
[self.tfdDistance setRightView:label];
[self.tfdDistance setRightViewMode:UITextFieldViewModeAlways];
}​

Weird UITextView behavior

I have a UITextView which i create in the code:
myView = [[UITextView alloc] initWithFrame:CGRectMake(10,5,220,50)];
myView.editable = YES;
myView.font = [UIFont fontWithName:#"Helvetica" size:16];
myView.bounces = NO;
myView.delegate = self;
I set UIView *myView in the header as well..
and also set delegate - UIViewController UITextViewDelegate>
I want to hide a label every time the user writes a text
for that i check if its equal to 0, else its hide.
the problem is in this method -
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if(textView.text.length == 0)
descLabel.hidden = NO;
else
descLabel.hidden = YES;
return YES;
}
the program runs but when i enter the first letter the label still there,
and when i enter the second letter it goes as it should. then i delete those two and its still gone! (reminder: i want the label to be hidden when the length is 0) but when i press on the delete again i can see the label. Pretty weird..
I want to have the behavior of a placeholder in UITextView but this problem annoying
Thanks for your help!
You are checking the textView.text value before the change; you presumably want to check the length after the update would be applied.
e.g.:
NSString *newString = [textView.text stringByReplacingCharactersInRange:range withString:text];

UIKeyboard turn Caps Lock on

I need my user to input some data like DF-DJSL so I put this in the code:
theTextField.autocapitalizationType = UITextAutocapitalizationTypeAllCharacters;
But unfortunately what happens is the first to letter type in CAPS but then letter immediately after typing the hyphen will be in lower case and then the rest return to CAPS therefore producing output like this (unless the user manually taps the shift button after typing a hyphen): DF-dJSL
How can I fix this?
Many Thanks
You don't mention which SDK you're using, but against 3.0 and above I see your desired behaviour.
That said, you could always change the text to upper case when they finish editing using the textFieldDidEndEditing method from the delegate:
- (void)textFieldDidEndEditing:(UITextField *)textField {
NSString *textToUpper = [textField.text uppercaseString];
[theTextField setText:textToUpper];
}
Or, by setting up a notification on the textfield when it changes, you could change the text as it is being typed:
// setup the UITextField
{
theTextField.delegate = self;
theTextField.autocapitalizationType = UITextAutocapitalizationTypeAllCharacters;
[theTextField addTarget:self action:#selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
}
You have to do it this way since, unlike UISearchBar, UITextField doesn't implement textDidChange. Something like this, perhaps?
- (void)textFieldDidChange:(UITextField *)textField {
NSRange range = [textField.text rangeOfString : #"-"];
if (range.location != NSNotFound) {
theTextField.autocapitalizationType = UITextAutocapitalizationTypeAllCharacters;
}
}