Wie kann man UITextview so gestalten, dass es das Textfeld Rounded Rect mag?

170

Ich verwende eine Textansicht als Kommentarkomponist.

Im Eigenschafteninspektor kann ich so etwas wie eine Eigenschaft im Rahmenstil nicht finden, sodass ich ein abgerundetes Rechteck verwenden kann, so etwas wie UITextField.

Die Frage ist also: Wie kann ich ein UITextViewLike a UITextFieldmit einem abgerundeten Rect stylen?

harshalb
quelle
1
Könnten Sie nicht verwenden UITextFieldund einfach ausschalten userInteractionEnabled?
Jowie

Antworten:

285

Es gibt keinen impliziten Stil, den Sie auswählen müssen. Es geht darum, ein bisschen Code mit dem QuartzCoreFramework zu schreiben :

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

Es funktioniert nur unter OS 3.0 und höher, aber ich denke, jetzt ist es sowieso die De-facto-Plattform.

luvieere
quelle
47
Ich habe festgestellt, dass durch Hinzufügen des folgenden Codes der obige Code den Rand einem UITextField sehr nahe kommt. [textView.layer setBorderColor: [[[UIColor greyColor] colorWithAlphaComponent: 0.5] CGColor]]; [textView.layer setBorderWidth: 2.0];
Rob
12
Stellen Sie sicher, dass Sie Folgendes haben: #import <QuartzCore / QuartzCore.h>. Ich hatte Probleme , weil ich nicht Quartz importieren
Austens
1
Für n00bs wie mich, erwähnenswert: Setzen Sie diesen Code in viewDidLoad NICHT in initWithNibName :-)
Brian Colavito
1
Sie können einfach a UITextFieldmit der borderStyleEigenschaft verwenden, die auf eingestellt ist UITextBorderStyleRoundedRect- siehe meinen Beitrag unten.
Jowie
5
iOS 7 - borderWidth von 1.0 und Alpha von .2 funktioniert mit dem Standardstil.
Kalel Wade
77

Dieser Code hat bei mir gut funktioniert:

    [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
quelle
4
Ich würde sagen, dass 5px näher an Textfeldern liegt, aber die graue Farbe dieser Antwort ist besser als die ausgewählte Antwort.
Peter DeWeese
2
Natürlich müssen Sie QuartzCore Framework für diese Antwort hinzufügen und von #import <QuartzCore / QuartzCore.h>
importieren
36

Swift 3 Version

Nach dem Einrichten der Textansicht im 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
}
Sean McClory
quelle
1
Das Problem ist, dass es nicht genau grau ist. Die Farbe des Rahmens von UITextField ist etwas anders.
Makalele
1
Wenn Sie .borderWidth = 0.7 festlegen, wird der aktuelle Stil, den ich unter iOS 11 sehe, näher betrachtet.
Chris Amelinckx
28

Bearbeiten: Sie müssen importieren

#import <QuartzCore/QuartzCore.h>

zur Verwendung des Eckenradius.

Versuchen Sie dies, es wird sicher funktionieren

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

Wie Rob herausgefunden hat, UITextFieldmüssen Sie die Rahmenbreite auf 2,0 und die Farbe auf Grau ändern, indem Sie die folgende Zeile hinzufügen, wenn Sie möchten, dass die Rahmenfarbe ähnlich ist

[textView.layer setBorderColor:[[[UIColor grayColor] colorWithAlphaComponent:0.5] CGColor]]; 
[textView.layer setBorderWidth:2.0];
Suresh Varma
quelle
2
Ich fragte mich, warum das nicht funktionierte. Vielen Dank für den Hinweis zu QuartzCore.
Echilon
23

Ich wollte das echte Geschäft, also füge ich UIImageViewals Unteransicht der UITextView. Dies entspricht dem nativen Rand auf a UITextField, einschließlich des Verlaufs von oben nach unten:

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

Dies sind die Bilder, die ich benutze:

Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein

Ben Packard
quelle
2
Ich denke, Sie müssen auch die textView anweisen, UITextBorderStyle None zu haben, wenn Sie das noch nicht in XCode festgelegt haben
superlogisch
1
Ich habe die PNG-Bilder erneut hochgeladen
Ben Packard
5
Nicht gut, der Hintergrund bewegt sich, wenn Sie durch die UITextView scrollen. Ich denke, ich muss alles in einem übergeordneten UIView platzieren.
Oliver Pearmain
1
Ausgezeichnet. Das sieht gut aus: D
Sune Trudslev
12

Eine Lösung besteht darin , ein UITextField unterhalb der UITextView hinzuzufügen , den UITextViewHintergrund transparent zu machen und jegliche Benutzerinteraktion auf dem zu deaktivieren UITextField. Ändern Sie dann im Code den UITextFieldRahmen mit so etwas

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

Sie sehen genauso aus wie ein Textfeld.

Und wie von Jon vorgeschlagen , sollten Sie diesen Code [UIViewController viewDidLayoutSubviews]unter iOS 5.0+ einfügen.

Phil
quelle
1
Das war so einfach und sieht genau so aus, wie ich es haben wollte. Ich habe gerade den Frame des UITextField mit dem UITextView abgeglichen: CGRect frame = self.myTextView.frame; frame.size.height + = 2; self.myTextField.frame = frame;
Buyin Brian
1
Schöne Antwort. Sauber und einfach. viewDidLayoutSubviews:Geben Sie Code ein (iOS 5.0+).
Jon
1
Schön, das war die Lösung, mit der ich am Ende gegangen bin. Beachten Sie, dass es nicht funktioniert hat, bis ich Jons Kommentar zu: viewDidLayoutSubviews:
daver
1
Dies war am schnellsten und sieht am besten aus.
Weston
5

Für den besten Effekt müssen Sie ein benutzerdefiniertes (dehnbares) Hintergrundbild verwenden. Auf diese Weise wird auch der UITextFieldabgerundete Rand des Zeichens gezeichnet.

kennytm
quelle
4

Eine Möglichkeit, dies ohne Programmierung zu tun, besteht darin, den Hintergrund des Textfelds transparent zu machen und dann einen runden Rechteck-Button dahinter zu platzieren. Stellen Sie sicher, dass Sie die Schaltflächeneinstellungen ändern, um sie zu deaktivieren, und deaktivieren Sie das Disable adjusts imageKontrollkästchen.

Andrew_L
quelle
4

Vielleicht möchten Sie meine Bibliothek namens DCKit überprüfen .

Sie können eine Textansicht mit abgerundeten Ecken (sowie ein Textfeld / eine Schaltfläche / eine Ebene UIView) Interface Builderdirekt erstellen :

DCKit: UITextView mit Rand

Es hat auch viele andere nützliche Funktionen, wie Textfelder mit Validierung, Steuerelemente mit Rahmen, gestrichelte Rahmen, Kreis- und Haaransichten usw.

Andrey Gordeev
quelle
4

Ich weiß, dass es bereits viele Antworten auf diese Frage gibt, aber ich fand keine wirklich ausreichend (zumindest in Swift). Ich wollte eine Lösung, die genau den gleichen Rand wie ein UITextField bietet (keine ungefähre Lösung, die so aussieht, wie sie jetzt aussieht, sondern eine, die genau so aussieht und immer genau so aussieht). Ich musste ein UITextField verwenden, um die UITextView für den Hintergrund zu sichern, wollte dies aber nicht jedes Mal separat erstellen müssen.

Die folgende Lösung ist eine UITextView, die ein eigenes UITextField für den Rahmen bereitstellt. Dies ist eine abgespeckte Version meiner Volllösung (die der UITextView auf ähnliche Weise "Platzhalter" -Unterstützung hinzufügt) und wurde hier veröffentlicht: 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);
    }        
}
BobDickinson
quelle
3

Eine Möglichkeit, dies ohne Programmierung zu tun, besteht darin, den Hintergrund des Textfelds transparent zu machen und dann einen runden Rechteck-Button dahinter zu platzieren. Stellen Sie sicher, dass Sie die Schaltflächeneinstellungen ändern, um sie zu deaktivieren, und deaktivieren Sie das Kontrollkästchen Bild anpassen deaktivieren.

Versuchte den Quartzcore-Code und stellte fest, dass er bei meinem alten 3G (das ich zum Testen verwende) zu Verzögerungen führte. Kein großes Problem, aber wenn Sie für verschiedene iOS und Hardware so umfassend wie möglich sein möchten, empfehle ich die Antwort von Andrew_L oben - oder erstellen Sie Ihre eigenen Bilder und bewerben Sie sich entsprechend.

Apple Jooce
quelle
3

Es gibt ein großartiges Hintergrundbild, das mit dem UITextViewzum Senden von Textnachrichten in der iPhone-Nachrichten-App verwendeten identisch ist . Sie benötigen Adobe Illustrator, um es zu erhalten und zu ändern. iPhone UI Vektor Elemente

ma11hew28
quelle
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];
}
Sonu
quelle
2

Sie können ein Textfeld erstellen, das keine Ereignisse über einer Textansicht wie folgt akzeptiert:

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
quelle
Oder erstellen Sie einfach ein Textfeld im Interface Builder. Stellen Sie dann die Höhe im Code ein (da der Interface Builder dies nicht zulässt). CGRect frameRect = self.textField.frame; frameRect.size.height = 50; self.textField.frame = frameRect;
Audub
2

Wenn Sie Ihren Controller-Code sauber halten möchten, können Sie UITextView wie unten beschrieben unterordnen und den Klassennamen im Interface Builder ändern.

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
quelle
1

Hier ist meine Lösung:

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

Ich denke nicht, dass es möglich ist. Sie können jedoch UITableView(gruppiert) mit 1 Abschnitt und 1 leeren Zelle arbeiten und diese als Container für Ihre verwenden UITextView.

Morion
quelle
0

Dies ist eine alte Frage, und ich wurde auch nach dieser Antwort gesucht. Die Antwort von luvieeres ist 100% richtig und später fügte Rob Code hinzu. Das ist ausgezeichnet, aber ich habe in einer anderen Frage einen Dritten gefunden , der mir sehr hilfreich erscheint. Ich wurde nicht nur nach einem ähnlichen Aussehen von UITextFieldOver gesucht, sondern UITextViewauch nach mehrzeiliger Unterstützung. ChatInputSample hat beide erfüllt. Deshalb denke ich, dass dieser Dritte für andere hilfreich sein könnte. Auch dank Timur erwähnte er diese Open Source hier .

Sumon
quelle
0

In iOS7 stimmt Folgendes perfekt mit dem UITextField-Rand überein (zumindest für mich):

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

Es ist nicht erforderlich, etwas Besonderes zu importieren.

Danke an @uvieere und @hanumanDev, deren Antworten mich fast dorthin bringen :)

Adrian Toman
quelle
-1

Wie wäre es einfach:

UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 20, 280, 32)];
textField.borderStyle = UITextBorderStyleRoundedRect;
[self addSubview:textField];
Jowie
quelle
Frage ist über Textansicht.
Azik Abdullah
Entschuldigung - lösen Sie eine glückliche Stapelantwort aus. Würde mich interessieren, warum sie nicht einfach ein UITextFieldwith userInteractionEnabledset to verwenden könnten NO.
Jowie
Textfield unterstützt nicht mehrere Zeilen
Azik Abdullah
verstanden. Vielen Dank für die Klarstellung
Jowie