Detect moment when newline starts in UITextView
This is how I would do it:
- Get the
UITextPosition
of the last character. - Call
caretRectForPosition
on yourUITextView
. - Create a
CGRect
variable and initially storeCGRectZero
in it. - In your
textViewDidChange:
method, callcaretRectForPosition:
by passing theUITextPosition
. - Compare it with the current value stored in the
CGRect
variable. If the new y-origin of the caretRect is greater than the last one, it means a new line has been reached.
Sample code:
CGRect previousRect = CGRectZero;
- (void)textViewDidChange:(UITextView *)textView{
UITextPosition* pos = yourTextView.endOfDocument;//explore others like beginningOfDocument if you want to customize the behaviour
CGRect currentRect = [yourTextView caretRectForPosition:pos];
if (currentRect.origin.y > previousRect.origin.y){
//new line reached, write your code
}
previousRect = currentRect;
}
Also, you should read the documentation for UITextInput
protocol reference here. It is magical, I'm telling you.
Let me know if you have any other issues with this.
UITextView (editing) - detecting that next line event occured
Will detect line changes from anything to hitting "return", backspacing to reduce line-count, typing till the end of the line and a word-wrap occurs, etc. (*Note: MUST adjust variables for font size, I recommend not using hard coded numbers like in my example below).
previousNumberOfLines = ((hiddenText.contentSize.height-37+21)/(21));//numbers will change according to font size
NSLog(@"%i", previousNumberOfLines);
Detect new-line character for auto enter new line text on UITextView on iOS
The UITextView
doesn't automatically enter a newline character once its text reaches the end of the line -- it simply wraps around with a line break. But if you want a string representation of the UITextView
text which includes newline characters to indicate the various line breaks, try this:
// This method takes in the `UITextView` and returns the string
// representation which includes the newline characters
- (NSString*)textViewWithNewLines:(UITextView*)textView {
// Create a variable to store the new string
NSString *stringWithNewlines = @"";
// Get the height of line one and store it in
// a variable representing the height of the current
// line
int currentLineHeight = textView.font.lineHeight;
// Go through the text view character by character
for (int i = 0 ; i < textView.text.length ; i ++) {
// Place the cursor at the current character
textView.selectedRange = NSMakeRange(i, 0);
// And use the cursor position to help calculate
// the current line height within the text view
CGPoint cursorPosition = [textView caretRectForPosition:textView.selectedTextRange.start].origin;
// If the y value of the cursor is greater than
// the currentLineHeight, we've moved onto the next line
if (cursorPosition.y > currentLineHeight) {
// Increment the currentLineHeight such that it's
// set to the height of the next line
currentLineHeight += textView.font.lineHeight;
// If there isn't a user inputted newline already,
// add a newline character to reflect the new line.
if (textView.text.length > i - 1 &&
[textView.text characterAtIndex:i-1] != '\n') {
stringWithNewlines = [stringWithNewlines stringByAppendingString:@"\n"];
}
// Then add the character to the stringWithNewlines variable
stringWithNewlines = [stringWithNewlines stringByAppendingString:[textView.text substringWithRange:NSMakeRange(i, 1)]];
} else {
// If the character is still on the "current line" simply
// add the character to the stringWithNewlines variable
stringWithNewlines = [stringWithNewlines stringByAppendingString:[textView.text substringWithRange:NSMakeRange(i, 1)]];
}
}
// Return the string representation of the text view
// now containing the newlines
return stringWithNewlines;
}
Swift 3 - Detecting new lines in UITextView
I solved the problem by myself, I will post the code below if someone need it (check comments in the code):
func textViewDidChange(_ textView: UITextView) {
let pos = textView.endOfDocument
let currentRect = textView.caretRect(for: pos)
if previousRect != CGRect.zero {
if currentRect.origin.y > previousRect.origin.y {
// Array of Strings
var currentLines = textView.text.components(separatedBy: "\n")
// Remove Blank Strings
currentLines = currentLines.filter{ $0 != "" }
//increase the counter counting how many items inside the array
counter = currentLines.count
}
}
previousRect = currentRect
}
UITextView/NSAttribute: Detect if word starts with a particular symbol
Assuming you keep #
or @
in the text, you can modify the answer in Larme's comment:
let regex = try! NSRegularExpression(pattern: "(?:#|@)\\w+", options: [])
func textViewDidChange(_ textView: UITextView) {
let attrStr = NSMutableAttributedString(attributedString: textView.attributedText ?? NSAttributedString())
let plainStr = attrStr.string
attrStr.addAttribute(.foregroundColor, value: UIColor.black, range: NSRange(0..<plainStr.utf16.count))
let matches = regex.matches(in: plainStr, range: NSRange(0..<plainStr.utf16.count))
for match in matches {
let nsRange = match.range
let matchStr = plainStr[Range(nsRange, in: plainStr)!]
let color: UIColor
if matchStr.hasPrefix("#") {
color = .red
} else {
color = .blue
}
attrStr.addAttribute(.foregroundColor, value: color, range: nsRange)
}
textView.attributedText = attrStr
}
I just have changed the pattern, adapted to Swift 4.1, fixed some bugs, removed some redundant codes and added some code to change colors.
Obj-C- Detecting textView line break?
Im not sure if this is gonna help at all since im also fairly new to obj-c but give it a go
-(void)textViewDidChange:(UITextView *)textView
{
CGFloat fixedWidth = textView.frame.size.width;
CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
CGRect newFrame = textView.frame;
newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth),
newSize.height);
textView.frame = newFrame;
}
Make sure you also disable scrolling
textview.scrollEnabled = NO;
Detect when a line break has been erased inside a UITextView - Objective C
Implement the delegate
-(BOOL)textView:shouldChangeTextInRange:replacementText:
If a delete occurs, you will have replacementText with length 0, and you can look at the textView.text at range to see what was deleted:
[textView.text substringWithRange:range]
Replace all line breaks with a space in a UITextView
You can use UITextViewDelegate
's textViewDidChange(_:)
method to listen whenever the text view's text changes. Inside here, you can then replace all occurrences of a newline (\n
) with an empty String (""
).
class ViewController: UIViewController {
@IBOutlet weak var textView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
textView.delegate = self
}
}
extension ViewController: UITextViewDelegate {
func textViewDidChange(_ textView: UITextView) {
let text = textView.text.replacingOccurrences(of: "\n", with: "")
textView.text = text
}
}
Without textViewDidChange(_:) | With textViewDidChange(_:) |
---|---|
In UITextView, how to get the point that next input will begin another line
In this delegate method of the UITextView, this code will count the number of lines each time the text field is changed :
-(void)textViewDidChange:(UITextView *)textView
{
UIFont *font = [UIFont boldSystemFontOfSize:11.0];
CGSize size = [string sizeWithFont:font
constrainedToSize:myUITextView.frame.size
lineBreakMode:UILineBreakModeWordWrap]; // default mode
float numberOfLines = size.height / font.lineHeight;
}
Related Topics
It Gives Errors When Using Swift Static Library with Objective-C Project
Invalid Redeclaration in Auto Code Generate Nsmanagedobject Subclass Swift 3
How to Retrieve Messages Logged with Os_Log from iPad/Iphone
What's Currently the "Correct" Way to Set a Uiview's Corner Radius
How to Set the Tab Order in iOS
How to Wait for Method That Has Completion Block (All on Main Thread)
Apple Watch, Watchkit Extension and Main Application
Using Apple's Reachability to Check Remote Server Reachability in Swift
How to Draw Inside the Black Edges in iOS Sdk with Opengl Es
How to Properly Set Uirequireddevicecapabilities
How Should a Swift + Objective-C Project Be Setup for Unit Testing
Where to Place a .Txt File and Read from It in a iOS Project
How to Use Coreaudio's Audioconverter to Encode Aac in Real-Time
Push/Pop View Controller with Navigation Bar from View Controller Without Navigation Bar
Unknown Class in Interface Builder
"Can't Find Model for Source Store" Occurring During iPhone "Automatic Lightweight Migration"
Get Current View Controller from the App Delegate (Modal Is Possible)