Как стилизовать UITextview как текстовое поле Rounded Rect?


170

Я использую текстовое представление как композитор комментария.

В инспекторе свойств я не могу найти ничего похожего на свойство стиля границы, чтобы я мог использовать закругленный прямоугольник, что-то вроде UITextField.

Итак, вопрос: Как я могу стилизацию UITextViewвроде UITextFieldс закругленным прямоугольником?


1
Не могли бы вы не использовать UITextFieldи просто выключить userInteractionEnabled?
Джоуи

Ответы:


285

Не существует неявного стиля, который вы должны выбрать, он включает в себя написание небольшого количества кода с использованием QuartzCoreфреймворка:

//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;

Это работает только на OS 3.0 и выше, но я думаю, что теперь это де-факто платформа в любом случае.


47
Я обнаружил, что добавление следующей вершины кода выше делает границу очень похожей на UITextField. [textView.layer setBorderColor: [[[UIColor grayColor] colorWithAlphaComponent: 0.5] CGColor]]; [textView.layer setBorderWidth: 2.0];
Роб

12
Убедитесь, что у вас есть: #import <QuartzCore / QuartzCore.h>. У меня были проблемы, потому что я не импортировал QuartzCore
austen

1
Для n00bs, как я, стоит отметить: поместите этот код в viewDidLoad, а НЕ в initWithNibName :-)
Брайан Колавито

1
Вы можете просто использовать UITextFieldс borderStyleнабором свойств к UITextBorderStyleRoundedRect- см мой пост ниже.
Джоуи

5
iOS 7 - borderWidth 1.0 и alpha .2 работает со стилем по умолчанию.
Калель Уэйд

77

этот код работал хорошо для меня:

    [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];

4
Я бы сказал, что 5px ближе к текстовым полям, но серый цвет этого ответа лучше, чем выбранный ответ.
Питер ДеВиз

2
Конечно, вам нужно добавить QuartzCore Framework для этого ответа и импортировать его с помощью #import <QuartzCore / QuartzCore.h>
lukaswelte

36

Версия Swift 3

После настройки просмотра текста в конструкторе интерфейса.

@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

@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
}

1
Проблема в том, что он не серый. Цвет рамки UITextField немного отличается.
Makalele

1
Если сделать .borderWidth = 0.7, это будет выглядеть ближе к текущему стилю, который я вижу в iOS 11.
Крис Амелинккс,

28

Редактировать: вы должны импортировать

#import <QuartzCore/QuartzCore.h>

для использования углового радиуса.

Попробуйте это, это будет работать наверняка

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

Как понял Роб, установив, что если вы хотите, чтобы цвет границы был похожим, UITextFieldвам нужно изменить ширину границы на 2,0 и цвет на серый, добавив следующую строку

[textView.layer setBorderColor:[[[UIColor grayColor] colorWithAlphaComponent:0.5] CGColor]]; 
[textView.layer setBorderWidth:2.0];

2
Мне было интересно, почему это не работает. Спасибо за отзыв о QuartzCore.
Echilon

23

Я хотел реальную сделку, поэтому я добавлю UIImageViewв качестве подпредставления UITextView. Это соответствует родной границе на a UITextField, включая градиент сверху вниз:

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];

Вот изображения, которые я использую:

введите описание изображения здесь введите описание изображения здесь


2
Я думаю, что вам также нужно указать textView, чтобы UITextBorderStyle None, если вы еще не установили это в XCode
суперлогично

1
Я повторно загрузил изображения PNG
Бен Паккард

5
Ничего хорошего, фон перемещается при прокрутке UITextView. Думаю, мне придется поместить все это в родительский UIView.
Оливер Пирмейн

1
Превосходно. Это выглядит великолепно: D
Sune Trudslev

12

Одно из решений - добавить UITextField под UITextView , сделать UITextViewфон прозрачным и отключить любое взаимодействие с пользователем на UITextField. Затем в коде поменяйте UITextFieldфрейм на что-то подобное

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

Вы будете выглядеть точно так же, как текстовое поле.

И, как предлагает Джон , вы должны поместить этот фрагмент кода [UIViewController viewDidLayoutSubviews]на iOS 5.0+.


1
Это было так просто и выглядит именно так, как я хотел, чтобы это выглядело. Я просто сопоставил кадр UITextField с UITextView: CGRect frame = self.myTextView.frame; frame.size.height + = 2; self.myTextField.frame = frame;
Буйен Брайан,

1
Прекрасный ответ. Чисто и просто. Вставьте код в viewDidLayoutSubviews:(iOS 5.0+).
Джон

1
Хорошо, это был soln, с которым я пошел в конце. Обратите внимание, что это не сработало, пока я не использовал комментарий Джона re: viewDidLayoutSubviews:
daver

1
Это было самым быстрым и выглядит лучше всего.
Уэстон

5

Для лучшего эффекта вы должны использовать пользовательское (растягиваемое) фоновое изображение. Это также, как UITextFieldнарисована округленная граница.


4

Один из способов сделать это без программирования - сделать фон текстового поля прозрачным, а затем поместить круглую кнопку Rect позади него. Обязательно измените настройки кнопки, чтобы отключить ее, и снимите Disable adjusts imageфлажок.


4

Вы можете проверить мою библиотеку под названием DCKit .

Вы сможете сделать текстовое представление с закругленными углами (а также текстовое поле / кнопку / обычный текст UIView) Interface Builderнепосредственно из:

DCKit: ограниченный UITextView

У этого также есть много других полезных функций, таких как текстовые поля с проверкой, элементы управления с границами, пунктирные границы, представления круга и линии роста волос и т. Д.


4

Я знаю, что на этот вопрос уже есть много ответов, но я не нашел ни одного из них достаточным (по крайней мере, в Swift). Я хотел решение, которое предоставило бы ту же самую точную границу, что и UITextField (не приблизительное, которое выглядит примерно так, как выглядит прямо сейчас, но такое, которое выглядит точно так же и всегда будет выглядеть точно так же). Мне нужно было использовать UITextField для поддержки UITextView для фона, но я не хотел создавать его отдельно каждый раз.

Решение ниже представляет собой UITextView, который предоставляет свой собственный UITextField для границы. Это урезанная версия моего полного решения (которая добавляет поддержку «заполнителя» в UITextView аналогичным образом), которая была размещена здесь: 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);
    }        
}

3

Один из способов сделать это без программирования - сделать фон текстового поля прозрачным, а затем поместить круглую кнопку Rect позади него. Обязательно измените настройки кнопки, чтобы отключить ее, и снимите флажок «Отключить настройки изображения».

Попробовал код Quartzcore и обнаружил, что он вызывает задержку на моем старом 3G (я использую для тестирования). Не большая проблема, но если вы хотите быть как можно более инклюзивным для разных ios и аппаратного обеспечения, я рекомендую ответ Andrew_L выше - или создайте свои собственные изображения и примените их соответствующим образом.


3

Есть отличное фоновое изображение, идентичное UITextViewиспользуемому для отправки текстовых сообщений в приложении Сообщения iPhone. Вам понадобится Adobe Illustrator, чтобы получить и изменить его. iphone UI векторные элементы


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];
}

2

Вы можете создать текстовое поле, которое не принимает никаких событий поверх текстового представления, например:

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;

Или просто сделайте текстовое поле в конструкторе интерфейса. Затем установите высоту в коде (так как интерфейсный конструктор не позволит вам). CGRect frameRect = self.textField.frame; frameRect.size.height = 50; self.textField.frame = frameRect;
2013 года

2

Если вы хотите, чтобы ваш код контроллера был чистым, вы можете создать подкласс UITextView, как показано ниже, и изменить имя класса в Интерфейсном Разработчике.

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

1

Вот мое решение:

- (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];
        }
    }
}

0

Я не думаю, что это возможно. но вы можете сделать UITableView(сгруппированы) с 1 разделом и 1 пустой ячейкой и использовать его в качестве контейнера для вашего UITextView.


0

Это старый вопрос, и я также искал ответ на этот вопрос. Ответ Лювьера на 100% правильный, и позже Роб добавил код. Это отлично, но я нашел стороннюю компанию в ответе на другие вопросы, которая мне кажется очень полезной. Я не только искал подобный взгляд на UITextFieldболее UITextView, я также искал многострочную поддержку. ChatInputSample удовлетворяет оба. Вот почему я думаю, что эта третья сторона может быть полезна для других. Также благодаря Тимуру он упомянул этот открытый исходный код здесь .


0

В iOS7 следующее идеально соответствует границе UITextField (по крайней мере, на мой взгляд):

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

Там нет необходимости импортировать что-то особенное.

Спасибо @uvieere и @hanumanDev, ответы на которые меня почти не оставляют :)


-1

Как насчет просто:

UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 20, 280, 32)];
textField.borderStyle = UITextBorderStyleRoundedRect;
[self addSubview:textField];

вопрос по поводу textview.
Азик Абдулла

Извините - вызвать счастливый стековый ответ. Было бы интересно узнать, почему они не могут просто использовать UITextFieldс userInteractionEnabledустановленным на NO.
Джоуи

Textfield не поддерживает несколько строк
Азик Абдулла

понят. Спасибо за разъяснение
Джоуи
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.