UITextView lineSpacing causes different cursor height inbetween paragraph lines
Asked Answered
H

2

28

I'm using NSMutableParagraphStyle in my UITextview for adding linespace between each row text.

When I type something in textview, cursor height is normal. but when I move cursor position to text on the 2nd row (not the last row), cursor height is getting bigger.

big caret

What should I do to make cursor height normal in every row of the texts? This is code I'm currently using:

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineSpacing = 30.;
textView.font = [UIFont fontWithName:@"Helvetica" size:16];
textView.attributedText = [[NSAttributedString alloc] initWithString:@"My Text" attributes:@{NSParagraphStyleAttributeName : paragraphStyle}];
Histoid answered 26/11, 2013 at 3:28 Comment(0)
H
39

Finally I found a solution that solve my problem.

Changing the cursor height is possible by subclassing the UITextView, then overriding the caretRectForPosition:position function. For example:

- (CGRect)caretRectForPosition:(UITextPosition *)position {
    CGRect originalRect = [super caretRectForPosition:position];
    originalRect.size.height = 18.0;
    return originalRect;
}

Documentation link: https://developer.apple.com/documentation/uikit/uitextinput/1614518-caretrectforposition


Update: Swift 2.x or Swift 3.x

See Nate's answer.


Update: Swift 4.x or Swift 5.x

For Swift 4.x use caretRect(for position: UITextPosition) -> CGRect.

import UIKit

class MyTextView: UITextView {

    override func caretRect(for position: UITextPosition) -> CGRect {
        var superRect = super.caretRect(for: position)
        guard let font = self.font else { return superRect }

        // "descender" is expressed as a negative value, 
        // so to add its height you must subtract its value
        superRect.size.height = font.pointSize - font.descender 
        return superRect
    }
}

Documentation link: https://developer.apple.com/documentation/uikit/uitextinput/1614518-caretrect

Histoid answered 1/12, 2013 at 11:30 Comment(2)
Is this a documented method? (EDIT: Yes, it's in the UITextInput protocol which UITextView conforms to (developer.apple.com/library/prerelease/ios/documentation/UIKit/…).Gittens
When selecting this text the handles are really Big, any idea how to fix it?Daimyo
D
11

And for Swift 2.x or Swift 3.x:

import UIKit

class MyTextView : UITextView {
    override func caretRectForPosition(position: UITextPosition) -> CGRect {
        var superRect = super.caretRectForPosition(position)
        guard let isFont = self.font else { return superRect }

        superRect.size.height = isFont.pointSize - isFont.descender 
            // "descender" is expressed as a negative value, 
            // so to add its height you must subtract its value

        return superRect
    }
}
Demolition answered 30/12, 2015 at 21:54 Comment(1)
Swift 4 changes caretRectForPosition(position: UITextPosition) to: caretRect(for position: UITextPosition)Reinaldoreinaldos

© 2022 - 2024 — McMap. All rights reserved.