UI 보기의 맨 위에 테두리를 추가하는 방법
제 질문은 제목에 있습니다.
위쪽이든 아래쪽이든 특정 면에 테두리를 추가하는 방법을 모르겠습니다. layer.border
전체 뷰의 경계를 그립니다...
는 서브클래스 분류고다니합려를하위class▁sub다▁considering▁i니를 고려합니다.UIView
및우위순선iding를 재정의함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
사용자의 프로젝트 및 기타 모든 항목에서 재사용할 수 있습니다.다른 색상과 너비를 정의하기 위해 다른 인수를 방법에 전달합니다.다양한 옵션.
Adam Waite의 원래 게시물에 둥근 모서리에 대한 기능 추가 및 다중 편집
중요!:이전에 언급한 대로 'add border'를 호출하기 직전에 'label.layoutIfNeeded()'를 추가하는 것을 잊지 마십시오.
참고: UILabel에서만 테스트했습니다.
extension CALayer {
enum BorderSide {
case top
case right
case bottom
case left
case notRight
case notLeft
case topAndBottom
case all
}
enum Corner {
case topLeft
case topRight
case bottomLeft
case bottomRight
}
func addBorder(side: BorderSide, thickness: CGFloat, color: CGColor, maskedCorners: CACornerMask? = nil) {
var topWidth = frame.size.width; var bottomWidth = topWidth
var leftHeight = frame.size.height; var rightHeight = leftHeight
var topXOffset: CGFloat = 0; var bottomXOffset: CGFloat = 0
var leftYOffset: CGFloat = 0; var rightYOffset: CGFloat = 0
// Draw the corners and set side offsets
switch maskedCorners {
case [.layerMinXMinYCorner, .layerMaxXMinYCorner]: // Top only
addCorner(.topLeft, thickness: thickness, color: color)
addCorner(.topRight, thickness: thickness, color: color)
topWidth -= cornerRadius*2
leftHeight -= cornerRadius; rightHeight -= cornerRadius
topXOffset = cornerRadius; leftYOffset = cornerRadius; rightYOffset = cornerRadius
case [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]: // Bottom only
addCorner(.bottomLeft, thickness: thickness, color: color)
addCorner(.bottomRight, thickness: thickness, color: color)
bottomWidth -= cornerRadius*2
leftHeight -= cornerRadius; rightHeight -= cornerRadius
bottomXOffset = cornerRadius
case [.layerMinXMinYCorner, .layerMinXMaxYCorner]: // Left only
addCorner(.topLeft, thickness: thickness, color: color)
addCorner(.bottomLeft, thickness: thickness, color: color)
topWidth -= cornerRadius; bottomWidth -= cornerRadius
leftHeight -= cornerRadius*2
leftYOffset = cornerRadius; topXOffset = cornerRadius; bottomXOffset = cornerRadius;
case [.layerMaxXMinYCorner, .layerMaxXMaxYCorner]: // Right only
addCorner(.topRight, thickness: thickness, color: color)
addCorner(.bottomRight, thickness: thickness, color: color)
topWidth -= cornerRadius; bottomWidth -= cornerRadius
rightHeight -= cornerRadius*2
rightYOffset = cornerRadius
case [.layerMaxXMinYCorner, .layerMaxXMaxYCorner, // All
.layerMinXMaxYCorner, .layerMinXMinYCorner]:
addCorner(.topLeft, thickness: thickness, color: color)
addCorner(.topRight, thickness: thickness, color: color)
addCorner(.bottomLeft, thickness: thickness, color: color)
addCorner(.bottomRight, thickness: thickness, color: color)
topWidth -= cornerRadius*2; bottomWidth -= cornerRadius*2
topXOffset = cornerRadius; bottomXOffset = cornerRadius
leftHeight -= cornerRadius*2; rightHeight -= cornerRadius*2
leftYOffset = cornerRadius; rightYOffset = cornerRadius
default: break
}
// Draw the sides
switch side {
case .top:
addLine(x: topXOffset, y: 0, width: topWidth, height: thickness, color: color)
case .right:
addLine(x: frame.size.width - thickness, y: rightYOffset, width: thickness, height: rightHeight, color: color)
case .bottom:
addLine(x: bottomXOffset, y: frame.size.height - thickness, width: bottomWidth, height: thickness, color: color)
case .left:
addLine(x: 0, y: leftYOffset, width: thickness, height: leftHeight, color: color)
// Multiple Sides
case .notRight:
addLine(x: topXOffset, y: 0, width: topWidth, height: thickness, color: color)
addLine(x: 0, y: leftYOffset, width: thickness, height: leftHeight, color: color)
addLine(x: bottomXOffset, y: frame.size.height - thickness, width: bottomWidth, height: thickness, color: color)
case .notLeft:
addLine(x: topXOffset, y: 0, width: topWidth, height: thickness, color: color)
addLine(x: frame.size.width - thickness, y: rightYOffset, width: thickness, height: rightHeight, color: color)
addLine(x: bottomXOffset, y: frame.size.height - thickness, width: bottomWidth, height: thickness, color: color)
case .topAndBottom:
addLine(x: topXOffset, y: 0, width: topWidth, height: thickness, color: color)
addLine(x: bottomXOffset, y: frame.size.height - thickness, width: bottomWidth, height: thickness, color: color)
case .all:
addLine(x: topXOffset, y: 0, width: topWidth, height: thickness, color: color)
addLine(x: frame.size.width - thickness, y: rightYOffset, width: thickness, height: rightHeight, color: color)
addLine(x: bottomXOffset, y: frame.size.height - thickness, width: bottomWidth, height: thickness, color: color)
addLine(x: 0, y: leftYOffset, width: thickness, height: leftHeight, color: color)
}
}
private func addLine(x: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat, color: CGColor) {
let border = CALayer()
border.frame = CGRect(x: x, y: y, width: width, height: height)
border.backgroundColor = color
addSublayer(border)
}
private func addCorner(_ corner: Corner, thickness: CGFloat, color: CGColor) {
// Set default to top left
let width = frame.size.width; let height = frame.size.height
var x = cornerRadius
var y = cornerRadius
var startAngle: CGFloat = .pi; var endAngle: CGFloat = .pi*3/2
switch corner {
case .bottomLeft:
y = height - cornerRadius
startAngle = .pi/2; endAngle = .pi
case .bottomRight:
x = width - cornerRadius
y = height - cornerRadius
startAngle = 0; endAngle = .pi/2
case .topRight:
x = width - cornerRadius
startAngle = .pi*3/2; endAngle = 0
default: break
}
let cornerPath = UIBezierPath(arcCenter: CGPoint(x: x, y: y),
radius: cornerRadius - thickness,
startAngle: startAngle,
endAngle: endAngle,
clockwise: true)
let cornerShape = CAShapeLayer()
cornerShape.path = cornerPath.cgPath
cornerShape.lineWidth = thickness
cornerShape.strokeColor = color
cornerShape.fillColor = nil
addSublayer(cornerShape)
}
}
이지만, UIView에 있는 카테고리입니다.adding views
CALayers, 즉 CALayers를 사용할 수 .take advantage of AutoresizingMasks
테두리 크기를 수퍼뷰와 함께 조정할 수 있습니다.
목표 C
- (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];
}
스위프트 5
func addTopBorder(with color: UIColor?, andWidth borderWidth: CGFloat) {
let border = UIView()
border.backgroundColor = color
border.autoresizingMask = [.flexibleWidth, .flexibleBottomMargin]
border.frame = CGRect(x: 0, y: 0, width: frame.size.width, height: borderWidth)
addSubview(border)
}
func addBottomBorder(with color: UIColor?, andWidth borderWidth: CGFloat) {
let border = UIView()
border.backgroundColor = color
border.autoresizingMask = [.flexibleWidth, .flexibleTopMargin]
border.frame = CGRect(x: 0, y: frame.size.height - borderWidth, width: frame.size.width, height: borderWidth)
addSubview(border)
}
func addLeftBorder(with color: UIColor?, andWidth borderWidth: CGFloat) {
let border = UIView()
border.backgroundColor = color
border.frame = CGRect(x: 0, y: 0, width: borderWidth, height: frame.size.height)
border.autoresizingMask = [.flexibleHeight, .flexibleRightMargin]
addSubview(border)
}
func addRightBorder(with color: UIColor?, andWidth borderWidth: CGFloat) {
let border = UIView()
border.backgroundColor = color
border.autoresizingMask = [.flexibleHeight, .flexibleLeftMargin]
border.frame = CGRect(x: frame.size.width - borderWidth, y: 0, width: borderWidth, height: frame.size.height)
addSubview(border)
}
스위프트 3.0
스위프트 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: frame.width, height: thickness)
case UIRectEdge.bottom:
border.frame = CGRect(x:0, y: frame.height - thickness, width: frame.width, height:thickness)
case UIRectEdge.left:
border.frame = CGRect(x:0, y:0, width: thickness, height: frame.height)
case UIRectEdge.right:
border.frame = CGRect(x: frame.width - thickness, y: 0, width: thickness, height: frame.height)
default: do {}
}
border.backgroundColor = color.cgColor
addSublayer(border)
}
}
클래스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);
}
스위프트 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픽셀의 빨간색 선을 그립니다.당신이 언급한 다른 모든 변형들은 독자들을 위한 사소한 연습으로 남겨집니다.
원하는 사용자가 있을 경우 선택한 답변의 코드입니다.
참고: 이는 자동 레이아웃(예: 장치를 가로 방향으로 회전)에서는 작동하지 않습니다.
먼저 두께를 정의합니다.
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];
이전 질문이지만 런타임 테두리 조정이 있는 자동 레이아웃 솔루션이 여전히 없습니다.
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]))
}
}
}
}
}
빠른 버전:
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
경계 부분 추가를 확인합니다.
Swift 4.2 및 자동 레이아웃
저는 제안된 해결책을 검토했습니다.대부분이 프레임에 기반을 두고 있습니다. 이는 AutoLayout과 함께 작동하는 간단한 확장입니다. 레이어 대신 View를 사용하여 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
}
}
}
아담 웨이트와 폴스의 답변을 모두 받아 조합했습니다.선택한 모서리를 함께 연결할 수 있는 기능도 추가했으므로 다음과 같이 하나의 함수만 호출하면 됩니다.
[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];
}
}
//MARK:- 보기의 왼쪽 테두리 추가
(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:- 보기에 대한 오른쪽 테두리 추가
(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];
}
Dan의 답변을 몇 가지 변경하여 하나의 명령으로 여러 모서리에 테두리를 추가할 수 있었습니다.
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)
}
}
}
스위프트 5
편의를 위해 이전 답변 일부 편집 및 추가 방법 추가
import UIKit
extension UIView {
enum ViewSide {
case top
case left
case bottom
case right
}
func addBorders(to sides: [ViewSide], in color: UIColor, width: CGFloat) {
sides.forEach { addBorder(to: $0, in: color, width: width) }
}
func addBorder(to side: ViewSide, in color: UIColor, width: CGFloat) {
switch side {
case .top:
addTopBorder(in: color, width: width)
case .left:
addLeftBorder(in: color, width: width)
case .bottom:
addBottomBorder(in: color, width: width)
case .right:
addRightBorder(in: color, width: width)
}
}
func addTopBorder(in color: UIColor?, width borderWidth: CGFloat) {
let border = UIView()
border.backgroundColor = color
border.frame = CGRect(x: 0, y: 0, width: frame.size.width, height: borderWidth)
border.autoresizingMask = [.flexibleWidth, .flexibleBottomMargin]
addSubview(border)
}
func addBottomBorder(in color: UIColor?, width borderWidth: CGFloat) {
let border = UIView()
border.backgroundColor = color
border.frame = CGRect(x: 0, y: frame.size.height - borderWidth, width: frame.size.width, height: borderWidth)
border.autoresizingMask = [.flexibleWidth, .flexibleTopMargin]
addSubview(border)
}
func addLeftBorder(in color: UIColor?, width borderWidth: CGFloat) {
let border = UIView()
border.backgroundColor = color
border.frame = CGRect(x: 0, y: 0, width: borderWidth, height: frame.size.height)
border.autoresizingMask = [.flexibleHeight, .flexibleRightMargin]
addSubview(border)
}
func addRightBorder(in color: UIColor?, width borderWidth: CGFloat) {
let border = UIView()
border.backgroundColor = color
border.frame = CGRect(x: frame.size.width - borderWidth, y: 0, width: borderWidth, height: frame.size.height)
border.autoresizingMask = [.flexibleHeight, .flexibleLeftMargin]
addSubview(border)
}
}
다음 중 하나를 수행할 수 있습니다.
- 특정 방법을 사용하거나 일반 방법을 사용하여 개별적으로 각 테두리 설정, 사례 선택
- 테두리 배열 설정
사용 예:
// Adding top border with 2 px in red
let myView = UIView()
myView.addBorder(to: .top, in: .red, width: 2)
(사용 가능한 두 개의 인터페이스에서 오는 모호성을 제거하고 도우미 메소드를 비공개로 설정할 수 있습니다.)저는 그것들을 그곳에서 제거하고 모든 케이스를 주요 방법으로 옮기지 않을 것입니다. 왜냐하면, 제가 보기에, 그것은 그것의 몸을 어지럽힐 수 있기 때문입니다.)
NSBum의 답변을 바탕으로, 저는 비슷한 접근 방식을 취했고 인터페이스 빌더에서 작동하고 제약 조건과 함께 작동하도록 이 간단한 UIView 하위 클래스를 만들었습니다: githublink
CGContextStrokePath 대신 CGContextFillRect를 사용하여 예측 가능하게 선을 완전히 견고하게 유지하고 뷰의 범위 내로 유지할 수 있었습니다.
http://natrosoft.com/ ?p=55에 대한 제 블로그 게시물입니다.
Interface Builder와 UIView는 NAUIViewWithBorders와 함께 사용됩니다.
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];
구현을 확인할 수 있도록 .m 파일에 대한 직접 링크가 있습니다.데모 프로젝트도 있습니다.이것이 누군가에게 도움이 되기를 바랍니다 :)
누군가가 사마린 버전을 필요로 할 경우:
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);
}
}
비슷한 질문에 대한 저의 대답: https://stackoverflow.com/a/27141956/435766 저는 개인적으로 그것을 UIView의 모든 하위 클래스에서 사용할 수 있기 때문에 카테고리 길을 가는 것을 선호합니다.
C#의 Xamarin의 경우 하위 계층을 추가할 때 경계를 인라인으로 작성합니다.
View.Layer.AddSublayer(new CALayer()
{
BackgroundColor = UIColor.Black.CGColor,
Frame = new CGRect(0, 0, View.Frame.Width, 0.5f)
});
다른 사용자가 제안한 대로 아래쪽, 왼쪽 및 오른쪽 테두리에 대해 이 옵션을 정렬할 수 있습니다.
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
}
}
}
}
스위프트 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)
국경을 추가하려는 사람을 돕기 위해 여기에 게시하는 것입니다.저는 여기서 수락된 답변에 몇 가지 변경을 가했습니다. 라벨만 테두리가 남아 있습니다.케이스의 폭이 변경UIRectEdge.Top
CGRectGetHeight(self.frame)
CGRectGetWidth(self.frame)
그리고 만일의 경우에는UIRectEdge.Bottom
UIScreen.mainScreen().bounds.width
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)
}
}
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)
}
}
여기 폴스의 스위프트 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)
}
@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
}
}
▁an다▁add니▁if▁from▁prefer선합호▁i것,▁the을을 추가하는 것을 선호합니다.UIView
의 유용한 의나유이에면 에.UIView
맨 위에 테두리를 작성하려면UIView
는 그냥 .UIView
내 경계선 폭으로..일 수 :) 른다면도동일게할하수있다습니 :)
여기 간단한 해결책이 있습니다.에레추에 합니다.UIView
레이블의 텍스트를 지우고 레이블 배경색을 테두리 색으로 설정합니다.을 설정합니다.(x,y)
의 신의라될것다입니이당기원벨.(x,y)
를 당신의 너비로 설정합니다.UIView
를 1 의 맨 ).UIView
그리고 그것이 효과가 있을 것입니다.
개인적으로 저는 뷰의 하위 분류 + drawRect를 좋아하지만, 여기 다른 방법이 있습니다(그리고 그것은 @If Pollavith의 승인된 답변과 같은 맥락에서 작동합니다).
새 테두리 레이어는 원하는 치수로 설정할 수 있습니다.@Pollavith의 대답처럼 원하는 높이만큼, 그리고 원하는 시야만큼 넓은 층을 만듭니다.도면층의 프레임 정의를 사용하여 도면층을 원하는 위치에 배치한 다음 뷰에 하위 도면층으로 추가합니다.
참고로, 저만의 요구 사항은 보기의 왼쪽에 테두리를 두는 것이었습니다. (이 코드를 잘라낸 후 붙여넣지 말고 '보기의 맨 위에 테두리를 두지 않기 때문에 아래 코드를 수정하는 것은 매우 간단합니다.)
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];
이에 비해 중간 정도의 이점과 작은 UIBiew 또는 UILabel을 만드는 것은 CALayer가 '경량'이며, CALayer를 사용하는 것과 비교하여 오버라이딩 DrawRect에 대한 많은 흥미로운 견해(의견과 같이)가 있다고 생각합니다(예: iOS: UIBiew의 'DrawRect: 레이어: Context: Context:
애니멀451
저는 파란색을 좋아합니다.
n8tr 외에도 스토리보드에서 설정할 수 있는 기능이 추가될 수 있습니다.
다과같 두가속추가성과 같은 두 가지 합니다.borderColor
그리고.borderWidth
.h 파일 .h 일파;
그런 다음 추가할 수 있습니다.keyPaths
스토리보드에서 스크린샷 링크 참조
다음 UIKit 및 Foundation 범주 모음도 확인할 수 있습니다. https://github.com/leszek-s/LSCategories
코드 한 줄로 UIView의 한 쪽에 테두리를 추가할 수 있습니다.
[self.someView lsAddBorderOnEdge:UIRectEdgeTop color:[UIColor blueColor] width:2];
보기 회전을 제대로 처리하지만 여기에 게시된 대부분의 답변은 제대로 처리하지 못합니다.
참고: 대부분의 솔루션은 적응형이 아니며 크기가 조정되지 않습니다.크기를 조정하는 솔루션은 CPU를 많이 사용하기 때문에 시작 시간에 큰 영향을 미칩니다.
아래에 있는 이 솔루션을 사용할 수 있습니다.계층보다 가벼운 UIBeezierPath에서 작동하여 시작 시간이 빠릅니다.사용하기 쉬우므로 아래 지침을 참조하십시오.
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 클래스를 BorderView 크기 조정으로 설정합니다.
- view.color와 view.lineWidth를 사용하여 색상과 선폭을 설정합니다.
- 모두에 대해 가장자리를 설정합니다. 예: yourview.dll = [.right, .left]([.all])
- 빠른 시작 및 테두리 크기 조정
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)
언급URL : https://stackoverflow.com/questions/17355280/how-to-add-a-border-just-on-the-top-side-of-a-uiview
'programing' 카테고리의 다른 글
현재 분기가 pull에 대해 구성되지 않았습니다. 구성에서 branch.master.merge 키 값을 찾을 수 없습니다. (0) | 2023.04.26 |
---|---|
프로그래밍 방식으로 ID 열이 있는 SQL 테이블을 결정하는 방법 (0) | 2023.04.26 |
SQL Server에서 "Null" 값의 크기 (0) | 2023.04.26 |
두 개의 목록 결합 및 중복 제거, 원래 목록의 중복 제거 안 함 (0) | 2023.04.26 |
기본값 대응:다음 키보드 버튼을 누른 후 다음 텍스트 입력을 선택하는 방법은 무엇입니까? (0) | 2023.04.26 |