strawtarget
strawtarget

Reputation: 1069

How to set margins (padding) in UITextView?

I have a UITextView for text editing. By default, it has a small margin around the text. I want to increase that margin by a few pixels.

The contentInset property gives me margins, but it does not change the text "wrap width". The text is wrapped at the same width, and the extra "margin" just causes the view to scroll horizontally.

Is there a way to make a UITextView of a certain width display the text with a narrower "wrap width"?

Upvotes: 58

Views: 55499

Answers (9)

Pankaj Jangid
Pankaj Jangid

Reputation: 832

if you want to set padding from one side, you can use below code:

 textView.contentInset.left = 5 //For left padding
 textView.contentInset.right = 5 //For right padding
 textView.contentInset.top = 5 //For top padding
 textView.contentInset.bottom = 5 //For bottom padding

Upvotes: 3

Baran
Baran

Reputation: 2820

Swift + iOS 12: A different approach

Setting padding to the left + right side of our UITextView did let the text disappear when entered more that 9 lines of text. Using the solution of @rajesh helped to solve this issue:

Make sure to invoke the method whenever text did change + the device rotates.

    /// Updates the left + right padding of the current text view.
    /// -> leftRightPadding value = 11.0
    func updateLeftRightPadding() {
        let leftPadding = UIBezierPath(rect: .init(x: 0.0, y: 0.0,
                                       width: leftRightPadding, height: contentSize.height))
        let rightPadding = UIBezierPath(rect: .init(x: frame.width - leftRightPadding, y: 0.0,
                                        width: 11, height: contentSize.height))
        textContainer.exclusionPaths = [leftPadding, rightPadding]
    }

Upvotes: 0

Rajesh Dharani
Rajesh Dharani

Reputation: 285

Try below code

For iOS7 use textContainerInset

textView.textContainerInset = UIEdgeInsetsMake(0, 20, 0, 20);

Check below link it might be useful to you

https://stackoverflow.com/a/22935404/5184217

Upvotes: 1

Karlis
Karlis

Reputation: 1910

Starting from iOS 7 you can use textContainerInset property:

Objective-C

textView.textContainerInset = UIEdgeInsetsMake(0, 20, 0, 20);

Swift

textView.textContainerInset = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)

Upvotes: 122

Michael Andersen
Michael Andersen

Reputation: 20

Thanks for the suggestions. I had this problem when developing a macOS / OSX app and ended up with this:

textView.textContainerInset = NSSize(width: 20, height: 20); //Sets margins

Upvotes: 1

Rajesh
Rajesh

Reputation: 960

Try this

UIBezierPath* aObjBezierPath = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 20, 20)];
txtView.textContainer.exclusionPaths  = @[aObjBezierPath];

Upvotes: 10

After fiddling around with this for a while I found another solution if you're only developing for iOS 6. Set the top and bottom margins with contentInset:

textView = [[UITextView alloc] init];
textView.contentInset = UIEdgeInsetsMake(20.0, 0.0, 20.0, 0.0);

For the left and right margins don't add your plain text right away but use an NSAttributedString instead with properly set left and right indents with an NSMutableParagraphStyle:

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.headIndent = 20.0;
paragraphStyle.firstLineHeadIndent = 20.0;
paragraphStyle.tailIndent = -20.0;

NSDictionary *attrsDictionary = @{NSFontAttributeName: [UIFont fontWithName:@"TrebuchetMS" size:12.0], NSParagraphStyleAttributeName: paragraphStyle};
textView.attributedText = [[NSAttributedString alloc] initWithString:myText attributes:attrsDictionary];

This gives you a UITextView with your text (in my case from the variable myText) with 20 pixels padding that properly scrolls.

Upvotes: 35

Nate Potter
Nate Potter

Reputation: 3222

This is working for me. Changing the textView contentInset and frame inset/position to get the correct padding and word wrap. Then changing the textView bounds to prevent horizontal scrolling. You also need to reset the padding each time the text is selected and changed.

- (void)setPadding
{
    UIEdgeInsets padding = UIEdgeInsetsMake(30, 20, 15, 50);

    textView.contentInset = padding;

    CGRect frame = textView.frame;

    // must change frame before bounds because the text wrap is reformatted based on frame, don't include the top and bottom insets
    CGRect insetFrame = UIEdgeInsetsInsetRect(frame, UIEdgeInsetsMake(0, padding.left, 0, padding.right));

    // offset frame back to original x
    CGFloat offsetX = frame.origin.x - (insetFrame.origin.x - ( padding.left + padding.right ) / 2);
    insetFrame = CGRectApplyAffineTransform(insetFrame, CGAffineTransformMakeTranslation(offsetX, 0));

    textView.frame = insetFrame;

    textView.bounds = UIEdgeInsetsInsetRect(textView.bounds, UIEdgeInsetsMake(0, -padding.left, 0, -padding.right));

    [textView scrollRectToVisible:CGRectMake(0,0,1,1) animated:NO];
}

-(void)textViewDidChangeSelection:(UITextView *)textView
{
    [self setPadding];
}

-(void)textViewDidChange:(UITextView *)textView
{
    [self setPadding];
}

Upvotes: 1

kennytm
kennytm

Reputation: 523294

You could just use a smaller UITextView, and place a UIView in the background to simulate the padding.

+----------+
|          | <-- UIView (as background)
|   +--+   |
|   |  | <---- UITextView
|   |  |   |
|   +--+   |
|          |
+----------+

Upvotes: 7

Related Questions