iOS: Highlight spelling errors but disable suggestions? - iphone

My app implements a custom spell checker with its own window and a different workflow from the built-in spell checker in iOS. Therefore I have switched off correction in the main text input view. This disables the built-in suggestions, but also the highlighting of misspelled words.
Is there a way to keep the highlighting, but disable the suggestions?

You can use below code to check weather the printed word is correct spelled or not and if wrong then highlight that word
first import
#import <UIKit/UITextChecker.h>
in your file
-(BOOL)isDictionaryWord:(NSString*)word {
UITextChecker *checker = [[UITextChecker alloc] init];
NSLocale *currentLocale = [NSLocale currentLocale];
NSString *currentLanguage = [currentLocale objectForKey:NSLocaleLanguageCode];
NSRange searchRange = NSMakeRange(0, [word length]);
NSRange misspelledRange = [checker rangeOfMisspelledWordInString:word range: searchRange
startingAt:0 wrap:NO language: currentLanguage ];
return misspelledRange.location == NSNotFound;
}

You will have to roll your own. Here's a rough (iOS 5 and later):
Drop a view with transparent background on top of the text view.
Find the visible range of text like so:
- (NSRange)visibleRangeOfTextView:(UITextView *)textView {
CGRect bounds = textView.bounds;
UITextPosition *start = [textView characterRangeAtPoint:bounds.origin].start;
UITextPosition *end = [textView characterRangeAtPoint:CGPointMake(CGRectGetMaxX(bounds), CGRectGetMaxY(bounds))].end;
return NSMakeRange([textView offsetFromPosition:textView.beginningOfDocument toPosition:start],
[textView offsetFromPosition:start toPosition:end]);
}
Search for misspelled words in that range.
Find their on-screen coordinates using UITextView firstRectForRange method.
Highlight any way you want.
Deciding when to do this is left as an exercise for the eager student :)

Related

How do I truncate a string within a string in a UILabel?

Say I have The Dark Knight Rises at 7:45pm and I need to fit that into a fixed-width UILabel (for iPhone). How would I make that truncate as "The Dark Knight Ris... at 7:45pm" rather than "The Dark Knight Rises at 7:4..."?
UILabel has this property:
#property(nonatomic) NSLineBreakMode lineBreakMode;
You enable that behaviour by setting it to NSLineBreakByTruncatingMiddle.
EDIT
I din't understand that you wanted to truncate only a part of the string.Then read this:
If you want to apply the line break mode to only a portion of the text, create a new attributed string with the desired style information and associate it with the label. If you are not using styled text, this property applies to the entire text string in the text property.
Example
So there is even a class for setting the paragraph style: NSParagraphStyle and it has also it's mutable version.
So let's say that you have a range where you want to apply that attribute:
NSRange range=NSMakeRange(i,j);
You have to create a NSMutableParagraphStyle object and set it's lineBreakMode to NSLineBreakByTruncatingMiddle.Notice that you may set also a lot of other parameters.So let's do that:
NSMutableParagraphStyle* style= [NSMutableParagraphStyle new];
style.lineBreakMode= NSLineBreakByTruncatingMiddle;
Then add that attribute for the attributedText of the label in that range.The attributedText property is a NSAttributedString, and not a NSMutableAttributedString, so you'll have to create a NSMutableAttributedString and assign it to that property:
NSMutableAttributedString* str=[[NSMutableAttributedString alloc]initWithString: self.label.text];
[str addAttribute: NSParagraphStyleAttributeName value: style range: range];
self.label.attributedText= str;
Notice that there are a lot of other properties for a NSAttributedString, check here.
You have to set the lineBreakMode. You can either do that from Interface Builder or programmatically as follows
label.lineBreakMode = NSLineBreakByTruncatingMiddle;
please note that since iOS 5 the type of such property changed from UILineBreakMode to NSLineBreakMode.
My first idea would be two labels side-by-side both with fixed width, but I'll assume you've ruled that out for some unstated reason. Alternatively, compute the truncation manually, like this ...
- (NSString *)truncatedStringFrom:(NSString *)string toFit:(UILabel *)label
atPixel:(CGFloat)pixel atPhrase:(NSString *)substring {
// truncate the part of string before substring until it fits pixel
// width in label
NSArray *components = [string componentsSeparatedByString:substring];
NSString *firstComponent = [components objectAtIndex:0];
CGSize size = [firstComponent sizeWithFont:label.font];
NSString *truncatedFirstComponent = firstComponent;
while (size.width > pixel) {
firstComponent = [firstComponent substringToIndex:[firstComponent length] - 1];
truncatedFirstComponent = [firstComponent stringByAppendingString:#"..."];
size = [truncatedFirstComponent sizeWithFont:label.font];
}
NSArray *newComponents = [NSArray arrayWithObjects:truncatedFirstComponent, [components lastObject], nil];
return [newComponents componentsJoinedByString:substring];
}
Call it like this:
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 160, 21)];
NSString *string = #"The Dark Knight Rises at 7:45pm";
NSString *substring = #"at";
CGFloat pix = 120.0;
NSString *result = [self truncatedStringFrom:string toFit:label atPixel:120.0 atPhrase:#"at"];
label.text = result;
This generates: #"The Dark Kni...at 7:45pm"

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

How to find the location of the cursor in a UITextView

I want to get the current position of cursor when I first click on a UITextView that contains some text.
I believe the UITextView selectedRange property should provide what you're after.
you could use UITextView's selectedRange to return the insertion point pf text.
The below code shows how to it.
NSString *contentsToAdd = #"some string";
NSRange cursorPosition = [tf selectedRange];
NSMutableString *tfContent = [[NSMutableString alloc] initWithString:[tf text]];
[tfContent insertString:contentsToAdd atIndex:cursorPosition.location];
[theTextField setText:tfContent];
[tfContent release];
for More to read the SO Post
Getting cursor position in a UITextView on the iPhone?
Also read the same on Apple discussion forum.
http://discussions.apple.com/thread.jspa?messageID=9940169

UITextView insert text in the textview text

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
}