Bagaimana gaya UITextview untuk menyukai bidang teks Rounded Rect?

170

Saya menggunakan tampilan teks sebagai komposer komentar.

Di properti inspektur saya tidak dapat menemukan apa pun seperti properti gaya perbatasan sehingga saya dapat menggunakan kotak bulat, seperti UITextField.

Jadi, pertanyaannya adalah: Bagaimana saya bisa bergaya UITextViewseperti UITextFielddengan persegi panjang?

harshalb
sumber
1
Bisakah Anda tidak menggunakan UITextFielddan mematikan saja userInteractionEnabled?
jowie

Jawaban:

285

Tidak ada gaya implisit yang harus Anda pilih, ini melibatkan penulisan sedikit kode menggunakan QuartzCorekerangka kerja:

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

Ini hanya bekerja pada OS 3.0 dan di atasnya, tapi saya kira sekarang ini adalah platform de facto.

luvieere
sumber
47
Saya menemukan menambahkan atas berikut kode di atas membuat perbatasan terlihat sangat dekat dengan UITextField. [textView.layer setBorderColor: [[[UIColor grayColor] colorWithAlphaComponent: 0,5] CGColor]]; [textView.layer setBorderWidth: 2.0];
Rob
12
Pastikan untuk memiliki: #import <QuartzCore / QuartzCore.h>. Saya mempunyai masalah karena saya tidak mengimpor QuartzCore
austen
1
Untuk n00bs seperti saya, patut dicatat: letakkan kode ini di viewDidLoad NOT initWithNibName :-)
Brian Colavito
1
Anda cukup menggunakan a UITextFielddengan borderStyleproperti disetel ke UITextBorderStyleRoundedRect- lihat posting saya di bawah ini.
jowie
5
iOS 7 - borderWidth dari 1.0 dan alpha dari .2 bekerja dengan gaya default.
Kalel Wade
77

kode ini bekerja dengan baik untuk saya:

    [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
sumber
4
Saya akan mengatakan bahwa 5px lebih dekat dengan bidang teks, tetapi warna abu-abu jawaban ini lebih baik daripada jawaban yang dipilih.
Peter DeWeese
2
Tentu saja Anda perlu menambahkan QuartzCore Framework untuk jawaban ini dan mengimpornya dengan #import <QuartzCore / QuartzCore.h>
lukaswelte
36

Versi Swift 3

Setelah mengatur tampilan teks dalam pembangun antarmuka.

@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 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
}
Sean McClory
sumber
1
Masalahnya adalah tidak abu-abu. Warna bingkai UITextField sedikit berbeda.
Makalele
1
Pembuatan .borderWidth = 0.7 membuatnya terlihat lebih dekat dengan gaya saat ini yang saya lihat di iOS 11.
Chris Amelinckx
28

Sunting: Anda harus mengimpor

#import <QuartzCore/QuartzCore.h>

untuk menggunakan jari-jari sudut.

Coba ini pasti akan berhasil

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

Seperti yang dipecahkan oleh Rob, pengaturan jika Anda ingin warna garis tepi sama UITextFieldmaka Anda perlu mengubah lebar garis menjadi 2.0 dan warna menjadi abu-abu dengan menambahkan baris berikut

[textView.layer setBorderColor:[[[UIColor grayColor] colorWithAlphaComponent:0.5] CGColor]]; 
[textView.layer setBorderWidth:2.0];
Suresh Varma
sumber
2
Saya bertanya-tanya mengapa ini tidak berhasil. Terima kasih atas informasi tentang QuartzCore.
Echilon
23

Saya ingin yang sebenarnya, jadi saya tambahkan UIImageViewsebagai subview dari UITextView. Ini cocok dengan batas asli pada a UITextField, termasuk gradien dari atas ke bawah:

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

Ini adalah gambar yang saya gunakan:

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

Ben Packard
sumber
2
Saya pikir Anda juga perlu memberi tahu textView agar UITextBorderStyle Tidak ada jika Anda belum menyetelnya di
XCode
1
Saya mengunggah ulang gambar png
Ben Packard
5
Tidak bagus, latar belakang bergerak saat Anda menggulir UITextView. Kira saya harus meletakkan semuanya di induk UIView.
Oliver Pearmain
1
Luar biasa. Itu tampak hebat: D
Sune Trudslev
12

Salah satu solusinya adalah menambahkan UITextField di bawah UITextView , menjadikan UITextViewlatar belakang transparan dan menonaktifkan interaksi pengguna di UITextField. Kemudian dalam kode ubah UITextFieldframe dengan sesuatu seperti itu

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

Anda akan memiliki tampilan yang sama persis dengan bidang teks.

Dan seperti yang disarankan oleh Jon , Anda harus memasukkan kode ini ke dalam [UIViewController viewDidLayoutSubviews]iOS 5.0+.

Phil
sumber
1
Ini sangat sederhana dan terlihat persis seperti yang saya inginkan. Saya baru saja mencocokkan frame dari UITextField ke UITextView: CGRect frame = self.myTextView.frame; frame.size.height + = 2; self.myTextField.frame = bingkai;
Buyin Brian
1
Jawaban yang bagus. Bersih dan sederhana. Masukkan kode viewDidLayoutSubviews:(iOS 5.0+).
Jon
1
Bagus, ini adalah soln yang saya ikuti pada akhirnya. Perhatikan bahwa itu tidak berfungsi sampai saya menggunakan komentar Jon re: viewDidLayoutSubviews:
daver
1
Ini yang tercepat, dan terlihat yang terbaik.
Weston
5

Untuk efek terbaik, Anda harus menggunakan gambar latar kustom (dapat ditarik). Ini juga bagaimana UITextFieldperbatasan bulat ditarik.

kennytm
sumber
4

Salah satu cara yang saya temukan untuk melakukannya tanpa pemrograman adalah membuat latar belakang textfield transparan, lalu letakkan Round Round Button di belakangnya. Pastikan untuk mengubah pengaturan tombol untuk menonaktifkannya dan hapus centang pada Disable adjusts imagekotak centang.

Andrew_L
sumber
4

Anda mungkin ingin memeriksa perpustakaan saya yang disebut DCKit .

Anda dapat membuat tampilan teks sudut bundar (serta bidang teks / tombol / polos UIView) dari Interface Builderlangsung:

DCKit: berbatasan UITextView

Ini juga memiliki banyak fitur berguna lainnya, seperti bidang teks dengan validasi, kontrol dengan batas, garis putus-putus, tampilan lingkaran dan garis rambut dll.

Andrey Gordeev
sumber
4

Saya tahu sudah ada banyak jawaban untuk yang ini, tetapi saya tidak benar-benar menemukan satu pun dari mereka cukup (setidaknya di Swift). Saya menginginkan solusi yang memberikan batas persis sama dengan UITextField (bukan yang diperkirakan yang terlihat seperti itu terlihat sekarang, tetapi yang terlihat persis seperti itu dan akan selalu terlihat persis seperti itu). Saya perlu menggunakan UITextField untuk mendukung UITextView sebagai latar belakang, tetapi tidak ingin harus membuatnya secara terpisah setiap waktu.

Solusi di bawah ini adalah UITextView yang memasok UITextField sendiri untuk perbatasan. Ini adalah versi lengkap dari solusi lengkap saya (yang menambahkan dukungan "placeholder" ke UITextView dengan cara yang serupa) dan diposting di sini: 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
sumber
3

Salah satu cara yang saya temukan untuk melakukannya tanpa pemrograman adalah membuat latar belakang textfield transparan, lalu letakkan Round Round Button di belakangnya. Pastikan untuk mengubah pengaturan tombol untuk menonaktifkannya dan hapus centang pada kotak centang Nonaktifkan menyesuaikan gambar.

Mencoba kode Quartzcore dan menemukannya menyebabkan kelambatan pada 3G lama saya (saya gunakan untuk pengujian). Bukan masalah besar tetapi jika Anda ingin menjadi inklusif mungkin untuk ios dan perangkat keras yang berbeda, saya sarankan jawaban Andrew_L di atas - atau buat gambar Anda sendiri dan terapkan sesuai itu.

Apple Jooce
sumber
3

Ada gambar latar belakang yang bagus yang identik dengan yang UITextViewdigunakan untuk mengirim pesan teks di aplikasi Pesan iPhone. Anda memerlukan Adobe Illustrator untuk mendapatkan & memodifikasinya. elemen vektor iphone ui

ma11hew28
sumber
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
sumber
2

Anda dapat membuat Bidang Teks yang tidak menerima acara apa pun di atas Tampilan Teks seperti ini:

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
sumber
Atau hanya membuat bidang teks dalam pembangun antarmuka. Kemudian atur tinggi kode (karena pembuat antarmuka tidak akan membiarkan Anda). CGRect frameRect = self.textField.frame; frameRect.size.height = 50; self.textField.frame = frameRect;
audub
2

Jika Anda ingin menjaga kode controller Anda tetap bersih, Anda dapat subkelas UITextView seperti di bawah ini, dan mengubah nama kelas di 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
Satoshi Nakajima
sumber
1

Ini solusinya:

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

Saya pikir itu tidak mungkin. tetapi Anda dapat melakukan UITableView(dikelompokkan) dengan 1 bagian dan 1 sel kosong dan menggunakannya sebagai wadah untuk Anda UITextView.

Morion
sumber
0

Ini adalah pertanyaan lama, dan saya juga mencari jawaban pertanyaan ini. Jawaban luvieeres adalah 100% benar dan kemudian Rob menambahkan beberapa kode. Itu luar biasa, tetapi saya menemukan pihak ketiga dalam jawaban pertanyaan lain yang tampaknya sangat membantu saya. Saya tidak hanya mencari tampilan yang sama dari UITextFieldatas UITextView, saya juga mencari dukungan multiline. ChatInputSample memuaskan keduanya. Itulah mengapa saya pikir pihak ketiga ini mungkin bermanfaat bagi orang lain. Terima kasih juga kepada Timur, ia menyebutkan open source ini di sini .

memanggil
sumber
0

Di iOS7, berikut ini cocok dengan batas UITextField dengan sempurna (setidaknya bagi saya):

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

Tidak perlu mengimpor sesuatu yang istimewa.

Terima kasih kepada @uvieere dan @hanumanDev yang jawabannya hampir membuat saya :)

Adrian Toman
sumber
-1

Bagaimana kalau saja:

UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 20, 280, 32)];
textField.borderStyle = UITextBorderStyleRoundedRect;
[self addSubview:textField];
jowie
sumber
pertanyaannya adalah tentang tampilan teks.
Azik Abdullah
Maaf - memicu respons tumpukan bahagia. Akan tertarik untuk mengetahui mengapa mereka tidak bisa hanya menggunakan UITextFielddengan userInteractionEnabledset ke NO.
jowie
Textfield tidak mendukung banyak baris
Azik Abdullah
dimengerti. Terima kasih telah mengklarifikasi
jowie