Làm cách nào để tạo kiểu cho UITextview để thích trường văn bản Rounded Rect?


170

Tôi đang sử dụng chế độ xem văn bản như một nhà soạn nhạc bình luận.

Trong trình kiểm tra thuộc tính, tôi không thể tìm thấy bất cứ thứ gì như thuộc tính kiểu viền để tôi có thể sử dụng một chỉnh lưu tròn, đại loại như thế UITextField.

Vì vậy, câu hỏi là: Làm thế nào tôi có thể tạo kiểu UITextViewgiống như UITextFieldvới một chỉnh lưu tròn?


1
Bạn có thể không sử dụng UITextFieldvà chỉ tắt userInteractionEnabled?
jowie

Câu trả lời:


285

Không có kiểu ngầm mà bạn phải chọn, nó liên quan đến việc viết một chút mã bằng cách sử dụng QuartzCorekhung:

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

Nó chỉ hoạt động trên OS 3.0 trở lên, nhưng tôi đoán bây giờ dù sao nó cũng là nền tảng thực tế.


47
Tôi thấy việc thêm đoạn mã trên vào dưới làm cho đường viền trông rất gần với UITextField. [textView.layer setBorderColor: [[[UIColor greyColor] colorWithAlphaComponent: 0.5] CGColor]]; [textView.layer setBorderWidth: 2.0];
Cướp

12
Đảm bảo có: #import <QuartzCore / QuartzCore.h>. Tôi gặp vấn đề vì tôi không nhập QuartzCore
vào

1
Đối với n00bs như tôi, đáng lưu ý: đặt mã này vào viewDidLoad KHÔNG trong initWithNibName :-)
Brian Colavito

1
Bạn chỉ có thể sử dụng một UITextFieldvới thuộc borderStyletính được đặt thành UITextBorderStyleRoundedRect- xem bài viết của tôi dưới đây.
jowie

5
iOS 7 - BorderWidth của 1.0 và alpha của .2 hoạt động với kiểu mặc định.
Kalel Wade

77

mã này hoạt động tốt với tôi:

    [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
Tôi có thể nói rằng 5px gần với các trường văn bản hơn, nhưng màu xám của câu trả lời này tốt hơn câu trả lời được chọn.
Peter De Weese

2
Tất nhiên, bạn cần thêm QuartzCore Framework cho câu trả lời này và nhập nó bằng cách #import <QuartzCore / QuartzCore.h>
lukaswelte

36

Phiên bản Swift 3

Sau khi thiết lập chế độ xem văn bản trong trình tạo giao diện.

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

Phiên bả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
Vấn đề là nó không chính xác màu xám. Màu sắc của khung UITextField hơi khác một chút.
Makalele

1
Tạo .borderWidth = 0.7 làm cho nó trông gần hơn với phong cách hiện tại tôi thấy trên iOS 11.
Chris Amelinckx 23/07/18

28

Chỉnh sửa: Bạn phải nhập

#import <QuartzCore/QuartzCore.h>

để sử dụng bán kính góc.

Hãy thử nó sẽ hoạt động chắc chắn

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

Như Rob đã tìm ra, nếu bạn muốn màu đường viền giống nhau UITextFieldthì bạn cần thay đổi độ rộng đường viền thành 2.0 và tô màu thành màu xám bằng cách thêm dòng sau

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

2
Tôi đã tự hỏi tại sao điều này không làm việc. Cảm ơn vì lời khuyên về QuartzCore.
Echilon

23

Tôi muốn thỏa thuận thực sự, vì vậy tôi thêm UIImageViewvào như một cuộc phỏng vấn của UITextView. Điều này khớp với đường viền gốc trên a UITextField, bao gồm cả gradient từ trên xuống dưới:

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

Đây là những hình ảnh tôi sử dụng:

nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây


2
Tôi nghĩ bạn cũng cần nói với textView để có UITextBorderStyle Không có gì nếu bạn chưa đặt trong XCode
superlogical

1
Tôi đã tải lên lại hình ảnh png
Ben Packard

5
Không tốt, nền di chuyển khi bạn cuộn UITextView. Đoán tôi sẽ phải đặt tất cả trong một UIView cha.
Oliver Pearmain

1
Thông minh. Trông thật tuyệt: D
Sune Trudslev

12

Một giải pháp là thêm UITextField bên dưới UITextView , làm cho UITextViewnền trong suốt và vô hiệu hóa mọi tương tác của người dùng trên UITextField. Sau đó, trong mã thay đổi UITextFieldkhung với một cái gì đó như thế

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

Bạn sẽ có giao diện giống hệt như trường văn bản.

Và theo đề xuất của Jon , bạn nên đặt đoạn mã này vào trong [UIViewController viewDidLayoutSubviews]iOS 5.0 trở lên.


1
Điều này rất đơn giản và trông chính xác như tôi muốn. Tôi vừa khớp khung của UITextField với UITextView: CGRect frame = self.myTextView.frame; frame.size.height + = 2; self.myTextField.frame = khung;
Brian

1
Câu trả lời đáng yêu. Sạch sẽ và đơn giản. Đặt mã vào viewDidLayoutSubviews:(iOS 5.0+).
Jon

1
Thật tuyệt, đây là lần cuối cùng tôi đi cùng. Lưu ý rằng nó không hoạt động cho đến khi tôi sử dụng bình luận của Jon re: viewDidLayoutSubviews:
daver

1
Đây là cách nhanh nhất và có vẻ tốt nhất.
Weston

5

Để có hiệu quả tốt nhất, bạn phải sử dụng hình nền tùy chỉnh (có thể kéo dài). Đây cũng là cách UITextFieldđường viền tròn được vẽ.


4

Một cách tôi tìm thấy để làm điều đó mà không cần lập trình là làm cho nền văn bản trong suốt, sau đó đặt Nút Rect Round phía sau nó. Đảm bảo thay đổi cài đặt nút để tắt và bỏ chọn Disable adjusts imagehộp kiểm.


4

Bạn có thể muốn kiểm tra thư viện của tôi được gọi là DCKit .

Bạn có thể tạo chế độ xem văn bản góc tròn (cũng như trường văn bản / nút / đơn giản UIView) từ Interface Buildertrực tiếp:

DCKit: giáp UITextView

Nó cũng có nhiều tính năng hữu ích khác, chẳng hạn như các trường văn bản có xác thực, điều khiển với viền, viền đứt, hình tròn và đường viền tóc, v.v.


4

Tôi biết đã có rất nhiều câu trả lời cho câu hỏi này, nhưng tôi thực sự không tìm thấy câu trả lời nào đủ (ít nhất là trong Swift). Tôi muốn một giải pháp cung cấp đường viền chính xác giống như UITextField (không phải là một giải pháp gần đúng trông giống như bây giờ, nhưng một giải pháp trông giống hệt nó và sẽ luôn trông giống hệt nó). Tôi cần sử dụng UITextField để sao lưu UITextView cho nền, nhưng không muốn tạo riêng biệt mỗi lần.

Giải pháp dưới đây là UITextView cung cấp UITextField của riêng nó cho đường viền. Đây là phiên bản rút gọn của giải pháp đầy đủ của tôi (có thêm hỗ trợ "giữ chỗ" cho UITextView theo cách tương tự) và đã được đăng ở đây: 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

Một cách tôi tìm thấy để làm điều đó mà không cần lập trình là làm cho nền văn bản trong suốt, sau đó đặt Nút Rect Round phía sau nó. Đảm bảo thay đổi cài đặt nút để tắt nó và bỏ chọn hộp kiểm Tắt điều chỉnh hình ảnh.

Đã thử mã Quartzcore và thấy nó gây ra độ trễ trên 3G cũ của tôi (tôi sử dụng để thử nghiệm). Không phải là một vấn đề lớn nhưng nếu bạn muốn bao quát hết mức có thể cho các ios và phần cứng khác nhau, tôi khuyên bạn nên trả lời câu hỏi của Andrew_L ở trên - hoặc tạo hình ảnh của riêng bạn và áp dụng theo đó.


3

Có một hình nền tuyệt vời giống hệt với hình ảnh được UITextViewsử dụng để gửi tin nhắn văn bản trong ứng dụng Tin nhắn của iPhone. Bạn sẽ cần Adobe Illustrator để lấy và sửa đổi nó. yếu tố vector 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

Bạn có thể tạo Trường văn bản không chấp nhận bất kỳ sự kiện nào ở trên Chế độ xem văn bản như sau:

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;

Hoặc chỉ cần tạo một trường văn bản trong trình xây dựng giao diện. Sau đó đặt chiều cao trong mã (vì trình tạo giao diện sẽ không cho phép bạn). CGRect frameRect = self.textField.frame; frameRect.size.height = 50; self.textField.frame = frameRect;
audub

2

Nếu bạn muốn giữ mã bộ điều khiển của mình sạch sẽ, bạn có thể phân lớp UITextView như bên dưới và thay đổi tên lớp trong Trình tạo giao diện.

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

Đây là giải pháp của tôi:

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

Tôi không nghĩ rằng nó có thể. nhưng bạn có thể làm UITableView(được nhóm) với 1 phần và 1 ô trống và sử dụng nó làm vùng chứa cho UITextView.


0

Đây là một câu hỏi cũ, và tôi cũng đã được tìm kiếm cho câu hỏi này trả lời. Câu trả lời của luvieeres là chính xác 100% và sau đó Rob đã thêm một số mã. Điều đó thật tuyệt vời, nhưng tôi đã tìm thấy một bên thứ ba trong một câu hỏi khác trả lời có vẻ rất hữu ích cho tôi. Tôi không chỉ được tìm kiếm cho cái nhìn tương tự UITextFieldhơn UITextView, tôi cũng được tìm kiếm để hỗ trợ đa dòng. ChatInputSample hài lòng cả. Đó là lý do tại sao tôi nghĩ rằng bên thứ ba này có thể hữu ích cho những người khác. Cũng nhờ Timur, anh ấy đã đề cập đến nguồn mở này ở đây .


0

Trong iOS7, các điều sau đây khớp hoàn toàn với đường viền UITextField (ít nhất là trong mắt tôi):

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

Không cần phải nhập bất cứ điều gì đặc biệt.

Cảm ơn @uvieere và @hanumanDev có câu trả lời cho tôi gần như vậy :)


-1

Còn về

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

câu hỏi là về textview.
Azik Abdullah

Xin lỗi - kích hoạt phản hồi ngăn xếp hạnh phúc. Sẽ được quan tâm để biết tại sao họ không thể chỉ cần sử dụng một UITextFieldvới userInteractionEnabledcác thiết lập để NO.
jowie

Textfield không hỗ trợ nhiều dòng
Azik Abdullah

hiểu. Cảm ơn đã làm rõ
jowie
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.