Как стилизовать 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.