Câu trả lời:
Bạn cần sử dụng lớp của view để đặt thuộc tính viền. ví dụ:
#import <QuartzCore/QuartzCore.h>
...
view.layer.borderColor = [UIColor redColor].CGColor;
view.layer.borderWidth = 3.0f;
Bạn cũng cần liên kết với QuartzCore.framework để truy cập chức năng này.
__bridge CGColorRef
. Điều này không hoạt động. Nó cần phải được [UIColor blackColor].CGColor
đề cập trong câu trả lời.
#import <QuartzCore/QuartzCore.h>
không còn cần thiết.
Vì phiên bản mới nhất của Xcode, có một giải pháp tốt hơn cho vấn đề này:
Với @IBInspectable
bạn có thể thiết lập thuộc tính trực tiếp từ bên trong các Attributes Inspector
.
Điều này đặt ra User Defined Runtime Attributes
cho bạn:
Có hai cách tiếp cận để thiết lập điều này:
Tùy chọn 1 (có cập nhật trực tiếp trong Storyboard)
MyCustomView
.UIView
.@IBDesignable
(điều này làm cho bản cập nhật Xem trực tiếp). *@IBInspectable
MyCustomView
`
@IBDesignable
class MyCustomView: UIView {
@IBInspectable var cornerRadius: CGFloat = 0 {
didSet {
layer.cornerRadius = cornerRadius
layer.masksToBounds = cornerRadius > 0
}
}
@IBInspectable var borderWidth: CGFloat = 0 {
didSet {
layer.borderWidth = borderWidth
}
}
@IBInspectable var borderColor: UIColor? {
didSet {
layer.borderColor = borderColor?.CGColor
}
}
}
* @IBDesignable
chỉ hoạt động khi được đặt ở đầuclass MyCustomView
Tùy chọn 2 (không hoạt động kể từ Swift 1.2, xem bình luận)
Mở rộng Lớp UIView của bạn:
extension UIView {
@IBInspectable var cornerRadius: CGFloat = 0 {
didSet {
layer.cornerRadius = cornerRadius
layer.masksToBounds = cornerRadius > 0
}
}
@IBInspectable var borderWidth: CGFloat = 0 {
didSet {
layer.borderWidth = borderWidth
}
}
@IBInspectable var borderColor: UIColor? {
didSet {
layer.borderColor = borderColor?.CGColor
}
}
}
Bằng cách này, Chế độ xem mặc định của bạn luôn có các trường có thể chỉnh sửa thêm đó Attributes Inspector
. Một lợi thế khác là bạn không phải thay đổi lớp MycustomView
mỗi lần. Tuy nhiên, một nhược điểm của điều này là bạn sẽ chỉ thấy những thay đổi của mình khi chạy ứng dụng.
Bạn cũng có thể tạo đường viền với màu của điều ước của bạn ..
view.layer.borderColor = [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1.0].CGColor;
* r, g, b là các giá trị trong khoảng từ 0 đến 255.
Thêm @IBInspectables trong phần mở rộng UIView
extension UIView {
@IBInspectable var borderWidth: CGFloat {
get {
return layer.borderWidth
}
set(newValue) {
layer.borderWidth = newValue
}
}
@IBInspectable var borderColor: UIColor? {
get {
if let color = layer.borderColor {
return UIColor(CGColor: color)
}
return nil
}
set(newValue) {
layer.borderColor = newValue?.CGColor
}
}
}
Và sau đó, bạn sẽ có thể đặt các thuộc tính BorderColor và BorderWidth trực tiếp từ trình kiểm tra thuộc tính. Xem hình ảnh đính kèm
Khi tôi sử dụng giải pháp CALayer của Vladimir và trên đỉnh của chế độ xem tôi có một hình ảnh động, giống như một chế độ UINavestionControll bị loại bỏ, tôi thấy rất nhiều trục trặc xảy ra và có vấn đề về hiệu năng.
Vì vậy, một cách khác để đạt được điều này, nhưng không có trục trặc và mất hiệu suất, là tạo một UIView tùy chỉnh và thực hiện drawRect
thông báo như vậy:
- (void)drawRect:(CGRect)rect
{
CGContextRef contextRef = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(contextRef, 1);
CGContextSetRGBStrokeColor(contextRef, 255.0, 255.0, 255.0, 1.0);
CGContextStrokeRect(contextRef, rect);
}
setNeedsDisplay
trên màn hình. Điều này sẽ buộc vẽ lại UIView và ngầm gọi lại drawRect
. Chưa được thử nghiệm, tho ...
view.layer.borderWidth = 1.0
view.layer.borderColor = UIColor.lightGray.cgColor
Hãy thử mã này:
view.layer.borderColor = [UIColor redColor].CGColor;
view.layer.borderWidth= 2.0;
[view setClipsToBounds:YES];
Tôi sẽ không đề xuất ghi đè drawRect do gây ra hiệu suất.
Thay vào đó, tôi sẽ sửa đổi các thuộc tính của lớp như bên dưới (trong uiview tùy chỉnh của bạn):
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.layer.borderWidth = 2.f;
self.layer.borderColor = [UIColor redColor].CGColor;
}
return self;
Tôi đã không thấy bất kỳ trục trặc nào khi thực hiện phương pháp trên - không chắc tại sao việc đưa vào initWithFrame lại ngăn chặn những điều này ;-)
Tôi muốn thêm câu này vào câu trả lời của @ marczking ( Tùy chọn 1 ) dưới dạng nhận xét, nhưng trạng thái thấp của tôi trên StackOverflow đang ngăn chặn điều đó.
Tôi đã thực hiện một câu trả lời của @ marczking cho Objective C. Hoạt động như sự quyến rũ, cảm ơn @marczking!
UIView + Border.h:
#import <UIKit/UIKit.h>
IB_DESIGNABLE
@interface UIView (Border)
-(void)setBorderColor:(UIColor *)color;
-(void)setBorderWidth:(CGFloat)width;
-(void)setCornerRadius:(CGFloat)radius;
@end
UIView + Border.m:
#import "UIView+Border.h"
@implementation UIView (Border)
// Note: cannot use synthesize in a Category
-(void)setBorderColor:(UIColor *)color
{
self.layer.borderColor = color.CGColor;
}
-(void)setBorderWidth:(CGFloat)width
{
self.layer.borderWidth = width;
}
-(void)setCornerRadius:(CGFloat)radius
{
self.layer.cornerRadius = radius;
self.layer.masksToBounds = radius > 0;
}
@end
@IBInspectable đang hoạt động với tôi trên iOS 9, Swift 2.0
extension UIView {
@IBInspectable var borderWidth: CGFloat {
get {
return layer.borderWidth
}
set(newValue) {
layer.borderWidth = newValue
}
}
@IBInspectable var cornerRadius: CGFloat {
get {
return layer.cornerRadius
}
set(newValue) {
layer.cornerRadius = newValue
}
}
@IBInspectable var borderColor: UIColor? {
get {
if let color = layer.borderColor {
return UIColor(CGColor: color)
}
return nil
}
set(newValue) {
layer.borderColor = newValue?.CGColor
}
}
Nếu bạn không muốn chỉnh sửa lớp của UIView, bạn luôn có thể nhúng chế độ xem trong chế độ xem khác. Chế độ xem chính sẽ có màu nền được đặt thành màu viền. Nó cũng sẽ lớn hơn một chút, tùy thuộc vào độ rộng bạn muốn đường viền.
Tất nhiên, điều này chỉ hoạt động nếu chế độ xem của bạn không trong suốt và bạn chỉ muốn một màu viền duy nhất. OP muốn có đường viền trong chế độ xem, nhưng đây có thể là một sự thay thế khả thi.
Nếu bạn muốn thêm các đường viền khác nhau ở các mặt khác nhau, có thể thêm một khung nhìn phụ với kiểu cụ thể là một cách dễ dàng để đưa ra.