Come adattare UITextview al campo di testo Rect arrotondato?


170

Sto usando una vista di testo come compositore di commenti.

Nella finestra di ispezione delle proprietà non riesco a trovare nulla di simile a una proprietà in stile bordo in modo da poter utilizzare un rettangolo arrotondato, qualcosa del genere UITextField.

Quindi, la domanda è: come posso modellare un UITextViewlike a UITextFieldcon un rettangolo arrotondato?


1
Non potresti usare UITextFielde semplicemente spegnere userInteractionEnabled?
jowie,

Risposte:


285

Non c'è uno stile implicito che devi scegliere, implica la scrittura di un po 'di codice usando il QuartzCoreframework:

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

Funziona solo su OS 3.0 e versioni successive, ma suppongo che ora sia comunque la piattaforma di fatto.


47
Ho scoperto che aggiungendo il seguente codice il codice sopra rende il bordo molto simile a un UITextField. [textView.layer setBorderColor: [[[[UIColor grayColor] colorWithAlphaComponent: 0.5] CGColor]]; [textView.layer setBorderWidth: 2.0];
Rob,

12
Assicurati di avere: #import <QuartzCore / QuartzCore.h>. Ho avuto problemi perché non ho importare QuartzCore
Austen

1
Per n00bs come me, degno di nota: metti questo codice in evidenzaDidLoad NON in initWithNibName :-)
Brian Colavito

1
Puoi semplicemente usare a UITextFieldcon la borderStyleproprietà impostata su UITextBorderStyleRoundedRect- vedi il mio post qui sotto.
Jowie,

5
iOS 7 - borderWidth di 1.0 e alpha di .2 funziona con lo stile predefinito.
Kalel Wade,

77

questo codice ha funzionato bene per 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];

4
Direi che 5px è più vicino ai campi di testo, ma il colore grigio di questa risposta è migliore della risposta selezionata.
Peter DeWeese,

2
Naturalmente è necessario aggiungere QuartzCore Framework per questa risposta e importarlo con #import <QuartzCore / QuartzCore.h>
lukaswelte

36

Versione Swift 3

Dopo aver impostato la vista testo nel generatore di interfaccia.

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

Versione 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
Il problema è che non è esattamente grigio. Il colore del telaio di UITextField è leggermente diverso.
Makalele,

1
Fare .borderWidth = 0.7 lo rende più vicino allo stile attuale che vedo su iOS 11.
Chris Amelinckx,

28

Modifica: devi importare

#import <QuartzCore/QuartzCore.h>

per l'utilizzo del raggio d'angolo.

Prova questo funzionerà di sicuro

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

Come Rob ha capito impostando se si desidera che il colore del bordo sia simile in quanto UITextFieldè necessario modificare la larghezza del bordo in 2.0 e il colore in grigio aggiungendo la seguente riga

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

2
Mi chiedevo perché non funzionasse. Grazie per l'informazione su QuartzCore.
Echilon,

23

Volevo il vero affare, quindi aggiungo UIImageViewcome sottoview di UITextView. Questo corrisponde al bordo nativo su a UITextField, incluso il gradiente dall'alto verso il basso:

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

Queste sono le immagini che uso:

inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine


2
Penso che anche tu debba dire a textView di avere UITextBorderStyle None se non lo hai già impostato in XCode
superlogico

1
Ho ricaricato le immagini in png
Ben Packard il

5
Non va bene, lo sfondo si sposta mentre scorri UITextView. Immagino che dovrò mettere tutto in un UIView genitore.
Oliver Pearmain,

1
Eccellente. Sembra fantastico: D
Sune Trudslev,

12

Una soluzione è quella di aggiungere un UITextField sotto UITextView , rendere UITextViewtrasparente lo sfondo e disabilitare qualsiasi interazione dell'utente sul UITextField. Quindi nel codice cambia il UITextFieldframe con qualcosa del genere

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

Avrai esattamente lo stesso aspetto di un campo di testo.

E come suggerito da Jon , dovresti inserire questo pezzo di codice [UIViewController viewDidLayoutSubviews]su iOS 5.0+.


1
Era così semplice e sembrava esattamente come volevo che fosse. Ho appena abbinato il frame di UITextField a UITextView: frame CGRect = self.myTextView.frame; frame.size.height + = 2; self.myTextField.frame = frame;
Acquistando Brian il

1
Bella risposta. Pulito e semplice. Inserisci il codice viewDidLayoutSubviews:(iOS 5.0+).
Jon,

1
Bello, questo è stato il soln con cui sono andato alla fine. Si noti che non ha funzionato fino a quando non ho usato il commento di Jon in riferimento a: viewDidLayoutSubviews:
daver

1
Questo è stato il più veloce e sembra il migliore.
Weston,

5

Per ottenere l'effetto migliore, è necessario utilizzare un'immagine di sfondo personalizzata (estensibile). Questo è anche il modo in cui UITextFieldviene disegnato il bordo arrotondato.


4

Un modo in cui ho scoperto di farlo senza programmazione è quello di rendere trasparente lo sfondo del campo di testo, quindi posizionare un pulsante Rect rotondo dietro di esso. Assicurati di modificare le impostazioni del pulsante per disabilitarlo e deseleziona la Disable adjusts imagecasella di controllo.


4

Potresti voler dare un'occhiata alla mia libreria chiamata DCKit .

Saresti in grado di creare una vista di testo ad angolo arrotondato (così come campo di testo / pulsante / semplice UIView) Interface Builderdirettamente dal:

DCKit: UITextView con bordi

Ha anche molte altre funzioni utili, come campi di testo con convalida, controlli con bordi, bordi tratteggiati, viste di cerchi e linee sottili ecc.


4

So che ci sono già molte risposte a questo, ma non ne ho trovati abbastanza sufficienti (almeno in Swift). Volevo una soluzione che fornisse lo stesso bordo esatto di un UITextField (non uno approssimato che sembra un po 'come sembra in questo momento, ma uno che assomiglia esattamente a quello e sarà sempre esattamente uguale). Avevo bisogno di utilizzare un UITextField per eseguire il backup di UITextView per lo sfondo, ma non volevo crearlo separatamente ogni volta.

La soluzione di seguito è un UITextView che fornisce il proprio UITextField per il bordo. Questa è una versione ridotta della mia soluzione completa (che aggiunge il supporto "segnaposto" a UITextView in modo simile) ed è stata pubblicata qui: 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

Un modo in cui ho scoperto di farlo senza programmazione è quello di rendere trasparente lo sfondo del campo di testo, quindi posizionare un pulsante Rect rotondo dietro di esso. Assicurati di modificare le impostazioni del pulsante per disabilitarlo e deseleziona la casella Disabilita regola immagine.

Ho provato il codice Quartzcore e ho scoperto che causava ritardo sul mio vecchio 3G (lo uso per i test). Non è un grosso problema, ma se vuoi essere il più inclusivo possibile per diversi iOS e hardware, ti consiglio la risposta di Andrew_L sopra - o fai le tue immagini e applica di conseguenza.


3

C'è una fantastica immagine di sfondo identica a quella UITextViewusata per inviare messaggi di testo nell'app Messaggi di iPhone. Avrai bisogno di Adobe Illustrator per ottenerlo e modificarlo. iphone elementi vettoriali 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

Puoi creare un campo di testo che non accetta eventi sopra una vista di testo come questo:

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 semplicemente crea un campo di testo nel generatore di interfacce. Quindi imposta l'altezza nel codice (poiché il generatore di interfacce non te lo consente). CGRect frameRect = self.textField.frame; frameRect.size.height = 50; self.textField.frame = frameRect;
Audub

2

Se si desidera mantenere pulito il codice del controller, è possibile sottoclassare UITextView come di seguito e modificare il nome della classe in 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

1

Ecco la mia soluzione:

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

Non penso che sia possibile. ma puoi farlo UITableView(raggruppato) con 1 sezione e 1 cella vuota e usarlo come contenitore per il tuo UITextView.


0

Questa è una vecchia domanda e ho anche cercato questa risposta. La risposta di luvieeres è corretta al 100% e in seguito Rob ha aggiunto del codice. Questo è eccellente, ma ho trovato una terza parte in un'altra risposta alle domande che mi sembra molto utile. Non solo sono stato cercato un aspetto simile da UITextFieldsopra UITextView, ma sono stato anche cercato un supporto multilinea. ChatInputSample soddisfatto entrambi. Ecco perché penso che questa terza parte possa essere utile agli altri. Anche grazie a Timur, ha menzionato questo open source qui .


0

In iOS7 i seguenti abbinano perfettamente il bordo UITextField (almeno ai miei occhi):

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

Non è necessario importare nulla di speciale.

Grazie a @uvieere e @hanumanDev le cui risposte mi arrivano quasi lì :)


-1

Che ne dici di:

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

la domanda riguarda la visualizzazione del testo.
Azik Abdullah,

Spiacenti, attiva la risposta in pila felice. Sarebbe interessato a sapere perché non potevano semplicemente usare un UITextFieldcon userInteractionEnabledset a NO.
jowie,

Textfield non supporta più righe
Azik Abdullah,

inteso. Grazie per il chiarimento
jowie il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.