我的问题是标题。
我不知道如何在特定的一侧,顶部或底部,任何一侧添加边框......
layer.border
为整个视图绘制边框......
答案 0 :(得分:187)
我认为在这里继承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: $0,
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
继承的所有内容 - 可在项目中重用,以及其他任何内容。将其他参数传递给您的方法以定义其他颜色和宽度。很多选择。
答案 1 :(得分:87)
Adam Waite's awesome 5/5/15 addition的快速版本:
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)
}
}
斯威夫特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)
}
}
答案 2 :(得分:41)
对我来说最好的方法是UIView上的类别,但是添加了视图而不是CALayers,因此我们可以利用AutoresizingMasks来确保边框与superview一起调整大小。
- (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];
}
答案 3 :(得分:24)
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)
}
}
答案 4 :(得分:21)
子类UIView
并在子类中实现drawRect:
,例如:
<强>目标c 强>
- (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像素的红线作为顶部边框。你提到的所有其他变化都留给了读者一个微不足道的练习。
建议答案 5 :(得分:19)
所选答案的代码,以防有人想要。
注意:这不适用于autolayout(也就是说,将设备旋转到横向等)。
首先定义厚度:
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];
答案 6 :(得分:13)
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)
编辑:对于更新版本,请在此处查看我的回购: https://github.com/goktugyil/EZSwiftExtensions/blob/master/Sources/UIViewExtensions.swift
查看addBorder部分
答案 7 :(得分:11)
旧问题,但仍然缺少运行时边界调整的自动布局解决方案。
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]))
}
}
}
}
}
答案 8 :(得分:4)
// 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];
}
答案 9 :(得分:4)
我接受了Adam Waite和Pauls的回答并将它们合并。我还添加了将选定边连接在一起的可能性,因此您只需要调用一个函数,如下所示:
[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];
}
}
答案 10 :(得分:3)
这是一个简单的解决方案。在UIView
上添加标签,清除标签上的文字,并将标签背景颜色设置为边框颜色。将标签的原点(x,y)
设置为视图的原点(x,y)
。并将标签的宽度设置为UIView
的宽度,将高度设置为1或2(对于UIView
顶部的边框高度)。这应该可以解决问题。
答案 11 :(得分:3)
我对Dan's answer进行了一些更改,以便我可以使用一个命令为多个边添加边框:
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)
}
}
}
答案 12 :(得分:2)
建立NSBum's答案,我采用了类似的方法并创建了这个简单的UIView子类,以便它在Interface Builder中工作并使用约束:github link
通过使用CGContextFillRect而不是CGContextStrokePath,我能够可预测地保持线条完全固定并且在视图的范围内。
这是关于它的博文: http://natrosoft.com/?p=55
- 基本上只需在Interface Builder中放入UIView并将其类类型更改为NAUIViewWithBorders。
- 然后在VC的viewDidLoad中执行以下操作:
/* 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];
这是.m file的直接链接,因此您可以看到实施情况。 还有一个演示项目。希望这有助于某人:)
答案 13 :(得分:2)
Swift 4.2和AutoLayout
我经历了提供的解决方案。许多基于框架 这是一个与AutoLayout一起使用的简单扩展 -使用“视图”而不是“图层”以确保我们可以使用“自动布局” -具有4个约束的单个子视图
用法如下:
self.addBorder(.bottom, color: .lightGray, thickness: 0.5)
extension UIView {
func addBorder(_ edge: UIRectEdge, color: UIColor, thickness: CGFloat) {
let subview = UIView()
subview.translatesAutoresizingMaskIntoConstraints = false
subview.backgroundColor = color
self.addSubview(subview)
switch edge {
case .top, .bottom:
subview.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 0).isActive = true
subview.rightAnchor.constraint(equalTo: self.rightAnchor, constant: 0).isActive = true
subview.heightAnchor.constraint(equalToConstant: thickness).isActive = true
if edge == .top {
subview.topAnchor.constraint(equalTo: self.topAnchor, constant: 0).isActive = true
} else {
subview.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0).isActive = true
}
case .left, .right:
subview.topAnchor.constraint(equalTo: self.topAnchor, constant: 0).isActive = true
subview.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0).isActive = true
subview.widthAnchor.constraint(equalToConstant: thickness).isActive = true
if edge == .left {
subview.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 0).isActive = true
} else {
subview.rightAnchor.constraint(equalTo: self.rightAnchor, constant: 0).isActive = true
}
default:
break
}
}
}
答案 14 :(得分:2)
Swift 3版本
extension UIView {
enum ViewSide {
case Top, Bottom, Left, Right
}
func addBorder(toSide side: ViewSide, withColor color: UIColor, andThickness thickness: CGFloat) {
let border = CALayer()
border.backgroundColor = color.cgColor
switch side {
case .Top:
border.frame = CGRect(x: 0, y: 0, width: frame.size.width, height: thickness)
case .Bottom:
border.frame = CGRect(x: 0, y: frame.size.height - thickness, width: frame.size.width, height: thickness)
case .Left:
border.frame = CGRect(x: 0, y: 0, width: thickness, height: frame.size.height)
case .Right:
border.frame = CGRect(x: frame.size.width - thickness, y: 0, width: thickness, height: frame.size.height)
}
layer.addSublayer(border)
}
}
要设置相应的边框,您应该覆盖 viewDidLayoutSubviews()方法:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
yourView.addBorder(toSide: UIView.ViewSide.Top, withColor: UIColor.lightGray, andThickness: 1)
答案 15 :(得分:2)
我对类似问题的回答:https://stackoverflow.com/a/27141956/435766 我个人更喜欢在那个类别的路上走下去,因为我希望能够在UIView的任何子类上使用它。
答案 16 :(得分:1)
只需在此处发帖,以帮助有人寻找添加边框。我已在接受的答案swift label only border left中做了一些更改。
将UIRectEdge.Top
的{{1}}的宽度更改为CGRectGetHeight(self.frame)
,将CGRectGetWidth(self.frame)
的{{1}}更改为UIRectEdge.Bottom
以正确获取边框。使用Swift 2。
最后,扩展名为:
UIScreen.mainScreen().bounds.width
答案 17 :(得分:1)
extension UIView {
func addBorder(edge: UIRectEdge, color: UIColor, borderWidth: CGFloat) {
let seperator = UIView()
self.addSubview(seperator)
seperator.translatesAutoresizingMaskIntoConstraints = false
seperator.backgroundColor = color
if edge == .top || edge == .bottom
{
seperator.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 0).isActive = true
seperator.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: 0).isActive = true
seperator.heightAnchor.constraint(equalToConstant: borderWidth).isActive = true
if edge == .top
{
seperator.topAnchor.constraint(equalTo: self.topAnchor, constant: 0).isActive = true
}
else
{
seperator.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0).isActive = true
}
}
else if edge == .left || edge == .right
{
seperator.topAnchor.constraint(equalTo: self.topAnchor, constant: 0).isActive = true
seperator.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0).isActive = true
seperator.widthAnchor.constraint(equalToConstant: borderWidth).isActive = true
if edge == .left
{
seperator.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 0).isActive = true
}
else
{
seperator.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: 0).isActive = true
}
}
}
}
答案 18 :(得分:1)
如果有人需要Xamarin版本:
$errors
答案 19 :(得分:1)
如果我在故事板中构建,我更喜欢在我有用的UIView
后面添加UIView
...如果我想在{{1}的顶部创建一个边框我只是通过边框宽度增加背景UIView
的高度..对于任何其他方面也可以这样做:)
答案 20 :(得分:1)
受@Addison的启发,我重写了扩展程序,而没有使用任何第三方框架,因为他使用了SnapKit和CocoaLumberjack。
与@Addisons方法一样,我还将删除以前添加的边框,因此该实现在表单元格和集合单元格等可重用视图中应该能很好地发挥作用。
fileprivate class BorderView: UIView {} // dummy class to help us differentiate among border views and other views
// to enabling us to remove existing borders and place new ones
extension UIView {
func setBorders(toEdges edges: [UIRectEdge], withColor color: UIColor, inset: CGFloat = 0, thickness: CGFloat) {
// Remove existing edges
for view in subviews {
if view is BorderView {
view.removeFromSuperview()
}
}
// Add new edges
if edges.contains(.all) {
addSidedBorder(toEdge: [.left,.right, .top, .bottom], withColor: color, inset: inset, thickness: thickness)
}
if edges.contains(.left) {
addSidedBorder(toEdge: [.left], withColor: color, inset: inset, thickness: thickness)
}
if edges.contains(.right) {
addSidedBorder(toEdge: [.right], withColor: color, inset: inset, thickness: thickness)
}
if edges.contains(.top) {
addSidedBorder(toEdge: [.top], withColor: color, inset: inset, thickness: thickness)
}
if edges.contains(.bottom) {
addSidedBorder(toEdge: [.bottom], withColor: color, inset: inset, thickness: thickness)
}
}
private func addSidedBorder(toEdge edges: [RectangularEdges], withColor color: UIColor, inset: CGFloat = 0, thickness: CGFloat) {
for edge in edges {
let border = BorderView(frame: .zero)
border.backgroundColor = color
addSubview(border)
border.translatesAutoresizingMaskIntoConstraints = false
switch edge {
case .left:
NSLayoutConstraint.activate([
border.leftAnchor.constraint(equalTo: self.leftAnchor, constant: inset),
border.topAnchor.constraint(equalTo: self.topAnchor, constant: inset),
border.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -inset),
NSLayoutConstraint(item: border, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .width, multiplier: 1, constant: thickness) ])
case .right:
NSLayoutConstraint.activate([
border.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -inset),
border.topAnchor.constraint(equalTo: self.topAnchor, constant: inset),
border.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -inset),
NSLayoutConstraint(item: border, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .width, multiplier: 1, constant: thickness) ])
case .top:
NSLayoutConstraint.activate([
border.leftAnchor.constraint(equalTo: self.leftAnchor, constant: inset),
border.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -inset),
border.topAnchor.constraint(equalTo: self.topAnchor, constant: inset),
NSLayoutConstraint(item: border, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: thickness) ])
case .bottom:
NSLayoutConstraint.activate([
border.leftAnchor.constraint(equalTo: self.leftAnchor, constant: inset),
border.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -inset),
border.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -inset),
NSLayoutConstraint(item: border, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: thickness) ])
}
}
}
private enum RectangularEdges {
case left
case right
case top
case bottom
}
}
答案 21 :(得分:1)
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)
}
答案 22 :(得分:0)
在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)
答案 23 :(得分:0)
除了n8tr之外,还可以添加一个可用性来设置故事板:
- 在.h文件中添加borderColor
和borderWidth
两个属性;
- 然后您可以在故事板中添加keyPaths
,请参阅screenshot
答案 24 :(得分:0)
为我工作
{
test: /\.scss$/,
use: [{
loader: 'style-loader' // creates style nodes from JS strings
},
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
modules: true,
localIdentName: "[name]_[local]_[hash:base64:5]"
},
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
modules: true,
localIdentName: "[name]_[local]_[hash:base64:5]"
} // compiles Sass to CSS
},
{
loader: require.resolve('postcss-loader'),
options: {
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
],
flexbox: 'no-2009',
}),
],
},
},
],
},
答案 25 :(得分:0)
我想出了一个使用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)
答案 26 :(得分:0)
将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)
}
}
答案 27 :(得分:0)
用于在Swift中为UIView设置顶部边框和底部边框。
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)
答案 28 :(得分:0)
注意:此处的大多数解决方案都不具有自适应性,不会调整大小。将调整大小的解决方案会对您的启动时间产生大量影响,因为它们会占用大量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()
}
}
}
答案 29 :(得分:0)
我个人喜欢view + drawRect的子类,但这只是另一种方式(它与@If Pollavith接受的答案一样有效):
您的新边框图层可以设置为您喜欢的任何尺寸。所以,就像@If Pollavith的回答一样,你创建一个和你想要的一样高的图层,以及你想要边界的视图。使用图层的框架定义将其放置在您想要的位置,然后将其作为子图层添加到视图中。
作为参考,我自己的要求是在视图的LEFT-HAND侧放置一个边框(请不要剪切和粘贴此代码并且不要'我只是因为它没有在顶部放置边框视图 - 修改下面的代码很简单):
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: Using UIView's 'drawRect:' vs. its layer's delagate 'drawLayer:inContext:')。
我喜欢蓝色。
答案 30 :(得分:0)
对于C#中的Xamarin,我只是在添加子图层时内联边框
View.Layer.AddSublayer(new CALayer()
{
BackgroundColor = UIColor.Black.CGColor,
Frame = new CGRect(0, 0, View.Frame.Width, 0.5f)
});
你可以安排这个(如他人所建议的)底部,左边和右边界。
答案 31 :(得分:0)
您还可以查看此UIKit和基金会类别的集合:https://github.com/leszek-s/LSCategories
它允许使用单行代码在UIView的一侧添加边框:
[self.someView lsAddBorderOnEdge:UIRectEdgeTop color:[UIColor blueColor] width:2];
并且它正确处理视图旋转,而此处发布的大多数答案都不能很好地处理它。
答案 32 :(得分:-7)
在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]];`
}
此代码将红色边框设置为您的视图