173

I am using a text view as a comment composer.

In the properties inspector I can't find anything like a border style property so that I can make use a rounded rect, something like UITextField.

So, the question is: How can I style a UITextView like a UITextField with a rounded rect?

jcaron
  • 17,302
  • 6
  • 32
  • 46
harshalb
  • 6,012
  • 13
  • 56
  • 92

20 Answers20

284

There is no implicit style that you have to choose, it involves writing a bit of code using the QuartzCore framework:

//first, you
#import <QuartzCore/QuartzCore.h>

//.....

//Here I add a UITextView in code, it will work if it's added in IB too
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(50, 220, 200, 100)];

//To make the border look very close to a UITextField
[textView.layer setBorderColor:[[[UIColor grayColor] colorWithAlphaComponent:0.5] CGColor]];
[textView.layer setBorderWidth:2.0];

//The rounded corner part, where you specify your view's corner radius:
textView.layer.cornerRadius = 5;
textView.clipsToBounds = YES;

It only works on OS 3.0 and above, but I guess now it's the de facto platform anyway.

Hemang
  • 26,840
  • 19
  • 119
  • 186
luvieere
  • 37,065
  • 18
  • 127
  • 179
  • 47
    I found adding the following top the above code makes the border look very close to a UITextField. [textView.layer setBorderColor:[[[UIColor grayColor] colorWithAlphaComponent:0.5] CGColor]]; [textView.layer setBorderWidth:2.0]; – Rob May 27 '11 at 01:01
  • 12
    Make sure to have: #import . I had problems because I didn't import QuartzCore – austen May 31 '11 at 07:05
  • 1
    For n00bs like me, worthy of note: put this code in viewDidLoad NOT in initWithNibName :-) – Brian Colavito Oct 09 '12 at 20:22
  • 1
    You can just use a `UITextField` with the `borderStyle` property set to `UITextBorderStyleRoundedRect` - see my post below. – jowie Jun 06 '13 at 10:23
  • On iOS 7, I find that a border width of 0.5f works much better. – Ethan Holshouser Jan 13 '14 at 23:44
  • borderWidth = 0.5f matches perfect in iOS 7 – MillaresRoo Feb 19 '14 at 21:52
  • 5
    iOS 7 - borderWidth of 1.0 and alpha of .2 works with the default style. – Kalel Wade May 21 '14 at 17:32
  • what does `textField.borderStyle = UITextBorderStyle.roundedRect` do then? What's the difference between that and your way? – mfaani Mar 22 '17 at 14:56
77

this code worked well for me:

    [yourTextView.layer setBackgroundColor: [[UIColor whiteColor] CGColor]];
    [yourTextView.layer setBorderColor: [[UIColor grayColor] CGColor]];
    [yourTextView.layer setBorderWidth: 1.0];
    [yourTextView.layer setCornerRadius:8.0f];
    [yourTextView.layer setMasksToBounds:YES];
hanumanDev
  • 6,592
  • 11
  • 82
  • 146
42

Swift 3 Version

After setting up the text view in interface builder.

@IBOutlet weak var textView: UITextView!

override func viewDidLoad() {
    super.viewDidLoad()
    textView.layer.cornerRadius = 5     
    textView.layer.borderColor = UIColor.gray.withAlphaComponent(0.5).cgColor
    textView.layer.borderWidth = 0.5  
    textView.clipsToBounds = true
}

Swift 2.2 Version

@IBOutlet weak var textView: UITextView!

override func viewDidLoad() {
    super.viewDidLoad()
    textView.layer.cornerRadius = 5     
    textView.layer.borderColor = UIColor.grayColor().colorWithAlphaComponent(0.5).CGColor
    textView.layer.borderWidth = 0.5  
    textView.clipsToBounds = true
}
DevB2F
  • 4,674
  • 4
  • 36
  • 60
Sean McClory
  • 4,195
  • 3
  • 32
  • 35
  • 1
    Problem is that it's not gray exactly. Color of UITextField's frame is a bit different. – Makalele Nov 30 '17 at 09:10
  • 2
    Making .borderWidth = 0.7 makes it look closer to current style I see on iOS 11. – Chris Amelinckx Jul 23 '18 at 13:19
  • Experimented with this a little on iOS14. It actually seems to render slightly differently depending on the model of phone used and does not look the same on iPhone8 vs iPhone11Pro. However as with Chris above, I found borderWidth = 0.7 to be good. In addition I found that colorWithAlphaComponent(0.25) gave a better result – Andy P Nov 27 '20 at 11:47
28

Edit: You have to import

#import <QuartzCore/QuartzCore.h>

for using corner radius.

Try this it will work for sure

UITextView* txtView = [[UITextView alloc] initWithFrame:CGRectMake(50, 50, 300, 100)];
txtView.layer.cornerRadius = 5.0;
txtView.clipsToBounds = YES;

As Rob figured it out setting the if you want the border color to be similar as UITextField then you need to change the border width to 2.0 and color to gray by adding the following line

[textView.layer setBorderColor:[[[UIColor grayColor] colorWithAlphaComponent:0.5] CGColor]]; 
[textView.layer setBorderWidth:2.0];
Venk
  • 5,949
  • 9
  • 41
  • 52
Suresh Varma
  • 9,750
  • 1
  • 60
  • 91
23

I wanted the real deal, so I add UIImageView as a subview of the UITextView. This matches the native border on a UITextField, including the gradient from top to bottom:

textView.backgroundColor = [UIColor clearColor];
UIImageView *borderView = [[UIImageView alloc] initWithFrame: CGRectMake(0, 0, textView.frame.size.width, textView.frame.size.height)];
borderView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
UIImage *textFieldImage = [[UIImage imageNamed:@"TextField.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(15, 8, 15, 8)];
borderView.image = textFieldImage;
[textField addSubview: borderView];
[textField sendSubviewToBack: borderView];

These are the images I use:

enter image description here enter image description here

Venk
  • 5,949
  • 9
  • 41
  • 52
Ben Packard
  • 26,102
  • 25
  • 102
  • 183
12

One solution is to add a UITextField below the UITextView, make the UITextView background transparent and disable any user interaction on the UITextField. Then in code change the UITextField frame with something like that

self.textField.frame = CGRectInset(self.textView.frame, 0, -2);

You will have exactly the same look as a text field.

And as suggested by Jon, you should put this piece of code inside [UIViewController viewDidLayoutSubviews] on iOS 5.0+.

Community
  • 1
  • 1
Phil
  • 2,784
  • 2
  • 28
  • 26
  • 1
    This was so simple and looks exactly how I wanted it to look. I just matched the frame of the UITextField to the UITextView: CGRect frame = self.myTextView.frame; frame.size.height +=2; self.myTextField.frame = frame; – Buyin Brian Mar 12 '13 at 01:40
  • 1
    Lovely answer. Clean and simple. Put code in ```viewDidLayoutSubviews:``` (iOS 5.0+). – Jon May 09 '13 at 16:43
  • 1
    Nice, this was the soln I went with in the end. Note that it did not work until I used Jon's comment re: viewDidLayoutSubviews: – daver Jul 07 '13 at 16:57
  • 1
    This was the quickest, and looks the best. – Weston Nov 29 '13 at 20:47
5

For the best effect you have to use a custom (stretchable) background image. This is also how the UITextField's rounded border is drawn.

Venk
  • 5,949
  • 9
  • 41
  • 52
kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
4

You may want to check out my library called DCKit.

You'd be able to make a rounded corner text view (as well as text field/button/plain UIView) from the Interface Builder directly:

DCKit: bordered UITextView

It also has many other useful features, such as text fields with validation, controls with borders, dashed borders, circle and hairline views etc.

Andrey Gordeev
  • 30,606
  • 13
  • 135
  • 162
4

I know there are already a lot of answers to this one, but I didn't really find any of them sufficient (at least in Swift). I wanted a solution that provided the same exact border as a UITextField (not an approximated one that looks sort of like it looks right now, but one that looks exactly like it and will always look exactly like it). I needed to use a UITextField to back the UITextView for the background, but didn't want to have to create that separately every time.

The solution below is a UITextView that supplies it's own UITextField for the border. This is a trimmed down version of my full solution (which adds "placeholder" support to the UITextView in a similar way) and was posted here: https://stackoverflow.com/a/36561236/1227119

// This class implements a UITextView that has a UITextField behind it, where the 
// UITextField provides the border.
//
class TextView : UITextView, UITextViewDelegate
{
    var textField = TextField();

    required init?(coder: NSCoder)
    {
        fatalError("This class doesn't support NSCoding.")
    }

    override init(frame: CGRect, textContainer: NSTextContainer?)
    {
        super.init(frame: frame, textContainer: textContainer);

        self.delegate = self;

        // Create a background TextField with clear (invisible) text and disabled
        self.textField.borderStyle = UITextBorderStyle.RoundedRect;
        self.textField.textColor = UIColor.clearColor();
        self.textField.userInteractionEnabled = false;

        self.addSubview(textField);
        self.sendSubviewToBack(textField);
    }

    convenience init()
    {
        self.init(frame: CGRectZero, textContainer: nil)
    }

    override func layoutSubviews()
    {
        super.layoutSubviews()
        // Do not scroll the background textView
        self.textField.frame = CGRectMake(0, self.contentOffset.y, self.frame.width, self.frame.height);
    }

    // UITextViewDelegate - Note: If you replace delegate, your delegate must call this
    func scrollViewDidScroll(scrollView: UIScrollView)
    {
        // Do not scroll the background textView
        self.textField.frame = CGRectMake(0, self.contentOffset.y, self.frame.width, self.frame.height);
    }        
}
Community
  • 1
  • 1
BobDickinson
  • 2,156
  • 21
  • 18
4

One way I found to do it without programming is to make the textfield background transparent, then place a Round Rect Button behind it. Make sure to change the button settings to disable it and uncheck the Disable adjusts image checkbox.

Andrew_L
  • 3,021
  • 2
  • 19
  • 18
3
#import <QuartzCore/QuartzCore.h>
- (void)viewDidLoad{
  UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(50, 220, 200, 100)];
  textView.layer.cornerRadius = 5;
  textView.clipsToBounds = YES;
  [textView.layer setBackgroundColor: [[UIColor whiteColor] CGColor]];
  [textView.layer setBorderColor: [[UIColor grayColor] CGColor]];
  [textView.layer setBorderWidth: 1.0];
  [textView.layer setCornerRadius:8.0f];
  [textView.layer setMasksToBounds:YES];
  [self.view addSubView:textview];
}
Hemang
  • 26,840
  • 19
  • 119
  • 186
Sonu
  • 937
  • 1
  • 10
  • 39
3

There is a great background image that is identical to the UITextView used for sending text messages in iPhone's Messages app. You'll need Adobe Illustrator to get & modify it. iphone ui vector elements

NANNAV
  • 4,875
  • 4
  • 32
  • 50
ma11hew28
  • 121,420
  • 116
  • 450
  • 651
3

One way I found to do it without programming is to make the textfield background transparent, then place a Round Rect Button behind it. Make sure to change the button settings to disable it and uncheck the Disable adjusts image checkbox.

Tried the Quartzcore code and found it caused lag on my old 3G (I use for testing). Not a big issue but if you want to be as inclusive as possible for different ios and hardware I recommend Andrew_L's answer above - or make your own images and apply accordingly.

2

You can create a Text Field that doesn't accept any events on top of a Text View like this:

CGRect frameRect = descriptionTextField.frame;
frameRect.size.height = 50;
descriptionTextField.frame = frameRect;
descriptionTextView.frame = frameRect;
descriptionTextField.backgroundColor = [UIColor clearColor];
descriptionTextField.enabled = NO;
descriptionTextView.layer.cornerRadius = 5;
descriptionTextView.clipsToBounds = YES;
Nate
  • 75
  • 9
  • Or just make a text field in interface builder. Then set height in code (since the interface builder wont let you). CGRect frameRect = self.textField.frame; frameRect.size.height = 50; self.textField.frame = frameRect; – audub Mar 10 '13 at 17:52
2

If you want to keep your controller code clean, you can subclass UITextView like below, and change the class name in the Interface Builder.

RoundTextView.h

#import <UIKit/UIKit.h>
@interface RoundTextView : UITextView
@end

RoundTextView.m

#import "RoundTextView.h"
#import <QuartzCore/QuartzCore.h>
@implementation RoundTextView
-(id) initWithCoder:(NSCoder *)aDecoder {
    if (self = [super initWithCoder:aDecoder]) {
        [self.layer setBorderColor:[[[UIColor grayColor] colorWithAlphaComponent:0.333] CGColor]];
        [self.layer setBorderWidth:1.0];
        self.layer.cornerRadius = 5;
        self.clipsToBounds = YES;
    }
    return self;
}
@end
Satoshi Nakajima
  • 1,863
  • 18
  • 29
1

Here is my solution:

- (void)viewDidLoad {
    [super viewDidLoad];


    self.textView.text = self.messagePlaceholderText;
    self.textView.layer.backgroundColor = [[UIColor whiteColor] CGColor];
    self.textView.layer.borderColor = [[[UIColor grayColor] colorWithAlphaComponent:0.3] CGColor];
    self.textView.layer.borderWidth = 0.5;
    self.textView.layer.cornerRadius = 5.5f;
    self.textView.layer.masksToBounds = YES;
    self.textView.textColor = [[UIColor grayColor] colorWithAlphaComponent:0.4];
}

- (void)textViewDidBeginEditing:(UITextView *)textView {
    if (textView == self.tvMessage) {
        // Delete placeholder text
        if ([self.textView.text isEqualToString:self.messagePlaceholderText]) {
            self.textView.text = @"";
            self.textView.textColor = [UIColor blackColor];
        }
    }
}

- (void)textViewDidEndEditing:(UITextView *)textView {
    if (textView == self.tvMessage) {
        // Write placeholder text
        if (self.textView.text.length == 0) {
            self.textView.text = self.messagePlaceholderText;
            self.textView.textColor = [[UIColor grayColor] colorWithAlphaComponent:0.4];
        }
    }
}
Manuel Schmitzberger
  • 5,162
  • 3
  • 36
  • 45
0

This is an old question, and I was also searched for this questions answer. luvieeres' answer is 100% correct and later Rob added some code. That is excellent, but I found a third party in another questions answer which seems very helpful to me. I was not only searched for similar look of UITextField over UITextView, I was also searched for multiline support. ChatInputSample satisfied both. Thats why I think this third party might be helpful to others. Also thanks to Timur, he mentioned this open source in here.

Community
  • 1
  • 1
sumon
  • 742
  • 1
  • 11
  • 33
0

I don't think that it is possible. but you can do UITableView(grouped) with 1 section and 1 empty cell and use it as a container for your UITextView.

Venk
  • 5,949
  • 9
  • 41
  • 52
Morion
  • 10,495
  • 1
  • 24
  • 33
0

In iOS7 the following matches UITextField border perfectly (to my eye at least):

textField.layer.borderColor = [[[UIColor grayColor] colorWithAlphaComponent:0.5] CGColor];
textField.layer.borderWidth = 0.5;
textField.layer.cornerRadius = 5;
textField.clipsToBounds = YES;

There is no need to import anything special.

Thanks to @uvieere and @hanumanDev whose answers go me almost there :)

Adrian Toman
  • 11,316
  • 5
  • 48
  • 62
-1

How about just:

UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 20, 280, 32)];
textField.borderStyle = UITextBorderStyleRoundedRect;
[self addSubview:textField];
jowie
  • 8,028
  • 8
  • 55
  • 94