Как добавить границу только на верхней стороне UIView
мой вопрос касается названия.
Я не знаю, как добавить границу в определенную сторону, сверху или снизу, с любой стороны...
layer.border
рисует границу для всего вида...
28 ответов
Я считаю подклассы UIView
и переопределить drawRect
перебор здесь. Почему бы не добавить расширение на UIView
и добавить подвиды границ?
@discardableResult
func addBorders(edges: UIRectEdge,
color: UIColor,
inset: CGFloat = 0.0,
thickness: CGFloat = 1.0) -> [UIView] {
var borders = [UIView]()
@discardableResult
func addBorder(formats: String...) -> UIView {
let border = UIView(frame: .zero)
border.backgroundColor = color
border.translatesAutoresizingMaskIntoConstraints = false
addSubview(border)
addConstraints(formats.flatMap {
NSLayoutConstraint.constraints(withVisualFormat: ,
options: [],
metrics: ["inset": inset, "thickness": thickness],
views: ["border": border]) })
borders.append(border)
return border
}
if edges.contains(.top) || edges.contains(.all) {
addBorder(formats: "V:|-0-[border(==thickness)]", "H:|-inset-[border]-inset-|")
}
if edges.contains(.bottom) || edges.contains(.all) {
addBorder(formats: "V:[border(==thickness)]-0-|", "H:|-inset-[border]-inset-|")
}
if edges.contains(.left) || edges.contains(.all) {
addBorder(formats: "V:|-inset-[border]-inset-|", "H:|-0-[border(==thickness)]")
}
if edges.contains(.right) || edges.contains(.all) {
addBorder(formats: "V:|-inset-[border]-inset-|", "H:[border(==thickness)]-0-|")
}
return borders
}
// Usage:
view.addBorder(edges: [.all]) // All with default arguments
view.addBorder(edges: [.top], color: .green) // Just Top, green, default thickness
view.addBorder(edges: [.left, .right, .bottom], color: .red, thickness: 3) // All except Top, red, thickness 3
С этим кодом вы тоже не привязаны к своему подклассу, вы можете применить его ко всему, что наследуется от UIView
- многоразовый в вашем проекте, и любые другие. Передайте другие аргументы своим методам, чтобы определить другие цвета и ширину. Много вариантов.
Swift версия удивительное дополнение Адама Уэйта 5/5/15:
extension CALayer {
func addBorder(edge: UIRectEdge, color: UIColor, thickness: CGFloat) {
var border = CALayer()
switch edge {
case .Top:
border.frame = CGRectMake(0, 0, CGRectGetWidth(self.frame), thickness)
break
case .Bottom:
border.frame = CGRectMake(0, CGRectGetHeight(self.frame) - thickness, CGRectGetWidth(self.frame), thickness)
break
case .Left:
border.frame = CGRectMake(0, 0, thickness, CGRectGetHeight(self.frame))
break
case .Right:
border.frame = CGRectMake(CGRectGetWidth(self.frame) - thickness, 0, thickness, CGRectGetHeight(self.frame))
break
default:
break
}
border.backgroundColor = color.CGColor;
addSublayer(border)
}
}
Swift 3:
extension CALayer {
func addBorder(edge: UIRectEdge, color: UIColor, thickness: CGFloat) {
let border = CALayer()
switch edge {
case .top:
border.frame = CGRect(x: 0, y: 0, width: frame.width, height: thickness)
case .bottom:
border.frame = CGRect(x: 0, y: frame.height - thickness, width: frame.width, height: thickness)
case .left:
border.frame = CGRect(x: 0, y: 0, width: thickness, height: frame.height)
case .right:
border.frame = CGRect(x: frame.width - thickness, y: 0, width: thickness, height: frame.height)
default:
break
}
border.backgroundColor = color.cgColor;
addSublayer(border)
}
}
лучший способ для меня-категория в UIView, но добавление представлений вместо CALayers, поэтому мы можем воспользоваться Авторезизацией масок, чтобы убедиться, что границы изменяются вместе с супервизором.
- (void)addTopBorderWithColor:(UIColor *)color andWidth:(CGFloat) borderWidth {
UIView *border = [UIView new];
border.backgroundColor = color;
[border setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin];
border.frame = CGRectMake(0, 0, self.frame.size.width, borderWidth);
[self addSubview:border];
}
- (void)addBottomBorderWithColor:(UIColor *)color andWidth:(CGFloat) borderWidth {
UIView *border = [UIView new];
border.backgroundColor = color;
[border setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin];
border.frame = CGRectMake(0, self.frame.size.height - borderWidth, self.frame.size.width, borderWidth);
[self addSubview:border];
}
- (void)addLeftBorderWithColor:(UIColor *)color andWidth:(CGFloat) borderWidth {
UIView *border = [UIView new];
border.backgroundColor = color;
border.frame = CGRectMake(0, 0, borderWidth, self.frame.size.height);
[border setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleRightMargin];
[self addSubview:border];
}
- (void)addRightBorderWithColor:(UIColor *)color andWidth:(CGFloat) borderWidth {
UIView *border = [UIView new];
border.backgroundColor = color;
[border setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin];
border.frame = CGRectMake(self.frame.size.width - borderWidth, 0, borderWidth, self.frame.size.height);
[self addSubview:border];
}
код для выбранного ответа, в случае, если кто-то хочет его.
Примечание: это не работает с autolayout (ака, вращая прибор к ландшафту, etc).
сначала определите толщину:
NSInteger borderThickness = 1;
затем просто скопируйте используйте любой или все из них, чтобы установить границы вы хотите установить.
Верхняя Граница
UIView *topBorder = [UIView new];
topBorder.backgroundColor = [UIColor lightGrayColor];
topBorder.frame = CGRectMake(0, 0, myView.frame.size.width, borderThickness);
[myView addSubview:topBorder];
Нижняя Граница
UIView *bottomBorder = [UIView new];
bottomBorder.backgroundColor = [UIColor lightGrayColor];
bottomBorder.frame = CGRectMake(0, myView.frame.size.height - borderThickness, myView.frame.size.width, borderThickness);
[myView addSubview:bottomBorder];
Левой Границы
UIView *leftBorder = [UIView new];
leftBorder.backgroundColor = [UIColor lightGrayColor];
leftBorder.frame = CGRectMake(0, 0, borderThickness, myView.frame.size.height);
[myView addSubview:leftBorder];
Правой Границы
UIView *rightBorder = [UIView new];
rightBorder.backgroundColor = [UIColor lightGrayColor];
rightBorder.frame = CGRectMake(myView.frame.size.width - borderThickness, 0, borderThickness, myView.frame.size.height);
[myView addSubview:rightBorder];
подкласс UIView
и реализовать drawRect:
в подклассе, например:
С
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextMoveToPoint(context, CGRectGetMinX(rect), CGRectGetMinY(rect));
CGContextAddLineToPoint(context, CGRectGetMaxX(rect), CGRectGetMinY(rect));
CGContextSetStrokeColorWithColor(context, [[UIColor redColor] CGColor] );
CGContextSetLineWidth(context, 2.0);
CGContextStrokePath(context);
}
Swift 4
override func draw(_ rect: CGRect) {
let cgContext = UIGraphicsGetCurrentContext()
cgContext?.move(to: CGPoint(x: rect.minX, y: rect.minY))
cgContext?.addLine(to: CGPoint(x: rect.maxX, y: rect.minY))
cgContext?.setStrokeColor(UIColor.red.cgColor)
cgContext?.setLineWidth(2.0)
cgContext?.strokePath()
}
это рисует 2-пиксельную красную линию в качестве верхней границы. Все остальные варианты, которые вы упомянули, оставлены как тривиальное упражнение для читателя.
руководство по программированию Quartz 2D рекомендуется.
Swift 3.0
Swift 4.1
extension CALayer {
func addBorder(edge: UIRectEdge, color: UIColor, thickness: CGFloat) {
let border = CALayer();
switch edge {
case UIRectEdge.top:
border.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: thickness)
break
case UIRectEdge.bottom:
border.frame = CGRect(x:0, y:self.frame.height - thickness, width:self.frame.width, height:thickness)
break
case UIRectEdge.left:
border.frame = CGRect(x:0, y:0, width: thickness, height: self.frame.height)
break
case UIRectEdge.right:
border.frame = CGRect(x:self.frame.width - thickness, y: 0, width: thickness, height:self.frame.height)
break
default:
break
}
border.backgroundColor = color.cgColor;
self.addSublayer(border)
}
}
Swift версия:
var myView = UIView(frame: CGRect(x: 100, y: 100, width: 100, height: 100))
myView.backgroundColor = UIColor.yellowColor()
var border = CALayer()
border.backgroundColor = UIColor.lightGrayColor()
border.frame = CGRect(x: 0, y: 0, width: myView.frame.width, height: 0.5)
myView.layer.addSublayer(border)
Edit: для обновленных версий проверьте мое РЕПО здесь: https://github.com/goktugyil/EZSwiftExtensions/blob/master/Sources/UIViewExtensions.swift
посмотрите на части addBorder
старый вопрос, но autolayout-решение с настройками границы выполнения все еще отсутствует.
borders(for: [.left, .bottom], width: 2, color: .red)
следующее расширение UIView добавит границу только на заданных ребрах. Если вы измените ребра во время выполнения, границы будут соответствующим образом скорректированы.
extension UIView {
func borders(for edges:[UIRectEdge], width:CGFloat = 1, color: UIColor = .black) {
if edges.contains(.all) {
layer.borderWidth = width
layer.borderColor = color.cgColor
} else {
let allSpecificBorders:[UIRectEdge] = [.top, .bottom, .left, .right]
for edge in allSpecificBorders {
if let v = viewWithTag(Int(edge.rawValue)) {
v.removeFromSuperview()
}
if edges.contains(edge) {
let v = UIView()
v.tag = Int(edge.rawValue)
v.backgroundColor = color
v.translatesAutoresizingMaskIntoConstraints = false
addSubview(v)
var horizontalVisualFormat = "H:"
var verticalVisualFormat = "V:"
switch edge {
case UIRectEdge.bottom:
horizontalVisualFormat += "|-(0)-[v]-(0)-|"
verticalVisualFormat += "[v(\(width))]-(0)-|"
case UIRectEdge.top:
horizontalVisualFormat += "|-(0)-[v]-(0)-|"
verticalVisualFormat += "|-(0)-[v(\(width))]"
case UIRectEdge.left:
horizontalVisualFormat += "|-(0)-[v(\(width))]"
verticalVisualFormat += "|-(0)-[v]-(0)-|"
case UIRectEdge.right:
horizontalVisualFormat += "[v(\(width))]-(0)-|"
verticalVisualFormat += "|-(0)-[v]-(0)-|"
default:
break
}
self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: horizontalVisualFormat, options: .directionLeadingToTrailing, metrics: nil, views: ["v": v]))
self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: verticalVisualFormat, options: .directionLeadingToTrailing, metrics: nil, views: ["v": v]))
}
}
}
}
}
[self.view addBordersToEdge:(UIRectEdgeLeft|UIRectEdgeRight)
withColor:[UIColor grayColor]
andWidth:1.0];
или так:
[self.view addBordersToEdge:(UIRectEdgeAll)
withColor:[UIColor grayColor]
andWidth:1.0];
что вам нужно реализовать, это категория в UIView, как предложено в других ответах со следующей реализацией:
- (void)addBordersToEdge:(UIRectEdge)edge withColor:(UIColor *)color andWidth:(CGFloat) borderWidth {
if (edge & UIRectEdgeTop) {
UIView *border = [UIView new];
border.backgroundColor = color;
[border setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin];
border.frame = CGRectMake(0, 0, self.frame.size.width, borderWidth);
[self addSubview:border];
}
if (edge & UIRectEdgeLeft) {
UIView *border = [UIView new];
border.backgroundColor = color;
border.frame = CGRectMake(0, 0, borderWidth, self.frame.size.height);
[border setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleRightMargin];
[self addSubview:border];
}
if (edge & UIRectEdgeBottom) {
UIView *border = [UIView new];
border.backgroundColor = color;
[border setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin];
border.frame = CGRectMake(0, self.frame.size.height - borderWidth, self.frame.size.width, borderWidth);
[self addSubview:border];
}
if (edge & UIRectEdgeRight) {
UIView *border = [UIView new];
border.backgroundColor = color;
[border setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin];
border.frame = CGRectMake(self.frame.size.width - borderWidth, 0, borderWidth, self.frame.size.height);
[self addSubview:border];
}
}
вот простое решение. Добавьте метку в свой UIView, очистите текст на метке и установите цвет фона метки в качестве цвета границы. Установите начало (x,y) вашей метки как начало (x, y) вашего представления. и установите ширину метки как ширину вашего UIView, установите высоту как 1 или 2 (для вашей высоты границы в верхней части вашего UIView). И это должно сработать.
/ / MARK: - добавить LeftBorder для просмотра
(void)prefix_addLeftBorder:(UIView *) viewName
{
CALayer *leftBorder = [CALayer layer];
leftBorder.backgroundColor = [UIColor colorWithRed:221/255.0f green:221/255.0f blue:221/255.0f alpha:1.0f].CGColor;
leftBorder.frame = CGRectMake(0,0,1.0,viewName.frame.size.height);
[viewName.layer addSublayer:leftBorder];
}
/ / MARK: - добавить RightBorder для просмотра
(void)prefix_addRightBorder:(UIView *) viewName
{
CALayer *rightBorder = [CALayer layer];
rightBorder.backgroundColor = [UIColor colorWithRed:221/255.0f green:221/255.0f blue:221/255.0f alpha:1.0f].CGColor;
rightBorder.frame = CGRectMake(viewName.frame.size.width - 1.0,0,1.0,viewName.frame.size.height);
[viewName.layer addSublayer:rightBorder];
}
/ / MARK: - добавить нижнюю границу для просмотра
(void)prefix_addbottomBorder:(UIView *) viewName
{
CALayer *bottomBorder = [CALayer layer];
bottomBorder.backgroundColor = [UIColor colorWithRed:221/255.0f green:221/255.0f blue:221/255.0f alpha:1.0f].CGColor;
bottomBorder.frame = CGRectMake(0,viewName.frame.size.height - 1.0,viewName.frame.size.width,1.0);
[viewName.layer addSublayer:bottomBorder];
}
строительство NSBum это ответ, я принял аналогичный подход и создал этот простой подкласс UIView, чтобы он работал в Interface Builder и работал с ограничениями:ссылка github
Используя CGContextFillRect вместо CGContextStrokePath, я смог предсказуемо сохранить линии полностью твердыми и в пределах представления.
вот мой пост в блоге об этом: http://natrosoft.com/?p=55
-- в основном просто зайдите в UIView в Interface Builder и измените его тип класса на NAUIViewWithBorders.
-- Тогда в viewDidLoad вашего VC сделайте что-то вроде:
/* For a top border only ———————————————- */
self.myBorderView.borderColorTop = [UIColor redColor];
self.myBorderView..borderWidthsAll = 1.0f;
/* For borders with different colors and widths ————————— */
self.myBorderView.borderWidths = UIEdgeInsetsMake(2.0, 4.0, 6.0, 8.0);
self.myBorderView.borderColorTop = [UIColor blueColor];
self.myBorderView.borderColorRight = [UIColor redColor];
self.myBorderView.borderColorBottom = [UIColor greenColor];
self.myBorderView.borderColorLeft = [UIColor darkGrayColor];
вот прямая ссылка на .файл м таким образом, вы можете увидеть реализацию. Есть и демо-проект. Надеюсь, это кому-то поможет:)
мой ответ на аналогичный вопрос:https://stackoverflow.com/a/27141956/435766 Я лично предпочитаю идти по дороге категории на этом, так как я хочу иметь возможность использовать его на любом подклассе UIView.
я внес некоторые изменения в Дэн чтобы я мог добавлять границы к нескольким ребрам с помощью одной команды:
infoView.addBorder(toEdges: [.left, .bottom, .right], color: borderColor, thickness: 1)
вот полный код:
extension UIView {
func addBorder(toEdges edges: UIRectEdge, color: UIColor, thickness: CGFloat) {
func addBorder(toEdge edges: UIRectEdge, color: UIColor, thickness: CGFloat) {
let border = CALayer()
border.backgroundColor = color.cgColor
switch edges {
case .top:
border.frame = CGRect(x: 0, y: 0, width: frame.width, height: thickness)
case .bottom:
border.frame = CGRect(x: 0, y: frame.height - thickness, width: frame.width, height: thickness)
case .left:
border.frame = CGRect(x: 0, y: 0, width: thickness, height: frame.height)
case .right:
border.frame = CGRect(x: frame.width - thickness, y: 0, width: thickness, height: frame.height)
default:
break
}
layer.addSublayer(border)
}
if edges.contains(.top) || edges.contains(.all) {
addBorder(toEdge: .top, color: color, thickness: thickness)
}
if edges.contains(.bottom) || edges.contains(.all) {
addBorder(toEdge: .bottom, color: color, thickness: thickness)
}
if edges.contains(.left) || edges.contains(.all) {
addBorder(toEdge: .left, color: color, thickness: thickness)
}
if edges.contains(.right) || edges.contains(.all) {
addBorder(toEdge: .right, color: color, thickness: thickness)
}
}
}
Если я строю из раскадровки, я предпочитаю добавить UIView за моим полезным UIView... Если я хочу создать границу в верхней части моего UIView, я просто увеличиваю высоту фона UIView на ширину границы.. То же самое можно сделать для любой другой стороне :)
просто разместите здесь, чтобы помочь кому-то, кто ищет добавление границ. Я сделал несколько изменений в принятом ответе здесь swift label только граница слева.
Изменена ширина в случае UIRectEdge.Top
С CGRectGetHeight(self.frame)
to CGRectGetWidth(self.frame)
и в случае UIRectEdge.Bottom
С UIScreen.mainScreen().bounds.width
to CGRectGetWidth(self.frame)
чтобы правильно получить границы. Использование Swift 2.
наконец-то расширения-это :
extension CALayer {
func addBorder(edge: UIRectEdge, color: UIColor, thickness: CGFloat) {
let border = CALayer();
switch edge {
case UIRectEdge.Top:
border.frame = CGRectMake(0, 0, CGRectGetWidth(self.frame), thickness);
break
case UIRectEdge.Bottom:
border.frame = CGRectMake(0, CGRectGetHeight(self.frame) - thickness, CGRectGetWidth(self.frame), thickness)
break
case UIRectEdge.Left:
border.frame = CGRectMake(0, 0, thickness, CGRectGetHeight(self.frame))
break
case UIRectEdge.Right:
border.frame = CGRectMake(CGRectGetWidth(self.frame) - thickness, 0, thickness, CGRectGetHeight(self.frame))
break
default:
break
}
border.backgroundColor = color.CGColor;
self.addSublayer(border)
}
}
в случае, если кому-то понадобится версия Xamarin:
public static class UIUtils
{
public static void AddBorder(this CALayer cALayer, UIRectEdge edge, UIColor color, float thickness)
{
var border = new CALayer();
switch (edge)
{
case UIRectEdge.Top:
border.Frame = new CGRect(0, 0, cALayer.Frame.Width, height: thickness);
break;
case UIRectEdge.Bottom:
border.Frame = new CGRect(0, cALayer.Frame.Height - thickness, width: cALayer.Frame.Width, height: thickness);
break;
case UIRectEdge.Left:
border.Frame = new CGRect(0, 0, width: thickness, height: cALayer.Frame.Height);
break;
case UIRectEdge.Right:
border.Frame = new CGRect(cALayer.Frame.Width - thickness, y: 0, width: thickness, height: cALayer.Frame.Height);
break;
default: break;
}
border.BackgroundColor = color.CGColor;
cALayer.AddSublayer(border);
}
}
вот Swift 4 версия ответ Паулса
func addTopBorder(color: UIColor, thickness: CGFloat) {
let border = UIView()
border.backgroundColor = color
border.autoresizingMask = [.flexibleWidth, .flexibleBottomMargin]
border.frame = CGRect(x: 0, y: 0, width: frame.size.width, height: thickness)
addSubview(border)
}
func addBottomBorder(color: UIColor, thickness: CGFloat) {
let border = UIView()
border.backgroundColor = color
border.autoresizingMask = [.flexibleWidth, .flexibleTopMargin]
border.frame = CGRect(x: 0, y: frame.size.height - thickness, width: frame.size.width, height: thickness)
addSubview(border)
}
func addLeftBorder(color: UIColor, thickness: CGFloat) {
let border = UIView()
border.backgroundColor = color
border.autoresizingMask = [.flexibleHeight, .flexibleRightMargin]
border.frame = CGRect(x: 0, y: 0, width: thickness, height: frame.size.height)
addSubview(border)
}
func addRightBorder(color: UIColor, thickness: CGFloat) {
let border = UIView()
border.backgroundColor = color
border.autoresizingMask = [.flexibleHeight, .flexibleLeftMargin]
border.frame = CGRect(x: frame.size.width - thickness, y: 0, width: thickness, height: frame.size.height)
addSubview(border)
}
лично мне нравится подкласс view + drawRect, но вот еще один способ сделать это (и он работает в том же направлении, что и принятый ответ @If Pollavith):
ваш новый пограничный слой может быть настроен так, чтобы иметь любые размеры, которые вам нравятся. Итак, как и ответ @If Pollavith, вы создаете слой, который будет таким высоким, каким вы хотите, и таким широким, как представление, которое вы хотите граничить. Используйте определение рамки слоя, чтобы разместить его там, где вы хотите, а затем добавьте его в качестве подслоя к вашему представлению.
для справки, мое собственное требование заключалось в том, чтобы поставить границу в левой части представления (пожалуйста, не вырезайте и не вставляйте этот код, и dis' me просто потому, что он не ставит границу в верхней части представления-изменение кода ниже достаточно просто):
CALayer *leftBorder = [CALayer layer];
leftBorder.borderColor = [UIColor colorWithRed:0.0 green:91.0/255.0 blue:141.0/255.0 alpha:1.0].CGColor;
leftBorder.borderWidth = 1;
leftBorder.frame = CGRectMake(0, 0, 1.0, CGRectGetHeight(self.myTargetView.frame));
[self.myTargetView.layer addSublayer:leftBorder];
Я думаю, что единственное умеренное преимущество над этим и создание небольшого UIView или UILabel заключается в том, что CALayer предположительно "легче", и есть много интересного мнения (как в мнениях) о чрезмерной езде drawRect против использования CALayers (как здесь:iOS: использование UIView "drawRect:" против его слоя delagate " drawLayer:inContext:").
Animal451
Мне нравится синий цвет.
преобразование DanShev ответ на Swift 3
extension CALayer {
func addBorder(edge: UIRectEdge, color: UIColor, thickness: CGFloat) {
let border = CALayer()
switch edge {
case .top:
border.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: thickness)
break
case .bottom:
border.frame = CGRect(x: 0, y: self.frame.height - thickness, width: self.frame.width, height: thickness)
break
case .left:
border.frame = CGRect(x: 0, y: 0, width: thickness, height: self.frame.height)
break
case .right:
border.frame = CGRect(x: self.frame.width - thickness, y: 0, width: thickness, height: self.frame.height)
break
default:
break
}
border.backgroundColor = color.cgColor;
self.addSublayer(border)
}
}
для Xamarin в C# я просто создаю границу inline при добавлении подслоя
View.Layer.AddSublayer(new CALayer()
{
BackgroundColor = UIColor.Black.CGColor,
Frame = new CGRect(0, 0, View.Frame.Width, 0.5f)
});
вы можете сделать это (как полагают другие) для нижней, левой и правой границ.
вы также можете проверить эту коллекцию категорий UIKit и Foundation:https://github.com/leszek-s/LSCategories
это позволяет добавить границу на одной стороне UIView с одной строкой кода:
[self.someView lsAddBorderOnEdge:UIRectEdgeTop color:[UIColor blueColor] width:2];
и он правильно обрабатывает вращение представления, в то время как большинство ответов, размещенных здесь, не справляются с этим хорошо.
Примечание: большинство решений здесь не являются адаптивными и не изменяют размер. Решения, которые будут изменять размер, будут иметь огромные влияние на время запуска, так как они используют много CPU.
вы можете использовать это решение ниже. Он работает на UIBezierPaths, которые легче, чем слои, вызывая быстрое время запуска. Он прост в использовании, см. инструкции ниже.
class ResizeBorderView: UIView {
var color = UIColor.white
var lineWidth: CGFloat = 1
var edges = [UIRectEdge](){
didSet {
setNeedsDisplay()
}
}
override func draw(_ rect: CGRect) {
if edges.contains(.top) || edges.contains(.all){
let path = UIBezierPath()
path.lineWidth = lineWidth
color.setStroke()
UIColor.blue.setFill()
path.move(to: CGPoint(x: 0, y: 0 + lineWidth / 2))
path.addLine(to: CGPoint(x: self.bounds.width, y: 0 + lineWidth / 2))
path.stroke()
}
if edges.contains(.bottom) || edges.contains(.all){
let path = UIBezierPath()
path.lineWidth = lineWidth
color.setStroke()
UIColor.blue.setFill()
path.move(to: CGPoint(x: 0, y: self.bounds.height - lineWidth / 2))
path.addLine(to: CGPoint(x: self.bounds.width, y: self.bounds.height - lineWidth / 2))
path.stroke()
}
if edges.contains(.left) || edges.contains(.all){
let path = UIBezierPath()
path.lineWidth = lineWidth
color.setStroke()
UIColor.blue.setFill()
path.move(to: CGPoint(x: 0 + lineWidth / 2, y: 0))
path.addLine(to: CGPoint(x: 0 + lineWidth / 2, y: self.bounds.height))
path.stroke()
}
if edges.contains(.right) || edges.contains(.all){
let path = UIBezierPath()
path.lineWidth = lineWidth
color.setStroke()
UIColor.blue.setFill()
path.move(to: CGPoint(x: self.bounds.width - lineWidth / 2, y: 0))
path.addLine(to: CGPoint(x: self.bounds.width - lineWidth / 2, y: self.bounds.height))
path.stroke()
}
}
}
- установите класс UIView в ResizeBorderView
- задать цвет и ширину линии с помощью yourview.цвет и yourview.lineWidth в вашем методе viewDidAppear
- установите ребра, например: yourview.стыки.[ = право. ,влево.[( ]все]) для всех
- наслаждайтесь быстрый старт и изменение размера границ
для установки верхней границы и нижней границы для UIView в Swift.
let topBorder = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: 1))
topBorder.backgroundColor = UIColor.black
myView.addSubview(topBorder)
let bottomBorder = UIView(frame: CGRect(x: 0, y: myView.frame.size.height - 1, width: 10, height: 1))
bottomBorder.backgroundColor = UIColor.black
myView.addSubview(bottomBorder)
в Swift 4 и 3
let borderThickness = 2
let topBorder = UIView()
topBorder.backgroundColor = UIColor.red
topBorder.frame = CGRect(x: 0, y: 0, width:
Int(yourViewFromOutlet.frame.size.width), height:
borderThickness)
yourViewFromOutlet.addSubview(topBorder)
Я придумал решение с использованием Swift 4.1, которое использует AutoLayout и UIViews, чтобы он изменял размер с представлением.
Он основан на ответе @AdamWaite, но решает проблему для ячеек представления таблицы, где ячейки используются повторно. Если предыдущая граница не удаляется перед добавлением новой, ТО повторно используемая ячейка будет содержать несколько границ.
это решается путем создания фиктивного класса BorderView и поиска подвида для границ и удаления их.
этот код использует SnapKit для ограничений и CocoaLumberjack для отладки. Если вы не используете их, то это должно быть довольно просто преобразовать
class BorderView: UIView {
}
extension UIView {
private func addSidedBorder(toEdge edge: UIRectEdge, withColor color: UIColor, inset: CGFloat, thickness: CGFloat) {
let border = BorderView(frame: .zero)
border.backgroundColor = color
addSubview(border)
border.snp.makeConstraints { make in
switch edge {
case .top:
make.top.equalToSuperview()
make.height.equalTo(thickness)
make.left.right.equalToSuperview().inset(inset)
case .left:
make.left.equalToSuperview()
make.width.equalTo(thickness)
make.top.bottom.equalToSuperview().inset(inset)
case .bottom:
make.bottom.equalToSuperview()
make.height.equalTo(thickness)
make.left.right.equalToSuperview().inset(inset)
case .right:
make.right.equalToSuperview()
make.width.equalTo(thickness)
make.top.bottom.equalToSuperview().inset(inset)
default:
DDLogWarn("Invalid sided border given in ExtendedUIView, border not added correctly")
}
}
}
func addBorder(toEdge edge: UIRectEdge, withColor color: UIColor = .black, inset: CGFloat = 0.0, thickness: CGFloat = 1.0) {
// Remove existing borders from view and readd them
for view in subviews {
if view is BorderView {
view.removeFromSuperview()
}
}
if edge.contains(.all) {
addSidedBorder(toEdge: .top, withColor: color, inset: inset, thickness: thickness)
addSidedBorder(toEdge: .left, withColor: color, inset: inset, thickness: thickness)
addSidedBorder(toEdge: .bottom, withColor: color, inset: inset, thickness: thickness)
addSidedBorder(toEdge: .right, withColor: color, inset: inset, thickness: thickness)
} else {
if edge.contains(.top) {
addSidedBorder(toEdge: .top, withColor: color, inset: inset, thickness: thickness)
}
if edge.contains(.left) {
addSidedBorder(toEdge: .left, withColor: color, inset: inset, thickness: thickness)
}
if edge.contains(.bottom) {
addSidedBorder(toEdge: .bottom, withColor: color, inset: inset, thickness: thickness)
}
if edge.contains(.right) {
addSidedBorder(toEdge: .right, withColor: color, inset: inset, thickness: thickness)
}
}
}
}
добавьте этот код, а затем в классе, который подклассы UIView, вызовите:
view.addBorder(toEdge: [.left, .right], withColor: .red, inset: 0.0, thickness: 1.0)
используйте ниже код в viewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view.layer setBorderWidth: 1.0];
[self.view.layer setCornerRadius:8.0f];
[self.view.layer setMasksToBounds:YES];
[self.view.layer setBorderColor:[[UIColor colorWithRed:251.0f/255.0f green:185.0f/255.0f blue:23.0f/255.0f alpha:1.0f]];`
}
этот код устанавливает красную границу цвета для вашего вида