So fügen Sie einen Rahmen direkt über einer UIView hinzu

144

Meine Frage ist auf den Titel.

Ich weiß nicht, wie ich einen Rand auf einer bestimmten Seite, oben oder unten, auf einer beliebigen Seite hinzufügen soll ... layer.borderzeichnet den Rand für die gesamte Ansicht ...

Mann im Mond
quelle
Mögliches Duplikat des unteren UIView-Randes?
Cœur

Antworten:

200

Ich denke hier über das Unterklassen UIViewund Überschreiben von drawRectOverkill nach. Warum nicht eine Erweiterung UIViewhinzufügen und Rahmenunteransichten hinzufügen?

@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

Mit diesem Code sind Sie auch nicht an Ihre Unterklasse gebunden. Sie können ihn auf alles anwenden, was erbt UIView- wiederverwendbar in Ihrem Projekt und auf alle anderen. Übergeben Sie andere Argumente an Ihre Methoden, um andere Farben und Breiten zu definieren. Viele Optionen.

Adam Waite
quelle
4
Der einzige Nachteil hier ist, dass die Größe nicht geändert werden kann.
Peter DeWeese
2
Könnte eine UIView verwenden und Einschränkungen für das automatische Layout hinzufügen. Gleiches Prinzip.
Adam Waite
1
@PeterDeWeese Dies ist auch kein Nachteil - wenn Sie die Größe des Rahmens steuern möchten, müssen Sie lediglich Folgendes tun: - (void) addUpperBorderWithSize: (CGFloat) size Und dann die Konstante durch einen Parameter in der Funktion ersetzen . Gleiches gilt für andere Parameter wie Farben.
o.shnn
1
@AdamWaite, diese Auto-Layout-Variante sieht sehr gut aus. Danke !
Manonthemoon
2
Vielen Dank für die gemeinsame Nutzung, mache ich eine Version von Objective-C mit Zwang Auto Layout hier .
Itachi
99

Adam Waites ursprünglicher Beitrag und die mehrfachen Änderungen wurden um Funktionen für abgerundete Ecken erweitert

Wichtig!: Vergessen Sie nicht, 'label.layoutIfNeeded ()' hinzuzufügen, bevor Sie 'addborder' aufrufen, wie zuvor kommentiert

Hinweis: Ich habe dies nur auf UILabels getestet.

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

}}

Dan
quelle
4
Dieser Code funktioniert aus irgendeinem Grund nicht mit Swift 3, nachdem die CGRectMake-Signatur und die CGColor per Swift 3
geändert wurden
Es gibt hier einen guten Artikel medium.com/swift-programming/… , der darüber spricht, was Sie für Swift 3 tun müssen.
Micah Montoya
2
Haben Sie Glück, dies in Swift 3 umzusetzen?
Marquavious Draggon
7
Damit es funktioniert, müssen Sie view.layoutIfNeeded()direkt vor dem Anruf hinzufügen view.layer.addBorder(...). Dann funktioniert es in Swift 3
Adam Studenic
es funktioniert gut. Fügen Sie die Zeile in dieser Methode hinzuoverride func viewDidLayoutSubviews()
Antony Raphel
60

Der beste Weg für mich ist eine Kategorie in UIView, aber adding viewsanstelle von CALayers, damit wir es könnentake advantage of AutoresizingMasks sicherstellen , dass die Größe der Rahmen zusammen mit der Übersicht geändert wird.

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

Swift 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)
}
Pauls
quelle
7
Dies ist bei weitem eine der besten Lösungen für dieses Problem. Die meisten anderen Lösungsangebote berücksichtigen KEINE Ansichtsänderungen (und damit Gerätedrehung oder geteilte Ansichten). Dieser tut es.
Womble
1
Wie kann dies angepasst werden, um abgerundete Ecken zu unterstützen?
8.
29

Swift 3.0

Swift 4.1

extension CALayer {

  func addBorder(edge: UIRectEdge, color: UIColor, thickness: CGFloat) {

    let border = CALayer()

    switch edge {
    case UIRectEdge.top:
        border.frame = CGRect(x: 0, y: 0, width: 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)
 }
}
AleyRobotics
quelle
1
Dies funktioniert nicht, wenn die Größe der Ansicht geändert wird, z. B. wenn sich die Ausrichtung ändert.
Nestor
Wenn Sie ein rahmenbasiertes Layout verwenden, müssen Sie layoutSubviews implementieren und alle darin enthaltenen Subview- (oder Sublayer-) Frames neu berechnen
Trapper
22

Unterklasse UIViewund Implementierung drawRect:in Ihrer Unterklasse, z.

Ziel c

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextMoveToPoint(context, CGRectGetMinX(rect), CGRectGetMinY(rect));
    CGContextAddLineToPoint(context, CGRectGetMaxX(rect), CGRectGetMinY(rect));
    CGContextSetStrokeColorWithColor(context, [[UIColor redColor] CGColor] );
    CGContextSetLineWidth(context, 2.0);
    CGContextStrokePath(context);
}

Swift 4

override func draw(_ rect: CGRect) {

    let cgContext = UIGraphicsGetCurrentContext()
    cgContext?.move(to: CGPoint(x: rect.minX, y: rect.minY))
    cgContext?.addLine(to: CGPoint(x: rect.maxX, y: rect.minY))
    cgContext?.setStrokeColor(UIColor.red.cgColor)
    cgContext?.setLineWidth(2.0)
    cgContext?.strokePath()
}

Dadurch wird eine rote Linie mit 2 Pixeln als oberer Rand gezeichnet. Alle anderen Variationen, die Sie erwähnen, bleiben dem Leser als triviale Übung.

Quartz 2D Programming Guide wird empfohlen.

FluffulousChimp
quelle
Ist es der einzige Weg dafür ??? Wenn ich also eine Ansicht mit einem oberen Rand und eine andere Ansicht mit einem unteren Rand und eine andere Ansicht erstellen muss ... Ich meine immer eine bestimmte Ansicht mit einem oder zwei Rändern, muss ich für jeden bestimmten Fall eine Unterklasse erstellen ??? Ich weiß nicht, ob es wirklich schön ist, eine Klasse zu erstellen, nur um Grenzen hinzuzufügen ...
Manonthemoon
1
Denk darüber nach. Ihre UIViewUnterklasse könnte eine Eigenschaft haben, die bestimmt, welche Rahmen gezogen werden drawRect:. Diese Eigenschaft kann mit definiert werden, NS_OPTIONSsodass eine Bitmaske wie die UIViewAutoresizingBitmaske definiert wird. Wenn Sie - aus welchem ​​Grund auch immer - wirklich stark gegen Unterklassen sind, UIViewfügen Sie einfach eine kleine Unteransicht mit einer Höhe von 1 bis 2 Pixel (oder einer breiten Breite) hinzu und geben Sie ihr die gewünschten Abmessungen, um einen Rand zu simulieren.
FluffulousChimp
Hey Leute, ich habe eine Swift-Unterklasse erstellt, die von diesem Code inspiriert ist. Ich hoffe, es gefällt
asiviero
19

Code für die ausgewählte Antwort, falls jemand dies wünscht.

HINWEIS: Dies funktioniert nicht mit Autolayout (auch bekannt als Drehen des Geräts in Querformat usw.).

Definieren Sie zuerst eine Dicke:

NSInteger borderThickness = 1;

Kopieren Sie dann einfach einige oder alle, um den Rahmen festzulegen, den Sie festlegen möchten.

Oberer Rand

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

Untere Grenze

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

Linker Rand

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

Rechter Rand

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];
Travis M.
quelle
Einfache Lösung ... mit einem UIView-Overhead im Vergleich zu nacktem CALayer
Soberman
Nachdem ich alle anderen Lösungen gelesen hatte, dachte ich, ich würde auch nur eine winzige Ansicht hinzufügen. All das funktioniert für eine Grenze! Diese Lösung benötigt nur ein paar Stifte, um auch im automatischen Layout zu funktionieren. Viel einfacher, den Kopf herumzukriegen.
Noobsmcgoobs
Vielen Dank, ich habe oben einen Hinweis hinzugefügt, damit Codierer nur verwenden, wenn sich ihre App nicht dreht.
Travis M.
15

Alte Frage, aber die Autolayout-Lösung mit Laufzeitrahmenanpassungen fehlt noch.

borders(for: [.left, .bottom], width: 2, color: .red)

Die folgende UIView-Erweiterung fügt den Rand nur an den angegebenen Kanten hinzu. Wenn Sie die Kanten zur Laufzeit ändern, werden die Ränder entsprechend angepasst.

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]))
                }
            }
        }
    }
}
seeppp
quelle
13

Schnelle Version:

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)

Bearbeiten: Für aktualisierte Versionen überprüfen Sie mein Repo hier: https://github.com/goktugyil/EZSwiftExtensions/blob/master/Sources/UIViewExtensions.swift

Schauen Sie sich die addBorder-Teile an

Esqarrouth
quelle
4

Ich nahm sowohl Adam Waites als auch Pauls Antworten und kombinierte sie. Ich habe auch die Möglichkeit hinzugefügt, die ausgewählten Kanten zusammenzuleiten, sodass Sie nur eine Funktion wie folgt aufrufen müssen:

[self.view addBordersToEdge:(UIRectEdgeLeft|UIRectEdgeRight)
                  withColor:[UIColor grayColor]
                   andWidth:1.0];

oder so:

[self.view addBordersToEdge:(UIRectEdgeAll)
                  withColor:[UIColor grayColor]
                   andWidth:1.0];

Was Sie implementieren müssen, ist eine Kategorie in UIView, wie in anderen Antworten mit der folgenden Implementierung vorgeschlagen:

- (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];
    }
}
Maco03
quelle
4

// MARK: - LeftBorder For View hinzufügen

(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 für Ansicht hinzufügen

(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: - Unteren Rand für Ansicht hinzufügen

(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];
}
Priyanka Jadhav
quelle
4

Swift 4.2 und AutoLayout

Ich habe die angebotenen Lösungen durchgesehen. Viele basieren auf Frames. Dies ist eine einfache Erweiterung, die mit AutoLayout funktioniert. Verwenden Sie Ansicht anstelle von Ebene, um sicherzustellen, dass AutoLayout - Einzelne Unteransicht mit 4 Einschränkungen verwendet werden kann

Verwenden Sie wie folgt:

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
        }
    }
}
eharo2
quelle
3

Ich habe einige Änderungen an Dans Antwort vorgenommen, damit ich mit einem Befehl mehreren Kanten Ränder hinzufügen kann:

infoView.addBorder(toEdges: [.left, .bottom, .right], color: borderColor, thickness: 1)

Hier ist der vollständige Code:

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)
        }
    }
}
NSExceptional
quelle
2

Aufbauend auf der Antwort von NSBum habe ich einen ähnlichen Ansatz gewählt und diese einfache UIView-Unterklasse so erstellt, dass sie in Interface Builder funktioniert und mit Einschränkungen funktioniert: Github-Link
Durch die Verwendung von CGContextFillRect anstelle von CGContextStrokePath konnte ich die Linien vorhersehbar vollständig fest und innerhalb halten die Grenzen der Sicht.

Hier ist mein Blog-Beitrag dazu: http://natrosoft.com/?p=55

- Legen Sie einfach eine UIView in Interface Builder ab und ändern Sie ihren Klassentyp in NAUIViewWithBorders.
- Dann machen Sie in viewDidLoad Ihres VC etwas wie:

/* 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];

Hier ist ein direkter Link zur .m-Datei, damit Sie die Implementierung sehen können. Es gibt auch ein Demo-Projekt. Hoffe das hilft jemandem :)

n8tr
quelle
2

Meine Antwort auf eine ähnliche Frage: https://stackoverflow.com/a/27141956/435766 Ich persönlich bevorzuge es, in dieser Kategorie den Weg der Kategorie zu gehen, da ich sie in jeder Unterklasse von UIView verwenden möchte.

P. Unto
quelle
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
            }
        }
    }

}
Ali Seymen
quelle
2

Hier ist eine einfache Lösung. Fügen Sie eine Beschriftung hinzu UIView, löschen Sie den Text auf der Beschriftung und legen Sie die Hintergrundfarbe der Beschriftung als Rahmenfarbe fest. Legen Sie den Ursprung (x,y)Ihres Etiketts als Ursprung (x,y)Ihrer Ansicht fest. und stellen Sie die Breite des Etiketts auf die Breite Ihres Etiketts ein UIView, stellen Sie die Höhe auf 1 oder 2 ein (für Ihre Rahmenhöhe oben auf Ihrem UIView). Und das sollte den Trick machen.

Wenn Pollavith
quelle
28
Es macht keinen Sinn, ein Label zu haben, es könnte genauso gut ein anderes UIView sein
maor10
1
Dies beantwortet nicht wirklich die Frage, ob einer uiview nur der obere Rand hinzugefügt wird. Dies ist eine schnelle Lösung, die bei komplexeren Problemen wahrscheinlich nicht funktioniert.
simon_smiley
1
siehe dies: stackoverflow.com/questions/7022656/…
Roland Kákonyi
2

Swift 3 Version

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

Um den entsprechenden Rahmen festzulegen, sollten Sie die Methode viewDidLayoutSubviews () überschreiben :

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    yourView.addBorder(toSide: UIView.ViewSide.Top, withColor: UIColor.lightGray, andThickness: 1)
karjaubayev
quelle
Wird es 'addSublayer' aufrufen, wenn das Layout aktualisiert wird?
Jeevan
1

Posten Sie einfach hier, um jemandem zu helfen, der nach dem Hinzufügen von Rahmen sucht. Ich habe ein paar Änderungen in der akzeptierten Antwort hier gemacht rasches Etikett nur linken Rand . Geänderte Breite bei Fall UIRectEdge.Topvon CGRectGetHeight(self.frame)bis CGRectGetWidth(self.frame)und bei Fall UIRectEdge.Bottomvon UIScreen.mainScreen().bounds.widthbisCGRectGetWidth(self.frame) , um die Ränder korrekt zu erhalten. Verwenden von Swift 2.

Schließlich lautet die Erweiterung:

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

}
Kavisha
quelle
1

Für den Fall, dass jemand jemals eine Xamarin-Version benötigt:

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);
    }
}
Array
quelle
1

Hier ist eine Swift 4-Version von Pauls 'Antwort

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)
}
NSExceptional
quelle
1

Inspiriert von @Addison habe ich die Erweiterung ohne Verwendung eines Frameworks von Drittanbietern umgeschrieben, da er SnapKit und CocoaLumberjack verwendet hat.

Wie beim @ Addisons-Ansatz entferne ich auch zuvor hinzugefügte Rahmen, sodass diese Implementierung mit wiederverwendbaren Ansichten als Tabellenzellen und Sammlungszellen gut funktionieren sollte.

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
    }
}
Andrej
quelle
1

Wenn ich aus dem Storyboard heraus baue, füge ich lieber ein UIViewhinter meinem nützlichen hinzu UIView... Wenn ich einen Rand über meinem erstellen möchte, UIViewerhöhe ich einfach die Höhe des Hintergrunds UIViewum meine Randbreite. Das Gleiche kann für jede andere Seite gemacht werden :)

Adrián Rivero
quelle
0

Persönlich mag ich die Unterklassifizierung von view + drawRect, aber hier ist nur eine andere Vorgehensweise (und sie funktioniert in etwa so, wie die von @If Pollavith akzeptierte Antwort):

Ihre neue Randebene kann so eingerichtet werden, dass sie beliebige Abmessungen aufweist. Wie bei der Antwort von @If Pollavith erstellen Sie eine Ebene, die so hoch ist, wie Sie möchten, und so breit wie die Ansicht, die Sie umrandet haben möchten. Verwenden Sie die Rahmendefinition der Ebene, um sie an der gewünschten Stelle zu platzieren, und fügen Sie sie dann als Unterebene zu Ihrer Ansicht hinzu.

Als Referenz bestand meine eigene Anforderung darin, einen Rand auf der LINKEN HAND-Seite der Ansicht einzufügen (bitte schneiden Sie diesen Code nicht aus und fügen Sie ihn ein, und deaktivieren Sie mich einfach, da er keinen Rand oben in der Ansicht einfügt - Das Ändern des folgenden Codes ist einfach genug):

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

Ich denke, der einzige moderate Vorteil gegenüber diesem und dem Erstellen eines kleinen UIView oder UILabel ist, dass der CALayer angeblich "leichter" ist und es viele interessante Ansichten (wie in Meinungen) über das Überschreiben von drawRect im Vergleich zur Verwendung von CALayers (wie hier) gibt : iOS: Verwenden von 'drawRect:' von UIView im Vergleich zu 'drawLayer: inContext:' ).

Animal451

Ich mag die Farbe blau.

Animal451
quelle
0

Zusätzlich zu n8tr kann hinzugefügt werden, dass es eine Verfügbarkeit gibt, um sie über das Storyboard festzulegen :
- Hinzufügen von zwei Eigenschaften wie borderColorund borderWidthin der .h-Datei;
- Dann können Sie keyPathsdirekt im Storyboard hinzufügen , siehe Link zum Screenshot

Mykhailo Lysenko
quelle
0

Konvertieren Sie die DanShev- Antwort in 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)
}
}
ADS
quelle
0

Für Xamarin in C # erstelle ich beim Hinzufügen der Unterebene einfach den Rahmen inline

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

Sie können dies (wie von anderen vorgeschlagen) für den unteren, linken und rechten Rand anordnen.

Craig Champion
quelle
0

Sie können auch diese Sammlung von UIKit- und Foundation-Kategorien überprüfen: https://github.com/leszek-s/LSCategories

Es ermöglicht das Hinzufügen eines Rahmens auf einer Seite von UIView mit einer einzigen Codezeile:

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

und es handhabt die Ansichtsrotation richtig, während die meisten hier veröffentlichten Antworten nicht gut damit umgehen.

Leszek Szary
quelle
0

Hinweis: Die meisten Lösungen hier sind nicht adaptiv und werden nicht in der Größe geändert. Die Lösungen, deren Größe geändert wird, werden massiv sein auf Ihre Startzeit aus, da sie viel CPU verbrauchen.

Sie können diese Lösung unten verwenden. Es funktioniert mit UIBezierPaths, die leichter als Ebenen sind und schnelle Startzeiten verursachen. Es ist einfach zu bedienen, siehe Anweisungen unten.

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. Setzen Sie die Klasse Ihres UIView auf ResizeBorderView
  2. Legen Sie die Farbe und Linienbreite mithilfe von yourview.color und yourview.lineWidth in Ihrer viewDidAppear-Methode fest
  3. Legen Sie die Kanten fest, Beispiel: yourview.edges = [.right, .left] ([.all]) für alle
  4. Genießen Sie den schnellen Start und die Größenänderung von Grenzen
J. Doe
quelle
0

Zum Festlegen des oberen und unteren Randes für eine UIView in 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)
Sudhi 9135
quelle
0

In Swift 4 und 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)
Naishta
quelle