¿Cómo aplicar estilo a UITextview para que le guste el campo de texto Rect redondeado?


170

Estoy usando una vista de texto como un compositor de comentarios.

En el inspector de propiedades no puedo encontrar nada como una propiedad de estilo de borde para poder hacer uso de un rect redondeado, algo así como UITextField .

Entonces, la pregunta es: ¿Cómo puedo diseñar un UITextViewlike como UITextFieldcon un rect redondeado?


1
¿No podrías usar UITextFieldy simplemente apagar userInteractionEnabled?
jowie

Respuestas:


285

No hay un estilo implícito que tenga que elegir, implica escribir un poco de código usando el QuartzCoremarco:

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

Solo funciona en OS 3.0 y superior, pero supongo que ahora es la plataforma de facto de todos modos.


47
Descubrí que al agregar la siguiente parte superior, el código anterior hace que el borde se vea muy cerca de un UITextField. [textView.layer setBorderColor: [[[UIColor grayColor] colorWithAlphaComponent: 0.5] CGColor]]; [textView.layer setBorderWidth: 2.0];
Rob

12
Asegúrese de tener: #import <QuartzCore / QuartzCore.h>. Tuve problemas porque no importé QuartzCore
austen

1
Para n00bs como yo, digno de mención: ponga este código en viewDidLoad NOT en initWithNibName :-)
Brian Colavito

1
Puede usar un UITextFieldcon la borderStylepropiedad establecida en UITextBorderStyleRoundedRect- vea mi publicación a continuación.
jowie

55
iOS 7: borderWidth de 1.0 y alpha de .2 funciona con el estilo predeterminado.
Kalel Wade

77

este código funcionó bien para mí:

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

44
Diría que 5px está más cerca de los campos de texto, pero el color gris de esta respuesta es mejor que la respuesta seleccionada.
Peter DeWeese

2
Por supuesto, necesita agregar QuartzCore Framework para esta respuesta e importarlo por #import <QuartzCore / QuartzCore.h>
lukaswelte

36

Versión Swift 3

Después de configurar la vista de texto en el generador de interfaces.

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

Versión 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
El problema es que no es gris exactamente. El color del marco de UITextField es un poco diferente.
Makalele

1
Hacer .borderWidth = 0.7 lo hace ver más cercano al estilo actual que veo en iOS 11.
Chris Amelinckx

28

Editar: tienes que importar

#import <QuartzCore/QuartzCore.h>

para usar el radio de la esquina.

Prueba esto, funcionará seguro

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

Como Rob descubrió, si desea que el color del borde sea similar, UITextFieldentonces debe cambiar el ancho del borde a 2.0 y el color a gris agregando la siguiente línea

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

2
Me preguntaba por qué esto no estaba funcionando. Gracias por el aviso sobre QuartzCore.
Echilon

23

Quería el verdadero negocio, así que agrego UIImageViewcomo una subvista de la UITextView. Esto coincide con el borde nativo en un UITextField, incluido el gradiente de arriba a abajo:

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

Estas son las imágenes que uso:

ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí


2
Creo que también necesita decirle a textView que tenga UITextBorderStyle None si aún no lo ha configurado en XCode
superlogical el

1
Recargué las imágenes png
Ben Packard

55
No está bien, el fondo se mueve a medida que desplaza la UITextView. Supongo que tendré que colocarlo todo en una UIView principal.
Oliver Pearmain

1
Excelente. Eso se ve muy bien: D
Sune Trudslev

12

Una solución es agregar un UITextField debajo del UITextView , hacer que el UITextViewfondo sea transparente y deshabilitar cualquier interacción del usuario en el UITextField. Luego, en el código, cambie el UITextFieldmarco con algo así

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

Tendrá exactamente el mismo aspecto que un campo de texto.

Y según lo sugerido por Jon , debe poner este código dentro [UIViewController viewDidLayoutSubviews]de iOS 5.0+.


1
Esto fue muy simple y se ve exactamente como quería que se viera. Acabo de hacer coincidir el marco del UITextField con el UITextView: CGRect frame = self.myTextView.frame; frame.size.height + = 2; self.myTextField.frame = frame;
Buyin Brian

1
Encantadora respuesta. Limpio y sencillo. Poner código en viewDidLayoutSubviews:(iOS 5.0+).
Jon

1
Bien, esta fue la solución con la que fui al final. Tenga en cuenta que no funcionó hasta que usé el comentario de Jon re: viewDidLayoutSubviews:
daver

1
Este fue el más rápido y se ve mejor.
Weston

5

Para obtener el mejor efecto, debe utilizar una imagen de fondo personalizada (extensible). Así también UITextFieldse dibuja el borde redondeado del 's.


4

Una forma de hacerlo sin programar es hacer que el fondo del campo de texto sea transparente y luego colocar un botón de Rectificación redonda detrás de él. Asegúrese de cambiar la configuración del botón para deshabilitarlo y desmarque la Disable adjusts imagecasilla de verificación.


4

Es posible que desee consultar mi biblioteca llamada DCKit .

Podrá crear una vista de texto de esquina redondeada (así como un campo de texto / botón / plano UIView) Interface Builderdirectamente desde:

DCKit: bordeado UITextView

También tiene muchas otras características útiles, como campos de texto con validación, controles con bordes, bordes discontinuos, vistas de círculo y rayita, etc.


4

Sé que ya hay muchas respuestas a esta, pero realmente no encontré ninguna de ellas suficiente (al menos en Swift). Quería una solución que proporcionara el mismo borde exacto que un UITextField (no una aproximada que se vea más o menos como se ve ahora, pero una que se ve exactamente igual y siempre se verá exactamente igual). Necesitaba usar un UITextField para respaldar el UITextView para el fondo, pero no quería tener que crearlo por separado cada vez.

La solución a continuación es un UITextView que proporciona su propio UITextField para el borde. Esta es una versión reducida de mi solución completa (que agrega soporte de "marcador de posición" al UITextView de manera similar) y se publicó aquí: 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

Una forma de hacerlo sin programar es hacer que el fondo del campo de texto sea transparente y luego colocar un botón de Rectificación redonda detrás de él. Asegúrese de cambiar la configuración del botón para deshabilitarlo y desmarque la casilla de verificación Deshabilitar ajustes de imagen.

Intenté el código Quartzcore y descubrí que causaba un retraso en mi 3G anterior (lo uso para las pruebas). No es un gran problema, pero si desea ser lo más inclusivo posible para diferentes dispositivos iOS y hardware, le recomiendo la respuesta de Andrew_L anterior, o haga sus propias imágenes y aplique en consecuencia.



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

Puede crear un campo de texto que no acepte ningún evento encima de una vista de texto como este:

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;

O simplemente haga un campo de texto en el generador de interfaces. Luego establezca la altura en el código (ya que el generador de interfaces no le permitirá). CGRect frameRect = self.textField.frame; frameRect.size.height = 50; self.textField.frame = frameRect;
audub

2

Si desea mantener limpio el código de su controlador, puede subclasificar UITextView como se muestra a continuación y cambiar el nombre de la clase en el Creador de interfaces.

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

Aquí está mi solución:

- (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

No creo que sea posible. pero puede hacerlo UITableView(agrupado) con 1 sección y 1 celda vacía y usarlo como contenedor para su UITextView.


0

Esta es una vieja pregunta, y también me buscaron por esta respuesta. La respuesta de luvieeres es 100% correcta y luego Rob agregó un código. Eso es excelente, pero encontré un tercero en otra respuesta a las preguntas que me parece muy útil. Yo no sólo se buscó aspecto similar de UITextFieldmás UITextView, también se buscó el apoyo de varias líneas. ChatInputSample satisfizo a ambos. Por eso creo que este tercero podría ser útil para otros. También gracias a Timur, mencionó este código abierto aquí .


0

En iOS7, lo siguiente coincide perfectamente con el borde UITextField (al menos para mi ojo):

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

No hay necesidad de importar nada especial.

Gracias a @uvieere y @hanumanDev cuyas respuestas me llevan casi allí :)


-1

¿Qué tal solo:

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

la pregunta es sobre textview.
Azik Abdullah

Lo sentimos, activa la respuesta de pila feliz. Estaría interesado en saber por qué no podrían simplemente usar a UITextFieldcon userInteractionEnabledset to NO.
jowie

Textfield no admite líneas múltiples
Azik Abdullah

entendido. Gracias por aclarar
jowie
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.