शीर्षक पर मेरा सवाल है।
मैं नहीं जानता कि किसी विशिष्ट पक्ष, ऊपर या नीचे, किसी भी पक्ष में एक सीमा कैसे जोड़ूं ...
layer.border
पूरे दृश्य के लिए सीमा खींचता है ...
शीर्षक पर मेरा सवाल है।
मैं नहीं जानता कि किसी विशिष्ट पक्ष, ऊपर या नीचे, किसी भी पक्ष में एक सीमा कैसे जोड़ूं ...
layer.border
पूरे दृश्य के लिए सीमा खींचता है ...
जवाबों:
मैं यहां उपश्रमण 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
- अपनी परियोजना में पुन: प्रयोज्य, और किसी भी अन्य पर लागू कर सकते हैं। अन्य रंगों और चौड़ाई को परिभाषित करने के लिए अपने तरीकों से अन्य तर्कों में पास करें। कई विकल्प।
एडम वाइट के मूल पद और कई संपादन के लिए गोल कोनों के लिए जोड़ा गया क्षमता
महत्वपूर्ण !: label.layoutIfNeeded()
'Addborder' को कॉल करने से पहले 'ठीक' जोड़ना न भूलें
नोट: मैंने केवल इस पर परीक्षण किया है UILabels
।
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 startAngle: CGFloat = .pi; var endAngle: CGFloat = .pi*3/2
switch corner {
case .bottomLeft: startAngle = .pi/2; endAngle = .pi
case .bottomRight:
x = width - 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: height / 2),
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)
}
}
view.layoutIfNeeded()
कॉल करने से पहले सही जोड़ना होगा view.layer.addBorder(...)
। फिर यह स्विफ्ट 3
override func viewDidLayoutSubviews()
मेरे लिए सबसे अच्छा तरीका UIView पर एक श्रेणी है, लेकिन adding views
कैलेयर्स के बजाय, इसलिए हम take advantage of AutoresizingMasks
यह सुनिश्चित कर सकते हैं कि पर्यवेक्षी के साथ-साथ सीमाओं का आकार बदल जाए।
उद्देश्य सी
- (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:
अपने उपवर्ग में लागू करें, जैसे:
उद्देश्य सी
- (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 पिक्सेल की लाल रेखा खींचता है। आपके द्वारा उल्लिखित अन्य सभी विविधताओं को पाठक के लिए एक तुच्छ अभ्यास के रूप में छोड़ दिया जाता है।
क्वार्ट्ज 2 डी प्रोग्रामिंग गाइड की सिफारिश की जाती है।
UIView
उपवर्ग में एक संपत्ति हो सकती है जो यह निर्धारित करती है कि सीमाएं क्या drawRect:
खींचती हैं। इस संपत्ति को इस प्रकार परिभाषित किया जा सकता है NS_OPTIONS
कि यह बिटमास्क की तरह एक बिटमैक्स को परिभाषित करता है UIViewAutoresizing
। यदि - जो भी कारण से - आप वास्तव में आपत्ति करते हैं कि दृढ़ता से उपवर्ग के लिए UIView
तो बस एक छोटे से 1-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
AddBorder भागों को देखें
स्विफ्ट 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
}
}
}
मैंने एडम वाइट्स और पॉल दोनों के उत्तर लिए और उन्हें संयोजित किया। मैंने चयनित किनारों को एक साथ पाइप करने की संभावना को भी जोड़ा, इसलिए आपको केवल एक फ़ंक्शन को कॉल करने की आवश्यकता है:
[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: - View के लिए 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];
}
// मार्क: - देखने के लिए राइटबॉर्डर जोड़ें
(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];
}
// मार्क: - व्यू के लिए बॉटम बॉर्डर जोड़ें
(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];
}
मैंने दान के उत्तर में कुछ बदलाव किए ताकि मैं एक कमांड के साथ कई किनारों पर सीमाएं जोड़ सकूं:
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)
}
}
}
NSBum के उत्तर का निर्माण , मैंने एक समान दृष्टिकोण लिया और इस सरल UIView उपवर्ग का निर्माण किया ताकि यह इंटरफ़ेस बिल्डर में काम करे और बाधाओं के साथ काम करे: github लिंक
CGContextFillRect के स्थान पर CGContextStrokePath का उपयोग करके, मैं अनुमानों को पूरी तरह से ठोस और भीतर रखने में सक्षम था। दृश्य की सीमा।
यहाँ इसके बारे में मेरा ब्लॉग पोस्ट है: http://natrosoft.com/?p=55
- मूल रूप से बस इंटरफ़ेस बिल्डर में एक UIView में ड्रॉप और NAUIViewWithBorders के लिए अपने वर्ग के प्रकार को बदलते हैं।
- फिर अपने वीसी के विचार में देखें
/* 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 फ़ाइल का सीधा लिंक दिया गया है ताकि आप कार्यान्वयन देख सकें। एक डेमो प्रोजेक्ट भी है। आशा है कि यह किसी की मदद करता है :)
इसी तरह के एक सवाल का मेरा जवाब: https://stackoverflow.com/a/27141956/435766 मैं व्यक्तिगत रूप से उस एक पर श्रेणी की सड़क पर जाना पसंद करता हूं, क्योंकि मैं इसे यूआईवीवाई के किसी भी उपवर्ग पर उपयोग करने में सक्षम होना चाहता हूं।
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
}
}
}
}
यहाँ एक सरल उपाय है। अपने पर एक लेबल जोड़ें, लेबल पर UIView
पाठ को साफ़ करें और लेबल पृष्ठभूमि रंग को अपनी सीमा रंग निर्धारित करें। अपने दृश्य (x,y)
की उत्पत्ति (x,y)
के लिए अपने लेबल की उत्पत्ति सेट करें । और लेबल की चौड़ाई को अपनी चौड़ाई के अनुसार UIView
सेट करें , ऊँचाई को 1 या 2 हो (अपनी सीमा के शीर्ष पर अपनी सीमा के लिए UIView
) सेट करें। और वह चाल चलनी चाहिए।
स्विफ्ट 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)
सीमाओं को सही ढंग से प्राप्त करने के लिए। स्विफ्ट 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)
}
}
मामले में किसी को कभी ज़ामरीन संस्करण की आवश्यकता होगी:
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);
}
}
यहाँ पॉल के जवाब का एक स्विफ्ट 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 का उपयोग किया था।
जैसा कि @ एडिसन दृष्टिकोण में मैं पहले से जोड़ी गई सीमाओं को भी हटा रहा हूं, इसलिए इस कार्यान्वयन को तालिका कोशिकाओं और संग्रह कोशिकाओं के रूप में पुन: प्रयोज्य दृश्यों के साथ अच्छा खेलना चाहिए।
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
}
}
अगर मैं स्टोरीबोर्ड के भीतर से निर्माण कर रहा हूं, तो मैं UIView
अपने उपयोगी के पीछे जोड़ना पसंद करता हूं UIView
... यदि मैं अपने शीर्ष पर एक सीमा बनाना चाहता हूं UIView
, तो मैं UIView
अपनी सीमा चौड़ाई से पृष्ठभूमि की ऊंचाई बढ़ाता हूं .. वही कर सकता है किसी अन्य पक्ष के लिए किया जा :)
व्यक्तिगत रूप से मुझे दृश्य + ड्रॉअर की उप-क्लासिंग पसंद है, लेकिन यहां इसके बारे में जाने का सिर्फ एक और तरीका है (और यह उसी तरह काम करता है जैसे @If पोलाविथ द्वारा स्वीकृत उत्तर)
आपकी नई बॉर्डर लेयर को सेट किया जा सकता है जो भी आपको पसंद हो। तो, @ इफ पोलाविथ के जवाब की तरह, आप एक परत बनाते हैं जितना आप चाहते हैं कि यह उतना लंबा हो, और जितना आप देखना चाहते हैं उतना व्यापक हो। जहाँ आप चाहते हैं, उसे रखने के लिए लेयर की फ़्रेम परिभाषा का उपयोग करें और फिर इसे अपने दृश्य में सब-लेयर के रूप में जोड़ें।
संदर्भ के लिए, मेरी अपनी आवश्यकता को देखने के लिए LEFT-HAND साइड पर एक बॉर्डर लगाना था (कृपया इस कोड को काटें और पेस्ट न करें और 'me just' cos यह व्यू के शीर्ष पर बॉर्डर नहीं डालता है - नीचे दिए गए कोड को संशोधित करना सरल है):
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];
मुझे लगता है कि इस पर एकमात्र उदारवादी लाभ है और एक छोटा उविअव या उइलैबेल बनाने का मतलब है कि काइलेयर माना जाता है कि 'हल्का-वजन' है, और कैलेयर्स का उपयोग करके बनाम बनाम राइडिंग ड्रॉ के बारे में बहुत सारे दिलचस्प विचार (जैसा कि राय में है) है (जैसे यहां) : iOS: UIView के 'drawRect:' बनाम इसकी लेयर की डेलीगेट 'drawLayer: inContext:' ) का उपयोग करना।
मुझे रंग नीला पसंद है।
N8tr के अलावा स्टोरीबोर्ड से उन्हें सेट करने के लिए एक उपलब्धता है कि जोड़ सकते हैं:
- जैसे borderColor
और borderWidth
inh फ़ाइल में दो गुण जोड़ें ;
- तब आप keyPaths
स्टोरीबोर्ड में सही जोड़ सकते हैं , स्क्रीनशॉट के लिए लिंक देख सकते हैं
कन्वर्ट दानिशे 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)
}
}
C # में Xamarin के लिए मैं बस उप परत जोड़ते समय सीमा इनलाइन बनाता हूं
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];
और यह ठीक तरह से रोटेशन को हैंडल करता है जबकि यहां पोस्ट किए गए अधिकांश उत्तर इसे अच्छी तरह से संभाल नहीं पाते हैं।
नोट: यहां अधिकांश समाधान अनुकूली नहीं हैं और आकार नहीं बदलेंगे। जो समाधान आकार लेंगे वे आपके स्टार्टअप समय पर बड़े पैमाने पर प्रभाव डालेंगे क्योंकि वे बहुत अधिक सीपीयू का उपयोग करते हैं।
आप इस घोल का प्रयोग नीचे कर सकते हैं। यह 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 के लिए टॉप बॉर्डर और बॉटम बॉर्डर सेट करने के लिए।
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)