UITextView text selection and highlight jumping in iOS 8
I ended up solving my problem like this, and if someone else has a more elegant solution please let me know:
- (void)viewDidLoad {
[super viewDidLoad];
UIMenuItem *highlightMenuItem = [[UIMenuItem alloc] initWithTitle:@"Highlight" action:@selector(highlight)];
[[UIMenuController sharedMenuController] setMenuItems:[NSArray arrayWithObject:highlightMenuItem]];
float sysVer = [[[UIDevice currentDevice] systemVersion] floatValue];
if (sysVer >= 8.0) {
self.textView.layoutManager.allowsNonContiguousLayout = NO;
}
}
- (void)highlight {
NSRange selectedTextRange = self.textView.selectedRange;
[attributedString addAttribute:NSBackgroundColorAttributeName
value:[UIColor redColor]
range:selectedTextRange];
float sysVer = [[[UIDevice currentDevice] systemVersion] floatValue];
if (sysVer < 8.0) {
// iOS 7 fix
self.textView.scrollEnabled = NO;
self.textView.attributedText = attributedString;
self.textView.scrollEnabled = YES;
} else {
self.textView.attributedText = attributedString;
}
}
Is it possible to change selection color in UITextView iOS?
Yes, you can change text selection color using tintColor
property of UITextView
.
Use this code to get the expected output.
self.textView.tintColor = .red
Also, You can do this from the storyboard, see the following image.
How to trigger an event when text is highlighted in swift
Assuming you are asking how to get an event when the selection changes in a UITextField, you need to add an observer to the "selectedTextRange" property of UITextField
(from the UITextInput
protocol).
Here is a little example view controller that listens to such events for a text field:
class MyVC: UIViewController {
var textField: UITextField!
@objc override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "selectedTextRange" {
if let tf = object as? UITextField {
// This is our event and text field
if let range = tf.selectedTextRange {
print("Updated selection = \(range)")
}
return
}
}
// This isn't the event or the object we care about, pass it on
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .yellow
textField = UITextField(frame: CGRect(x: 0, y: 0, width: 300, height: 44))
textField.text = "Hello there. How are you?"
// Options is empty because we don't care about the old range and we can get the new range from the text field
textField.addObserver(self, forKeyPath: "selectedTextRange", options: [], context: nil)
view.addSubview(textField)
}
deinit {
textField.removeObserver(self, forKeyPath: "selectedTextRange")
}
}
How to highlight text in a textView in Swift?
If you only need to highlight a single, contiguous block of text you can set the selection programmatically. Your examples show multiple discontinuous parts however. For that you are going to need to use an attributed string. There is no other system-provided highlighting function. (There might be a third party library that offers this though - you'll have to search.)
How to highlight or change color of text within iOS?
In iOS 6 you can do it, because iOS 6 now allows UITextView (as well as UILabel, UIButton etc.) to display styled text (NSAttributedString). You color the word with NSForegroundColorAttributeName
and color its background with NSBackgroundColorAttributeName
and presto, there's your highlight. There are several very good WWDC 2012 videos on this topic.
How to remove yellow selection highlight?
Found out that if I'm setting animate
property to false
it disappears.
pdfView.setCurrentSelection(wordSelection, animate: false)
UITextView starts at Bottom or Middle of the text
That did the trick for me!
Objective C:
[self.textView scrollRangeToVisible:NSMakeRange(0, 0)];
Swift:
self.textView.scrollRangeToVisible(NSMakeRange(0, 0))
Swift 2 (Alternate Solution)
Add this override method to your ViewController
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
textView.setContentOffset(CGPointZero, animated: false)
}
Swift 3 & 4 (syntax edit)
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
textView.contentOffset = .zero
}
highlight a text in textview
It is only doable using CoreText, because it needs formatting attributes and NSAttributedString
to display text with multiple font style and colors.
You may be interested in my OHAttributedLabel
class that is a subclass of UILabel
to render NSAttributedString
(obviously it uses CoreText for this).
As setting the background color of a range of text is not directly possible/supported (no corresponding attribute in NSAttributedString
), you may need to draw the yellow rectangles (before drawing the text) yourself, but I've done this in my class too to manage highlighted links (see drawActiveLinkHighlightForRect:
method) so you may do a similar thing in your case.
Related Topics
Swift Dynamic Table Cell Height
Itms-90809: Deprecated API Usage - Existing App That Use Uiwebview Are No Longer Accepted
Programmatically Highlight Uibarbuttonitem
Simple Uitableview in Swift - Unexpectedly Found Nil
JSON Parsing Using Nsjsonserialization in iOS
How to Write Output of Augraph to a File
Does iPhone Support Hardware-Accelerated Aes Encryption
Get Device Current Orientation (App Extension)
Checking Push Notification Registration: Isregisteredforremotenotifications Not Updating
Ignore Manual Entries from Apple Health App as Data Source
How to Get Assets.Xcassets File Names in an Array (Or Some Data Structure)
Nsdata to Nsstring with JSON Response
Swift 3 - Alamofilre 4.0 Multipart Image Upload with Progress
Get Version Number of iOS Universal Framework in Client
Type 'String.Index' Does Not Conform Protocol 'Integerliteralconvertible'
Ios: Usage of Self and Underscore(_) with Variable
"Invalid Predicate: Nil Rhs" for Second Argument in Nspredicate Format