Gestrichelter Rand um UIView

Antworten:

131

Sie können den Rahmen mit diesem Muster mithilfe des Ebenen- und Bezier-Pfads wie in den folgenden Beispielen festlegen.

Ziel c

CAShapeLayer *yourViewBorder = [CAShapeLayer layer];
yourViewBorder.strokeColor = [UIColor blackColor].CGColor;
yourViewBorder.fillColor = nil;
yourViewBorder.lineDashPattern = @[@2, @2];
yourViewBorder.frame = yourView.bounds;
yourViewBorder.path = [UIBezierPath bezierPathWithRect:yourView.bounds].CGPath;
[yourView.layer addSublayer:yourViewBorder];

Swift 3.1

var yourViewBorder = CAShapeLayer()
yourViewBorder.strokeColor = UIColor.black.cgColor
yourViewBorder.lineDashPattern = [2, 2]
yourViewBorder.frame = yourView.bounds
yourViewBorder.fillColor = nil
yourViewBorder.path = UIBezierPath(rect: yourView.bounds).cgPath
yourView.layer.addSublayer(yourViewBorder)

Sie können auch verschiedene Arten von Designs mithilfe des Musterbilds wie im folgenden Beispiel festlegen.

[yourView.layer setBorderWidth:5.0];
[yourView.layer setBorderColor:[[UIColor colorWithPatternImage:[UIImage imageNamed:@"DotedImage.png"]] CGColor]];///just add image name and create image with dashed or doted drawing and add here

Hier müssen Sie <QuartzCore/QuartzCore>dem Projekt ein Framework hinzufügen und es mit der folgenden Zeile in die YourViewController.mDatei importieren .

#import <QuartzCore/QuartzCore.h>
Paras Joshi
quelle
2
Es ist kein perfekter Weg, wenn es um iPhone6 ​​Plus geht. Die gepunktete Linie könnte unscharf werden.
Jacky
1
@ Jacky: Verwenden Sie ein Bild mit höherer Auflösung. :)
Olie
6
Was ist ein Beispiel für das Bild?
Tom Roggero
1
Können Sie ein Beispiel für das Bild geben?
Jonguo
1
Jonguo Wenn Sie beispielsweise ein Bild mit der richtigen Auflösung hinzufügen, z. B. eine normale Bildgröße von 120 x 120 und der Name test.png, erstellen Sie zwei weitere Bilder mit dem Namen [email protected] und [email protected] mit einer Größe von 240 x 240 und 360x360, das in allen Apple-Geräten automatisch mit dem zugehörigen Namen verwendet wird. (dh test.png wird in iPhone 4 verwendet, test @ 2x ist nützlich für iPhone 4s, 5, 5s, 6, 6s und twst @ 3x ist nützlich für iPhone 6 plus, 6s plus.
Paras Joshi
273

Eine andere Methode, wenn Sie Unterschichten mögen. Fügen Sie in der Init Ihrer benutzerdefinierten Ansicht Folgendes ein (_border ist ein ivar):

_border = [CAShapeLayer layer];
_border.strokeColor = [UIColor colorWithRed:67/255.0f green:37/255.0f blue:83/255.0f alpha:1].CGColor;
_border.fillColor = nil;
_border.lineDashPattern = @[@4, @2];
[self.layer addSublayer:_border];

Und in Ihre Layoutsubviews setzen Sie Folgendes:

_border.path = [UIBezierPath bezierPathWithRect:self.bounds].CGPath;
_border.frame = self.bounds;
Chris
quelle
41
Nett! Sie können auch so etwas für einen abgerundeten Effekt verwenden:_border.path = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:5.f].CGPath;
Everton Cunha
Es tut uns leid! Ich verstehe es nicht Irgendein Beispiel? @ VertonCunha
Yi Jiang
3
@ VanDuTran Im ersten Ausschnitt,_border.lineWidth = 3
Chris
1
Hey, ich habe diesen Code auf die Beschriftung in der Zelle der Tabellenansicht angewendet, aber er gibt eine kleine Rahmengröße an. Wie kann ich das korrigieren?
Chaudhary Ankit Deshwal
3
Swift 3: border = CAShapeLayer() border.strokeColor = yourColor border.fillColor = nil border.lineDashPattern = [4, 2] self.layer.addSublayer(border)
Geek20
71

Für diejenigen unter Ihnen, die in Swift arbeiten, macht diese Klassenerweiterung in UIView es einfach. Dies basierte auf der Antwort von sunshineDev.

extension UIView {
  func addDashedBorder() {
    let color = UIColor.red.cgColor

    let shapeLayer:CAShapeLayer = CAShapeLayer()
    let frameSize = self.frame.size
    let shapeRect = CGRect(x: 0, y: 0, width: frameSize.width, height: frameSize.height)

    shapeLayer.bounds = shapeRect
    shapeLayer.position = CGPoint(x: frameSize.width/2, y: frameSize.height/2)
    shapeLayer.fillColor = UIColor.clear.cgColor
    shapeLayer.strokeColor = color
    shapeLayer.lineWidth = 2
    shapeLayer.lineJoin = CAShapeLayerLineJoin.round
    shapeLayer.lineDashPattern = [6,3]
    shapeLayer.path = UIBezierPath(roundedRect: shapeRect, cornerRadius: 5).cgPath

    self.layer.addSublayer(shapeLayer)
    }
}

Um es zu benutzen:

anyView.addDashedBorder()
Geld
quelle
2
Tolles Stück Code! Nur ein Problem: Wenn ich es auf ein UIImageView anwende, erkennt es nicht die gesamte Breite, es macht ungefähr 80% davon aus.
Arielcr
1
Ich denke, Sie rufen wahrscheinlich addDashBorder zu früh an, versuchen Sie es in didLayoutSubviews
Godfather
3
Ich habe eine benutzerdefinierte UIView erstellt und diese Erweiterung eingefügt. Dann rief ich an, addDashedBorder()während ich didMoveToSuperview()dachte, dass das Autolayout bis dahin abgeschlossen sein würde und die Rahmengröße korrekt wäre, aber es war nicht so. Die Breite des gestrichelten Rahmens geht über die Breite der Ansicht hinaus. Die gestrichelte Linie sieht übrigens so gut aus! Das self.frame.sizeist nicht richtig.
Levibostian
self.layer.masksToBounds = true Verwenden Sie diese Option, wenn die Grenzen
überschritten werden
@rmooney hat xcellent funktioniert, aber das Problem ist, wenn Sie eine Unterebene in eine dynamische UITableView-Zelle einfügen, dass die Ebene als Ebene des Storyboards betrachtet wird und nicht in einer benutzerdefinierten Zelle funktioniert. Die Größe unterscheidet sich, wenn Ihre Storyboard-Breite 375 Pixel beträgt Größe und es wird nicht in einem größeren Gerät wie 414px und so weiter funktionieren.
Azharhussain Shaikh
18

Swift 3 :

import UIKit

class UIViewWithDashedLineBorder: UIView {

    override func draw(_ rect: CGRect) {

        let path = UIBezierPath(roundedRect: rect, cornerRadius: 0)

        UIColor.purple.setFill()
        path.fill()

        UIColor.orange.setStroke()
        path.lineWidth = 5

        let dashPattern : [CGFloat] = [10, 4]
        path.setLineDash(dashPattern, count: 2, phase: 0)
        path.stroke()
    }
}

Verwendung in einem Storyboard (als benutzerdefinierte Klasse) oder direkt im Code:

let v = UIViewWithDashedLineBorder(frame: CGRect(x: 0, y: 0, width: 100, height: 100))

Ergebnis:

Geben Sie hier die Bildbeschreibung ein

Schärpe
quelle
Überraschen Sie, dass es dazu keine weiteren Stimmen gibt. Diese Lösung funktioniert am besten mit dem automatischen Layout im Vergleich zu anderen Antworten.
Yuchen Zhong
17

Aufbauend auf den Vorschlägen von Prasad G habe ich eine Methode in einer UIImage Extras-Klasse mit den folgenden Methoden erstellt:

- (CAShapeLayer *) addDashedBorderWithColor: (CGColorRef) color {
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];

    CGSize frameSize = self.size;

    CGRect shapeRect = CGRectMake(0.0f, 0.0f, frameSize.width, frameSize.height);
    [shapeLayer setBounds:shapeRect];
    [shapeLayer setPosition:CGPointMake( frameSize.width/2,frameSize.height/2)];

    [shapeLayer setFillColor:[[UIColor clearColor] CGColor]];
    [shapeLayer setStrokeColor:color];
    [shapeLayer setLineWidth:5.0f];
    [shapeLayer setLineJoin:kCALineJoinRound];
    [shapeLayer setLineDashPattern:
     [NSArray arrayWithObjects:[NSNumber numberWithInt:10],
      [NSNumber numberWithInt:5],
      nil]];
    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:shapeRect cornerRadius:15.0];
    [shapeLayer setPath:path.CGPath];

    return shapeLayer;
}

Es ist wichtig darauf hinzuweisen, dass, wenn Sie die Position Ihrer Form als (0,0) definieren, die untere Ecke des Rahmens in der Bildmitte platziert wird. Deshalb habe ich Folgendes festgelegt: (frameSize.width / 2, frameSize Höhe / 2)

Ich verwende dann meine Methode, um den gestrichelten Rand mithilfe des UIImage meiner UIImageView abzurufen und die CAShapeLayer als Unterebene der UIImageView-Ebene hinzuzufügen:

[myImageView.layer addSublayer:[myImageView.image addDashedBorderWithColor:[[UIColor whiteColor] CGColor]]];
sunshineDev
quelle
16

Verwenden Sie die CGContextSetLineDash () -Methode.

CGFloat dashPattern[]= {3.0, 2};

context =UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
// And draw with a blue fill color
CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1.0);
// Draw them with a 2.0 stroke width so they are a bit more visible.
CGContextSetLineWidth(context, 4.0);
CGContextSetLineDash(context, 0.0, dashPattern, 2);

CGContextAddRect(context, self.bounds);

// Close the path
CGContextClosePath(context);

CGContextStrokePath(context);

// Fill & stroke the path
CGContextDrawPath(context, kCGPathFillStroke);

Ich denke, es wird Ihnen hilfreich sein.

Prasad G.
quelle
1
Was ist hier Kontext?
Avinash Sharma
11

Hier ist eine UIView-Unterklasse, die für jedes Projekt geeignet ist. Sie funktioniert auch für runde Ansichten:

import UIKit

class CustomDashedView: UIView {

    @IBInspectable var cornerRadius: CGFloat = 0 {
        didSet {
            layer.cornerRadius = cornerRadius
            layer.masksToBounds = cornerRadius > 0
        }
    }
    @IBInspectable var dashWidth: CGFloat = 0
    @IBInspectable var dashColor: UIColor = .clear
    @IBInspectable var dashLength: CGFloat = 0
    @IBInspectable var betweenDashesSpace: CGFloat = 0

    var dashBorder: CAShapeLayer?

    override func layoutSubviews() {
        super.layoutSubviews()
        dashBorder?.removeFromSuperlayer()
        let dashBorder = CAShapeLayer()
        dashBorder.lineWidth = dashWidth
        dashBorder.strokeColor = dashColor.cgColor
        dashBorder.lineDashPattern = [dashLength, betweenDashesSpace] as [NSNumber]
        dashBorder.frame = bounds
        dashBorder.fillColor = nil
        if cornerRadius > 0 {
            dashBorder.path = UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).cgPath
        } else {
            dashBorder.path = UIBezierPath(rect: bounds).cgPath
        }
        layer.addSublayer(dashBorder)
        self.dashBorder = dashBorder
    }
}

Auf diese Weise können Sie vom Storyboard aus wie folgt bearbeiten:

Geben Sie hier die Bildbeschreibung ein

Ein paar Ergebnisse:

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

xavi.pedrals
quelle
10

Dazu müssen Sie CAShapeLayer für dieses bestimmte Objekt hinzufügen

 CAShapeLayer * dotborder = [CAShapeLayer layer];
    dotborder.strokeColor = [UIColor redColor].CGColor;//your own color
    dotborder.fillColor = nil;
    dotborder.lineDashPattern = @[@4, @2];//your own patten 
    [codeBtn.layer addSublayer:dotborder];
    dotborder.path = [UIBezierPath bezierPathWithRect:codeBtn.bounds].CGPath;
    dotborder.frame = codeBtn.bounds;
btmanikandan
quelle
7

Swift 4.2

Basierend auf der Antwort von rmooney als UIViewErweiterung mit konfigurierbaren Parametern, für die Standardwerte festgelegt wurden.

Beachten Sie, dass dies nicht funktioniert, wenn die Ansicht hat self.translatesAutoresizingMaskIntoConstraints = false

extension UIView {
  func addDashedBorder(_ color: UIColor = UIColor.black, withWidth width: CGFloat = 2, cornerRadius: CGFloat = 5, dashPattern: [NSNumber] = [3,6]) {

    let shapeLayer = CAShapeLayer()

    shapeLayer.bounds = bounds
    shapeLayer.position = CGPoint(x: bounds.width/2, y: bounds.height/2)
    shapeLayer.fillColor = nil
    shapeLayer.strokeColor = color.cgColor
    shapeLayer.lineWidth = width
    shapeLayer.lineJoin = CAShapeLayerLineJoin.round // Updated in swift 4.2
    shapeLayer.lineDashPattern = dashPattern
    shapeLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).cgPath

    self.layer.addSublayer(shapeLayer)
  }
}
Dan Leonard
quelle
shapeLayer.lineJoin = CAShapeLayerLineJoin.roundsollte seinyourViewBorder.lineJoin = kCALineJoinRound
pw2
6

Schnelle Version der QuartzCore-Antwort.

import QuartzCore    

let dottedPattern = UIImage(named: "dottedPattern")
myView.layer.borderWidth = 1
myView.layer.borderColor = UIColor(patternImage: dottedPattern!).CGColor

Der CAShapeLayerAnsatz funktioniert, aber der QuartzCore-Ansatz kann ein erneutes Laden der Tabellenansicht besser verarbeiten, wenn sich der Ansatz UIViewin einer Zelle befindet.

Für das Bild können Sie so etwas verwenden (es ist wirklich klein):

Geben Sie hier die Bildbeschreibung ein

Ich bevorzuge Vektoren gegenüber PNGs, wenn ich damit durchkommen kann:

  • Erstellen Sie in Sketch ein 4x4-Pixel-Rechteck.
  • Machen Sie insgesamt vier davon
  • Gruppieren Sie sie zu einem viereckigen, abwechselnden Farbton
  • Exportieren Sie die Gruppe als PDF
  • Images.xcassetsErstellen Sie innerhalb ein New Image Setaufgerufenes dottedPattern
  • Ändern Sie das Scale FactorsinSingle Vector
  • Legen Sie Ihr PDF ab
Robert Chen
quelle
6

Für Xamarin.iOS gestrichelter / gepunkteter Rand.

        dottedLayer = new CAShapeLayer();
        dottedLayer.StrokeColor = UIColor.FromRGB(202, 202, 208).CGColor; 
        dottedLayer.FillColor = null;
        dottedLayer.LineDashPattern = new[] { new NSNumber(4), new NSNumber(2) };

        dottedLayer.Path = UIBezierPath.FromRect(YourView.Bounds).CGPath; //for square
        dottedLayer.Path = UIBezierPath.FromRoundedRect(YourView.Bounds, 5).CGPath; //for rounded corners

        dottedLayer.Frame = YourView.Bounds;
        YourView.Layer.AddSublayer(dottedLayer);
c.lamont.dev
quelle
Bitte erläutern Sie Ihre Antwort ein wenig, anstatt nur das Code-Snippet einzufügen.
Kabirbaidhya
1
Hinweis für zukünftige Leser: Sie müssen den Namespace CoreAnimation verwenden, um den CAShapeLayer-Konstruktor verwenden zu können.
jnel899
6

In Swift 3

let border = CAShapeLayer();
border.strokeColor = UIColor.black.cgColor;
border.fillColor = nil;
border.lineDashPattern = [4, 4];
border.path = UIBezierPath(rect: theView.bounds).cgPath
border.frame = theView.bounds;
theView.layer.addSublayer(border);
ddb
quelle
4

Dies ist, wenn Sie es in Swift 2 wollten

func addDashedLineBorderWithColor(color:UIColor) {
    let _ = self.sublayers?.filter({$0.name == "DashedBorder"}).map({$0.removeFromSuperlayer()})
    let  border = CAShapeLayer();
    border.name = "DashedBorder"
    border.strokeColor = color.CGColor;
    border.fillColor = nil;
    border.lineDashPattern = [4, 4];
    border.path = UIBezierPath(rect: self.bounds).CGPath
    border.frame = self.bounds;
    self.addSublayer(border);

}
Christos Chadjikyriacou
quelle
3

Versuchen Sie es mit dem folgenden Code

- (void)drawRect:(CGRect)rect {
    //// Color Declarations
    UIColor* fillColor = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 1];
    UIColor* strokeColor = [UIColor colorWithRed: 0.29 green: 0.565 blue: 0.886 alpha: 1];

    //// Rectangle Drawing
    UIBezierPath* rectanglePath = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius: 6];
    [fillColor setFill];
    [rectanglePath fill];
    [strokeColor setStroke];
    rectanglePath.lineWidth = 1;
    CGFloat rectanglePattern[] = {6, 2, 6, 2};
    [rectanglePath setLineDash: rectanglePattern count: 4 phase: 0];
    [rectanglePath stroke];
    [super drawRect:rect];
}

für einen wie unten Geben Sie hier die Bildbeschreibung ein

Shabeer Ali
quelle
Cornes werden nicht gekrümmt.
Vivek Tyagi
3

Für Swift 5

extension UIView {
    func addDashBorder() {
        let color = UIColor.white.cgColor

        let shapeLayer:CAShapeLayer = CAShapeLayer()

        let frameSize = self.frame.size
        let shapeRect = CGRect(x: 0, y: 0, width: frameSize.width, height: frameSize.height)

        shapeLayer.bounds = shapeRect
        shapeLayer.name = "DashBorder"
        shapeLayer.position = CGPoint(x: frameSize.width/2, y: frameSize.height/2)
        shapeLayer.fillColor = UIColor.clear.cgColor
        shapeLayer.strokeColor = color
        shapeLayer.lineWidth = 1.5
        shapeLayer.lineJoin = .round
        shapeLayer.lineDashPattern = [2,4]
        shapeLayer.path = UIBezierPath(roundedRect: shapeRect, cornerRadius: 10).cgPath

        self.layer.masksToBounds = false

        self.layer.addSublayer(shapeLayer)
    }
}

Wie man hinzufügen

vw.addDashBorder()

So entfernen Sie den Rand wieder

let _ = vw.layer.sublayers?.filter({$0.name == "DashBorder"}).map({$0.removeFromSuperlayer()})
Hardik Thakkar
quelle
2

Am Ende habe ich ein IB Designable mit einigen @ Chris-Implementierungen erstellt:

CurvedDashedBorderUIVIew.h:

#import <UIKit/UIKit.h>

IB_DESIGNABLE
@interface CurvedDashedBorderUIVIew : UIView

@property (nonatomic) IBInspectable CGFloat cornerRadius;
@property (nonatomic) IBInspectable UIColor *borderColor;
@property (nonatomic) IBInspectable int dashPaintedSize;
@property (nonatomic) IBInspectable int dashUnpaintedSize;

@property (strong, nonatomic) CAShapeLayer *border;

@end

CurvedDashedBorderUIVIew.m:

#import "CurvedDashedBorderUIVIew.h"

@implementation CurvedDashedBorderUIVIew

- (instancetype)init
{
    self = [super init];
    if (self) {
        [self setup];
    }
    return self;
}

- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        [self setup];
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setup];
    }
    return self;
}

-(void)setup
{
    _border = [CAShapeLayer layer];
    [self.layer addSublayer:_border];
}

-(void)layoutSubviews {
    [super layoutSubviews];
    self.layer.cornerRadius = self.cornerRadius;

    _border.strokeColor = self.borderColor.CGColor;
    _border.fillColor = nil;
    _border.lineDashPattern = @[[NSNumber numberWithInt:_dashPaintedSize],
                                [NSNumber numberWithInt:_dashUnpaintedSize]];
    _border.path = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:self.cornerRadius].CGPath;
    _border.frame = self.bounds;
}

@end

dann richte es einfach im xib / storyboard ein:

Geben Sie hier die Bildbeschreibung ein

Iain Smith
quelle
2

Schnelle Lösung mit benutzerdefinierter Klasse arbeitete mit Autolayout

angepasst von @Iain Smith

class DashedBorderView: UIView {

    @IBInspectable var cornerRadius: CGFloat = 4
    @IBInspectable var borderColor: UIColor = UIColor.black
    @IBInspectable var dashPaintedSize: Int = 2
    @IBInspectable var dashUnpaintedSize: Int = 2

    let dashedBorder = CAShapeLayer()

    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }

    private func commonInit() {
        //custom initialization
        self.layer.addSublayer(dashedBorder)
        applyDashBorder()
    }

    override func layoutSublayers(of layer: CALayer) {
        super.layoutSublayers(of: layer)
        applyDashBorder()
    }

    func applyDashBorder() {
        dashedBorder.strokeColor = borderColor.cgColor
        dashedBorder.lineDashPattern = [NSNumber(value: dashPaintedSize), NSNumber(value: dashUnpaintedSize)]
        dashedBorder.fillColor = nil
        dashedBorder.cornerRadius = cornerRadius
        dashedBorder.path = UIBezierPath(rect: self.bounds).cgPath
        dashedBorder.frame = self.bounds
    }
}
Marosdee Uma
quelle
2

Sie können einfach eine IBDesignable-Klasse wie folgt erstellen:

import UIKit

@IBDesignable
class BorderedView: UIView {

    @IBInspectable var cornerRadius: CGFloat = 0

    @IBInspectable var borderWidth: CGFloat = 0

    @IBInspectable var borderColor: UIColor = UIColor.clear

    override func draw(_ rect: CGRect) {
        let path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius)
        path.lineWidth = borderWidth

        borderColor.setStroke()

        let dashPattern : [CGFloat] = [10, 4]
        path.setLineDash(dashPattern, count: 2, phase: 0)
        path.stroke()
    }

}

Dann klassifizieren Sie Ihre Ansicht einfach mit BorderedView von Xcode. Auf diese Weise können Sie die Rahmenfarbe und die Rahmenbreite ganz einfach über den Interface Builder einstellen!

Zahidur Rahman Faisal
quelle
2
extension UIView{
func addDashedLineBorder() {
    let color = UIColor.black.cgColor

    let shapeLayer:CAShapeLayer = CAShapeLayer()
    let frameSize = (self.frame.size)
    let shapeRect = CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height)

    shapeLayer.bounds = shapeRect
    shapeLayer.position = CGPoint(x: frameSize.width/2, y: frameSize.height/2)
    shapeLayer.fillColor = UIColor.clear.cgColor
    shapeLayer.strokeColor = color
    shapeLayer.lineWidth = 1
    shapeLayer.lineJoin = kCALineJoinRound
    shapeLayer.lineDashPattern = [2,2]
    shapeLayer.path = UIBezierPath(rect: shapeRect).cgPath

    self.layer.addSublayer(shapeLayer)
}

} und rufen Sie diese Funktion in viewdidLoad () mit Verzögerung auf:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { 
            // Your code with delay
            self.YourView.addDashedBorder()
        }
Ayush Dixit
quelle
Dies wird den 100% igen Teil Ihrer Ansicht abdecken.
Ayush Dixit
1

• Swift 5

• Funktioniert mit Autolayout

• Arbeitet mit dem Eckenradius

import UIKit

    class DashedBorderView: UIView {

    private let dashedLineColor = UIColor.black.cgColor
    private let dashedLinePattern: [NSNumber] = [6, 3]
    private let dashedLineWidth: CGFloat = 4

    private let borderLayer = CAShapeLayer()

    init() {
        super.init(frame: CGRect.zero)

        borderLayer.strokeColor = dashedLineColor
        borderLayer.lineDashPattern = dashedLinePattern
        borderLayer.backgroundColor = UIColor.clear.cgColor
        borderLayer.fillColor = UIColor.clear.cgColor
        borderLayer.lineWidth = dashedLineWidth
        layer.addSublayer(borderLayer)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func draw(_ rect: CGRect) {
        borderLayer.frame = bounds
        borderLayer.path = UIBezierPath(roundedRect: rect, cornerRadius: layer.cornerRadius).cgPath
    }
}
Skornos
quelle
0

In Swift 4 habe ich eine UIView-Erweiterung mit folgender Funktion erstellt:

func borderDash(withRadius cornerRadius: Float, borderWidth: Float, borderColor: UIColor, dashSize: Int) {
    let currentFrame = self.bounds
    let shapeLayer = CAShapeLayer()
    let path = CGMutablePath()
    let radius = CGFloat(cornerRadius)

    // Points - Eight points that define the round border. Each border is defined by two points.
    let topLeftPoint = CGPoint(x: radius, y: 0)
    let topRightPoint = CGPoint(x: currentFrame.size.width - radius, y: 0)
    let middleRightTopPoint = CGPoint(x: currentFrame.size.width, y: radius)
    let middleRightBottomPoint = CGPoint(x: currentFrame.size.width, y: currentFrame.size.height - radius)
    let bottomRightPoint = CGPoint(x: currentFrame.size.width - radius, y: currentFrame.size.height)
    let bottomLeftPoint = CGPoint(x: radius, y: currentFrame.size.height)
    let middleLeftBottomPoint = CGPoint(x: 0, y: currentFrame.size.height - radius)
    let middleLeftTopPoint = CGPoint(x: 0, y: radius)

    // Points - Four points that are the center of the corners borders.
    let cornerTopRightCenter = CGPoint(x: currentFrame.size.width - radius, y: radius)
    let cornerBottomRightCenter = CGPoint(x: currentFrame.size.width - radius, y: currentFrame.size.height - radius)
    let cornerBottomLeftCenter = CGPoint(x: radius, y: currentFrame.size.height - radius)
    let cornerTopLeftCenter = CGPoint(x: radius, y: radius)

    // Angles - The corner radius angles.
    let topRightStartAngle = CGFloat(Double.pi * 3 / 2)
    let topRightEndAngle = CGFloat(0)
    let bottomRightStartAngle = CGFloat(0)
    let bottmRightEndAngle = CGFloat(Double.pi / 2)
    let bottomLeftStartAngle = CGFloat(Double.pi / 2)
    let bottomLeftEndAngle = CGFloat(Double.pi)
    let topLeftStartAngle = CGFloat(Double.pi)
    let topLeftEndAngle = CGFloat(Double.pi * 3 / 2)

    // Drawing a border around a view.
    path.move(to: topLeftPoint)
    path.addLine(to: topRightPoint)
    path.addArc(center: cornerTopRightCenter,
                radius: radius,
                startAngle: topRightStartAngle,
                endAngle: topRightEndAngle,
                clockwise: false)
    path.addLine(to: middleRightBottomPoint)
    path.addArc(center: cornerBottomRightCenter,
                radius: radius,
                startAngle: bottomRightStartAngle,
                endAngle: bottmRightEndAngle,
                clockwise: false)
    path.addLine(to: bottomLeftPoint)
    path.addArc(center: cornerBottomLeftCenter,
                radius: radius,
                startAngle: bottomLeftStartAngle,
                endAngle: bottomLeftEndAngle,
                clockwise: false)
    path.addLine(to: middleLeftTopPoint)
    path.addArc(center: cornerTopLeftCenter,
                radius: radius,
                startAngle: topLeftStartAngle,
                endAngle: topLeftEndAngle,
                clockwise: false)

    // Path is set as the shapeLayer object's path.
    shapeLayer.path = path;
    shapeLayer.backgroundColor = UIColor.clear.cgColor
    shapeLayer.frame = currentFrame
    shapeLayer.masksToBounds = false
    shapeLayer.setValue(0, forKey: "isCircle")
    shapeLayer.fillColor = UIColor.clear.cgColor
    shapeLayer.strokeColor = borderColor.cgColor
    shapeLayer.lineWidth = CGFloat(borderWidth)
    shapeLayer.lineDashPattern = [NSNumber(value: dashSize), NSNumber(value: dashSize)]
    shapeLayer.lineCap = kCALineCapRound

    self.layer.addSublayer(shapeLayer)
    self.layer.cornerRadius = radius;
}
Gastón Antonio Montes
quelle
0

Wenn Sie möchten, dass dies mit CornerRadius funktioniert, versuchen Sie dies

tagView.clipsToBounds = YES;
tagView.layer.cornerRadius = 20.0f;
tagView.backgroundColor = [UIColor groupTableViewBackgroundColor];

CAShapeLayer *yourViewBorder = [CAShapeLayer layer];
yourViewBorder.strokeColor = [UIColor blackColor].CGColor;
yourViewBorder.fillColor = nil;
yourViewBorder.lineDashPattern = @[@2, @2];
yourViewBorder.frame = tagView.bounds;

// Create the path for to make circle
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:tagView.bounds
                                               byRoundingCorners:UIRectCornerAllCorners
                                                     cornerRadii:CGSizeMake(20, 20)];


yourViewBorder.path = maskPath.CGPath;

[tagView.layer addSublayer:yourViewBorder];
Clement Joseph
quelle
0

Swift 5+

import UIKit

class DashedBorderView: UIView {

    private let borderLayer = CAShapeLayer()

    init(color: UIColor, width: CGFloat = 1) {
        super.init(frame: CGRect.zero)

        let pattern: [NSNumber] = [NSNumber(value: Float(5 * width)), NSNumber(value: Float(3 * width))]

        borderLayer.backgroundColor = nil
        borderLayer.fillColor = nil
        borderLayer.lineDashPattern = pattern
        borderLayer.lineWidth = width
        borderLayer.strokeColor = color.cgColor

        layer.addSublayer(borderLayer)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func draw(_ rect: CGRect) {
        borderLayer.frame = bounds
        borderLayer.path = UIBezierPath(roundedRect: rect, cornerRadius: layer.cornerRadius).cgPath
    }
}

Wie benutzt man:

// f.e. inside UIViewController

let viewWithDashedBorder = DashedBorderView(color: .red, width: 2)
view.addSubview(viewWithDashedBorder)
Gondo
quelle