วิธีเพิ่มเส้นขอบที่ด้านบนของ UIView


144

คำถามของฉันอยู่ที่ชื่อ

ฉันไม่ทราบวิธีเพิ่มเส้นขอบในด้านเฉพาะด้านบนหรือด้านล่างด้านใดด้านหนึ่ง ... layer.borderดึงเส้นขอบสำหรับมุมมองทั้งหมด ...


เป็นไปได้ซ้ำกันของเส้นขอบด้านล่าง
Cœur

คำตอบ:


200

ฉันพิจารณา subclassing UIViewและ overkiding drawRectoverkill ที่นี่ ทำไมไม่เพิ่มส่วนขยาย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- นำมาใช้ใหม่ในโครงการของคุณและคนอื่น ๆ ส่งผ่านข้อโต้แย้งอื่น ๆ ไปยังวิธีการของคุณเพื่อกำหนดสีและความกว้างอื่น ๆ ตัวเลือกมากมาย


4
ข้อเสียเดียวที่นี่คือมันไม่สามารถปรับขนาด
Peter DeWeese

2
สามารถใช้ UIView และเพิ่มข้อ จำกัด เลย์เอาต์อัตโนมัติ หลักการเดียวกัน
Adam Waite

1
@PeterDeWeese นี่ไม่ใช่ข้อเสีย - ถ้าคุณต้องการควบคุมขนาดของเส้นขอบสิ่งที่คุณต้องทำคือ: - (เป็นโมฆะ) addUpperBorderWithSize: (CGFloat) ขนาดแล้วแทนที่ค่าคงที่ด้วยพารามิเตอร์ในฟังก์ชัน . กันไปสำหรับพารามิเตอร์อื่น ๆ เช่นสี
o.shnn

1
@ AdamWaite ชุดรูปแบบอัตโนมัตินี้ดูดีมาก ขอบคุณ !
manonthemoon

2
ขอบคุณสำหรับการแบ่งปันผมทำรุ่นของ Objective-C ที่มีข้อ จำกัด รูปแบบอัตโนมัติที่นี่
Itachi

99

เพิ่มความสามารถสำหรับมุมโค้งมนไปยังโพสต์ดั้งเดิมของ Adam Waite และการแก้ไขหลายรายการ

สำคัญ!: อย่าลืมเพิ่ม ' 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)
    }
}

4
รหัสนี้ไม่ทำงานบน Swift 3 ด้วยเหตุผลบางอย่างหลังจากเปลี่ยนลายเซ็น CGRectMake และ CGColor ต่อ Swift 3
EmbCoder

มีบทความดีๆอยู่ที่นี่medium.com/swift-programming/ …ที่พูดถึงสิ่งที่คุณต้องทำเพื่อ Swift 3
คาห์มอนโตยะ

2
มีโชคในการนำไปใช้ใน 3 อย่างรวดเร็วหรือไม่?
Draggon Marquavious

7
ที่จะทำให้มันทำงานคุณต้องเพิ่มทางขวาก่อนที่จะเรียกview.layoutIfNeeded() view.layer.addBorder(...)จากนั้นใช้งานได้ใน Swift 3
Adam Studenic

มันทำงานได้ดี เพิ่มบรรทัดในวิธีนี้override func viewDidLayoutSubviews()
Antony Raphel

60

วิธีที่ดีที่สุดสำหรับฉันคือหมวดหมู่ของ UIView แต่adding viewsแทนที่จะเป็น 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)
}

7
นี่คือหนึ่งในทางออกที่ดีที่สุดสำหรับปัญหานี้ โซลูชันอื่น ๆ ส่วนใหญ่เสนอไม่ให้เกียรติการเปลี่ยนแปลงมุมมอง (และเช่นการหมุนอุปกรณ์หรือแยกมุมมอง) อันนี้ทำ
Womble

1
สิ่งนี้สามารถปรับให้รองรับมุมมนได้อย่างไร
ntaj

29

Swift 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)
 }
}

1
สิ่งนี้จะไม่ทำงานเมื่อมุมมองปรับขนาดเช่นการเปลี่ยนแนว
Nestor

หากคุณใช้โครงร่างแบบอิงเฟรมคุณจะต้องใช้ layoutSubviews และคำนวณเฟรมย่อยมุมมองย่อย (หรือเลเยอร์ย่อย) ทั้งหมดอีกครั้ง
trapper

22

คลาสย่อยUIViewและนำไปใช้drawRect:ในคลาสย่อยของคุณเช่น:

Objective-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 พิกเซลเป็นเส้นขอบด้านบน รูปแบบอื่น ๆ ทั้งหมดที่คุณพูดถึงนั้นเป็นแบบฝึกหัดเล็กน้อยสำหรับผู้อ่าน

แนะนำให้ใช้โปรแกรมการเขียนโปรแกรมควอตซ์ 2D


มันเป็นทางเดียวเท่านั้นใช่มั้ย ??? ดังนั้นถ้าฉันต้องการสร้างมุมมองด้วยเส้นขอบด้านบนและมุมมองอื่นที่มีเส้นขอบด้านล่างและมุมมองอื่น ๆ ... ฉันหมายถึงมุมมองที่เฉพาะเจาะจงที่มีเส้นขอบหนึ่งหรือสองเส้นเสมอฉันจะต้องสร้างคลาสย่อยสำหรับแต่ละกรณี ??? ฉันไม่รู้ว่ามันดีจริงๆหรือที่จะสร้างคลาสเพื่อเพิ่มเส้นขอบ ...
manonthemoon

1
ไม่คิดเกี่ยวกับมัน UIViewคลาสย่อยของคุณอาจมีคุณสมบัติที่กำหนดว่าจะdrawRect:วาดเส้นขอบใด คุณสมบัตินี้สามารถกำหนดด้วยNS_OPTIONSเพื่อที่จะกำหนด bitmask เช่นUIViewAutoresizingbitmask ถ้า - ด้วยเหตุผลใดก็ตาม - คุณคัดค้านอย่างยิ่งที่จะทำการซับคลาสUIViewแล้วเพียงแค่เพิ่มมุมมองย่อย (หรือกว้าง) สูง 1-2 พิกเซลและให้มิติใดก็ตามที่คุณต้องการจำลองขอบ
FluffulousChimp

เฮ้พวกฉันทำคลาสย่อย Swift ที่ได้รับแรงบันดาลใจจากรหัสนี้หวังว่าคุณจะสนุกกับมัน: gist.github.com/asiviero/4f52ab7dea7d9252a64c
asiviero

19

รหัสสำหรับคำตอบที่เลือกในกรณีที่ทุกคนต้องการ

หมายเหตุ: วิธีนี้ใช้ไม่ได้กับการหมุนอัตโนมัติ (aka การหมุนอุปกรณ์เป็นแนวนอน ฯลฯ )

ก่อนกำหนดความหนา:

NSInteger borderThickness = 1;

จากนั้นเพียงคัดลอกใช้สิ่งเหล่านี้เพื่อตั้งค่าเส้นขอบที่คุณต้องการ

ขอบด้านบน

UIView *topBorder = [UIView new];
topBorder.backgroundColor = [UIColor lightGrayColor];
topBorder.frame = CGRectMake(0, 0, myView.frame.size.width, borderThickness);
[myView addSubview:topBorder];

ขอบด้านล่าง

UIView *bottomBorder = [UIView new];
bottomBorder.backgroundColor = [UIColor lightGrayColor];
bottomBorder.frame = CGRectMake(0, myView.frame.size.height - borderThickness, myView.frame.size.width, borderThickness);
[myView addSubview:bottomBorder];

ชายแดนด้านซ้าย

UIView *leftBorder = [UIView new];
leftBorder.backgroundColor = [UIColor lightGrayColor];
leftBorder.frame = CGRectMake(0, 0, borderThickness, myView.frame.size.height);
[myView addSubview:leftBorder];

ชายแดนด้านขวา

UIView *rightBorder = [UIView new];
rightBorder.backgroundColor = [UIColor lightGrayColor];
rightBorder.frame = CGRectMake(myView.frame.size.width - borderThickness, 0, borderThickness, myView.frame.size.height);
[myView addSubview:rightBorder];

วิธีการแก้ปัญหาที่ตรงไปตรงมา ... กับ UIView ค่าใช้จ่ายเมื่อเทียบกับเปลือย CALayer
Soberman

หลังจากอ่านวิธีแก้ปัญหาอื่น ๆ ทั้งหมดฉันคิดว่าฉันแค่เพิ่มมุมมองเล็ก ๆ เช่นกัน ทุกอย่างใช้งานได้สำหรับชายแดน! วิธีการแก้ปัญหานี้ต้องการพินเพียงเล็กน้อยเพื่อทำงานในเลย์เอาต์อัตโนมัติเช่นกัน วิธีที่จะทำให้หัวของคุณง่ายขึ้น
noobsmcgoobs

ขอขอบคุณฉันได้เพิ่มบันทึกด้านบนเพื่อให้ผู้เข้ารหัสจะใช้เฉพาะเมื่อแอปไม่หมุน
Travis M.

15

คำถามเก่า แต่วิธีแก้ปัญหาอัตโนมัติที่มีการปรับขอบแบบรันไทม์ยังคงหายไป

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]))
                }
            }
        }
    }
}

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)

แก้ไข: สำหรับรุ่นที่ปรับปรุงตรวจสอบ repo ของฉันที่นี่: https://github.com/goktugyil/EZSwiftExtensions/blob/master/Sources/UIViewExtensions.swift

ดูที่ส่วน AddBorder


5

Swift 4.2 และ AutoLayout

ฉันผ่านโซลูชั่นที่นำเสนอ หลายตัวใช้เฟรมเป็นส่วนขยายแบบง่ายที่ทำงานกับ AutoLayout - ใช้มุมมองแทน Layer เพื่อให้แน่ใจว่าเราสามารถใช้ 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
        }
    }
}

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];
    }
}

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];
}

3

ฉันทำการเปลี่ยนแปลงคำตอบของ 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)
        }
    }
}

2

อาคารออกจากNSBum ของคำตอบที่ผมเอาวิธีการที่คล้ายกันและสร้างขึ้นนี้ subclass UIView ง่ายเพื่อที่จะทำงานใน Interface Builder และทำงานร่วมกับข้อ จำกัด : การเชื่อมโยง GitHub
โดยใช้ CGContextFillRect แทน CGContextStrokePath ผมก็สามารถที่จะคาดการณ์ให้สายสมบูรณ์มั่นคงและภายใน ขอบเขตของมุมมอง

นี่คือบล็อกของฉันเกี่ยวกับโพสต์: http://natrosoft.com/?p=55

- โดยทั่วไปเพียงแค่วาง UIView ใน Interface Builder และเปลี่ยนประเภทคลาสเป็น 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เพื่อให้คุณสามารถเห็นการใช้งาน มีโครงการสาธิตเช่นกัน หวังว่าจะช่วยให้ใครบางคน :)


2

คำตอบของฉันสำหรับคำถามที่คล้ายกัน: https://stackoverflow.com/a/27141956/435766 ฉันชอบไปตามถนนหมวดหมู่ในนั้นเนื่องจากฉันต้องการที่จะใช้มันในคลาสย่อยของ UIView


2
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
            }
        }
    }

}

2

นี่เป็นวิธีง่ายๆ เพิ่มป้ายกำกับของคุณUIViewล้างข้อความบนป้ายกำกับและตั้งค่าสีพื้นหลังของป้ายกำกับให้เป็นสีเส้นขอบของคุณ กำหนดจุดเริ่มต้น(x,y)ของป้ายกำกับของคุณให้เป็นจุดเริ่มต้น(x,y)ของมุมมองของคุณ และตั้งค่าความกว้างของฉลากให้เป็นความกว้างของคุณUIViewตั้งความสูงเป็น 1 หรือ 2 (สำหรับความสูงชายแดนที่ด้านบนของคุณUIView) และนั่นควรทำเคล็ดลับ


28
ไม่มีจุดที่จะมีป้ายกำกับแล้วเช่นกันอาจเป็นอีก UIView
maor10

1
นี่ไม่ได้ตอบคำถามที่ว่าจะเพิ่มเฉพาะขอบบนสุดของ uiview เท่านั้น นี่เป็นการแก้ไขด่วนซึ่งอาจไม่สามารถแก้ไขปัญหาที่ซับซ้อนได้มากขึ้น
simon_smiley


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)

มันจะเรียกว่า 'addSublayer' ทุกครั้งที่เลย์เอาต์ได้รับการอัพเดตหรือไม่
byJeevan

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)
}

}

1

ในกรณีที่มีคนต้องการรุ่น Xamarin:

public static class UIUtils
{
    public static void AddBorder(this CALayer cALayer, UIRectEdge edge, UIColor color, float thickness)
    {

        var border = new CALayer();
        switch (edge) 
        {
            case UIRectEdge.Top:
                border.Frame = new CGRect(0, 0, cALayer.Frame.Width, height: thickness);
                break;
            case UIRectEdge.Bottom:
                border.Frame = new CGRect(0, cALayer.Frame.Height - thickness, width: cALayer.Frame.Width, height: thickness);
                break;
            case UIRectEdge.Left:
                border.Frame = new CGRect(0, 0, width: thickness, height: cALayer.Frame.Height);
                break;
            case UIRectEdge.Right:
                border.Frame = new CGRect(cALayer.Frame.Width - thickness, y: 0, width: thickness, height: cALayer.Frame.Height);
                break;
            default: break;
        }
        border.BackgroundColor = color.CGColor;
        cALayer.AddSublayer(border);
    }
}

1

นี่คือคำตอบของ Paulsรุ่น Swift 4

func addTopBorder(color: UIColor, thickness: CGFloat) {
    let border = UIView()
    border.backgroundColor = color
    border.autoresizingMask = [.flexibleWidth, .flexibleBottomMargin]
    border.frame = CGRect(x: 0, y: 0, width: frame.size.width, height: thickness)
    addSubview(border)
}

func addBottomBorder(color: UIColor, thickness: CGFloat) {
    let border = UIView()
    border.backgroundColor = color
    border.autoresizingMask = [.flexibleWidth, .flexibleTopMargin]
    border.frame = CGRect(x: 0, y: frame.size.height - thickness, width: frame.size.width, height: thickness)
    addSubview(border)
}

func addLeftBorder(color: UIColor, thickness: CGFloat) {
    let border = UIView()
    border.backgroundColor = color
    border.autoresizingMask = [.flexibleHeight, .flexibleRightMargin]
    border.frame = CGRect(x: 0, y: 0, width: thickness, height: frame.size.height)
    addSubview(border)
}

func addRightBorder(color: UIColor, thickness: CGFloat) {
    let border = UIView()
    border.backgroundColor = color
    border.autoresizingMask = [.flexibleHeight, .flexibleLeftMargin]
    border.frame = CGRect(x: frame.size.width - thickness, y: 0, width: thickness, height: frame.size.height)
    addSubview(border)
}

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
    }
}

1

ถ้าฉันสร้างจากภายในกระดานเรื่องราวฉันต้องการเพิ่มUIViewด้านหลังของฉันมีประโยชน์UIView... ถ้าฉันต้องการสร้างเส้นขอบด้านบนของฉันUIViewฉันแค่เพิ่มความสูงของพื้นหลังUIViewตามความกว้างชายแดนของฉัน .. สามารถเดียวกัน จะทำเพื่อด้านอื่น ๆ :)


0

โดยส่วนตัวแล้วฉันชอบการจัดหมวดหมู่ย่อยของมุมมอง + 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];

ฉันเดาว่ามีประโยชน์ปานกลางในเรื่องนี้และการสร้าง UIView หรือ UILabel เล็ก ๆ ก็คือ CALayer นั้นควรจะเป็น 'น้ำหนักเบา' และมีมุมมองที่น่าสนใจมากมาย : iOS: การใช้ 'drawRect:' กับ UUVIEW ของ delagate 'layer เลเยอร์' drawLayer: inContext: ' )

Animal451

ฉันชอบสีฟ้า


0

นอกจากn8trสามารถเพิ่มว่ามีความพร้อมในการตั้งค่าจากกระดานเรื่องราว:
- เพิ่มคุณสมบัติสองอย่างเช่นborderColorและborderWidthในไฟล์. h;
- จากนั้นคุณสามารถเพิ่มkeyPathsสิทธิ์ลงในกระดานเรื่องราวดูลิงก์ไปที่ภาพหน้าจอ


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)
}
}

0

สำหรับ Xamarin ใน C # ฉันเพิ่งสร้างอินไลน์ชายแดนเมื่อเพิ่มเลเยอร์ย่อย

  View.Layer.AddSublayer(new CALayer()
    {
        BackgroundColor = UIColor.Black.CGColor,
        Frame = new CGRect(0, 0, View.Frame.Width, 0.5f)
    });

คุณสามารถจัดเรียงสิ่งนี้ (ตามที่คนอื่นแนะนำ) สำหรับขอบล่างซ้ายและขวา


0

นอกจากนี้คุณยังสามารถตรวจสอบคอลเล็กชันของ UIKit และหมวดหมู่มูลนิธิ: https://github.com/leszek-s/LSCหมวดหมู่

อนุญาตให้เพิ่มเส้นขอบที่ด้านหนึ่งของ UIView ด้วยรหัสบรรทัดเดียว:

[self.someView lsAddBorderOnEdge:UIRectEdgeTop color:[UIColor blueColor] width:2];

และจัดการกับมุมมองการหมุนอย่างถูกต้องในขณะที่คำตอบส่วนใหญ่ที่โพสต์ที่นี่ตอบสนองได้ไม่ดีนัก


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()
        }
    }
}
  1. ตั้งค่าคลาส UIView ของคุณเป็น ResizeBorderView
  2. ตั้งค่าสีและความกว้างของเส้นโดยใช้ yourview.color และ yourview.lineWidth ในเมธอด viewDidAppear ของคุณ
  3. ตั้งค่าขอบตัวอย่าง: yourview.edges = [.right, .left] ([.all]) สำหรับทุกคน
  4. เพลิดเพลินกับการเริ่มต้นและปรับขนาดเส้นขอบอย่างรวดเร็ว

0

สำหรับการตั้งค่าขอบด้านบนและขอบด้านล่างสำหรับ UIView ใน Swift

let topBorder = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: 1))
topBorder.backgroundColor = UIColor.black
myView.addSubview(topBorder)

let bottomBorder = UIView(frame: CGRect(x: 0, y: myView.frame.size.height - 1, width: 10, height: 1))
bottomBorder.backgroundColor = UIColor.black
myView.addSubview(bottomBorder)

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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.