Swift
textView.text = "Hello, world!"
Objective-C:
textView.text = @"Hello, world!";
// Modify some of the attributes of the attributed string.
let attributedText = NSMutableAttributedString(attributedString: textView.attributedText!)
// Use NSString so the result of rangeOfString is an NSRange.
let text = textView.text! as NSString
// Find the range of each element to modify.
let tintedRange = text.range(of: NSLocalizedString("tinted", comment: ""))
let highlightedRange = text.range(of: NSLocalizedString("highlighted", comment: ""))
// Add tint.
attributedText.addAttribute(NSForegroundColorAttributeName, value: UIColor.blue, range: tintedRange)
// Add highlight.
attributedText.addAttribute(NSBackgroundColorAttributeName, value: UIColor.yellow, range: highlightedRange)
textView.attributedText = attributedText
Swift
textView.textAlignment = .left
Objective-C
textView.textAlignment = NSTextAlignmentLeft;
Responding to Editing Notifications
textViewShouldBeginEditing(_:)
textViewDidBeginEditing(_:)
textViewShouldEndEditing(_:)
textViewDidEndEditing(_:)
Responding to Text Changes
textView(_:shouldChangeTextIn:replacementText:)
textViewDidChange(_:)
Responding to URL
textView(_: UITextView, shouldInteractWithURL: NSURL, inRange: NSRange) -> Bool
Swift
//System Font
textView.font = UIFont.systemFont(ofSize: 12)
//Font of your choosing
textView.font = UIFont(name: "Font Name", size: 12)
Objective-C
//System Font
textView.font = [UIFont systemFontOfSize:12];
//Font of your choosing
textView.font = [UIFont fontWithName:@"Font Name" size:12];
Swift
textView.textColor = UIColor.red
Objective-C
textView.textColor = [UIColor redColor];
NSString *htmlString = @"<p> This is an <b>HTML</b> text</p>";
NSAttributedString *attributedString = [[NSMutableAttributedString alloc]
initWithData: [htmlString dataUsingEncoding:NSUnicodeStringEncoding]
options: @{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType }
documentAttributes: nil
error: nil
];
_yourTextView.attributedText = attributedString;
// If you want to modify the font
field.font = [UIFont fontWithName:@"Raleway-Regular" size:15];
UITextView
has built in support to auto detect a variety of data.
The data that is able to be auto-detected currently includes:
enum {
UIDataDetectorTypePhoneNumber = 1 << 0,
UIDataDetectorTypeLink = 1 << 1,
UIDataDetectorTypeAddress = 1 << 2,
UIDataDetectorTypeCalendarEvent = 1 << 3,
UIDataDetectorTypeNone = 0,
UIDataDetectorTypeAll = NSUIntegerMax
};
// you may add as many as you like by using the `|` operator between options
textView.dataDetectorTypes = (UIDataDetectorTypeLink | UIDataDetectorTypePhoneNumber);
If enabled, the text will appear as a hyperlink on the UITextView
To allow the link to be clicked (which will result in different actions depending on the data type) you must ensure that the UITextView
is selectable but not editable and that user interaction is enabled
textView.editable = NO;
textView.selectable = YES;
textView.userInteractionEnabled = YES; // YES by default
Swift
if let text = self.textView.text where !text.isEmpty {
// Do stuff for text
} else {
// Do stuff for nil text or empty string
}
Objective-C
if (self.textView.text.length > 0){
// Do stuff for text
} else {
// Do stuff for nil text or empty string
}
The very beginning of the text field text:
let startPosition: UITextPosition = textView.beginningOfDocument
The very end of the text field text:
let endPosition: UITextPosition = textView.endOfDocument
The currently selected range:
let selectedRange: UITextRange? = textView.selectedTextRange
if let selectedRange = textView.selectedTextRange {
let cursorPosition = textView.offsetFromPosition(textView.beginningOfDocument, toPosition: selectedRange.start)
print("\(cursorPosition)")
}
In order to set the position, all of these methods are actually setting a range with the same start and end values.
To the beginning
let newPosition = textView.beginningOfDocument
textView.selectedTextRange = textView.textRangeFromPosition(newPosition, toPosition: newPosition)
To the end
let newPosition = textView.endOfDocument
textView.selectedTextRange = textView.textRangeFromPosition(newPosition, toPosition: newPosition)
To one position to the left of the current cursor position
// only if there is a currently selected range
if let selectedRange = textView.selectedTextRange {
// and only if the new position is valid
if let newPosition = textView.positionFromPosition(selectedRange.start, inDirection: UITextLayoutDirection.Left, offset: 1) {
// set the new position
textView.selectedTextRange = textView.textRangeFromPosition(newPosition, toPosition: newPosition)
}
}
To an arbitrary position
Start at the beginning and move 5 characters to the right.
let arbitraryValue: Int = 5
if let newPosition = textView.positionFromPosition(textView.beginningOfDocument, inDirection: UITextLayoutDirection.Right, offset: arbitraryValue) {
textView.selectedTextRange = textView.textRangeFromPosition(newPosition, toPosition: newPosition)
}
Select all text
textView.selectedTextRange = textView.textRangeFromPosition(textView.beginningOfDocument, toPosition: textView.endOfDocument)
Select a range of text
// Range: 3 to 7
let startPosition = textView.positionFromPosition(textView.beginningOfDocument, inDirection: UITextLayoutDirection.Right, offset: 3)
let endPosition = textView.positionFromPosition(textView.beginningOfDocument, inDirection: UITextLayoutDirection.Right, offset: 7)
if startPosition != nil && endPosition != nil {
textView.selectedTextRange = textView.textRangeFromPosition(startPosition!, toPosition: endPosition!)
}
Insert text at the current cursor position
textView.insertText("Hello")
This example originally comes from an adaptation of this Stack Overflow answer.
This answer uses a text field, but the same concepts apply to UITextView
.
Use textView.becomeFirstResponder()
to give focus to the text field and make the keyboard appear.
See this answer for how to get the text at some range.
selectedTextRange
here rather than just selectedRange
)UITextView
has extra paddings by default. Sometimes it's annoying especially if you want to measure some text without view instance and place them at some area precisely.
Do this to remove such paddings.
messageTextView.textContainerInset = UIEdgeInsetsZero
messageTextView.textContainer.lineFragmentPadding = 0
Now you can measure text size using NSAttributedString.boundingRectWithSize(...)
, and resize a UITextView
just to fit it to the text.
let budget = getSomeCGSizeBudget()
let text = getSomeAttributedString()
let textSize = text.boundingRectWithSize(budget, options: [.UsesLineFragmentOrigin, .UsesFontLeading], context: nil).size
messageTextView.frame.size = textSize // Just fits.