Perbatasan garis putus-putus di sekitar UIView

Jawaban:

131

Anda dapat mengatur perbatasan dengan pola ini menggunakan jalur Layer dan Bezier seperti contoh di bawah ini.

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

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

Anda juga dapat mengatur berbagai jenis desain menggunakan gambar pola seperti contoh di bawah ini.

[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

Di sini Anda harus menambahkan <QuartzCore/QuartzCore>kerangka kerja dalam proyek dan mengimpornya dengan YourViewController.mfile baris di bawah ini .

#import <QuartzCore/QuartzCore.h>
Paras Joshi
sumber
2
itu bukan cara yang sempurna ketika berbicara tentang iPhone6 ​​plus. Garis putus-putus bisa menjadi kabur.
Jacky
1
@ Jacky: gunakan gambar beresolusi lebih tinggi. :)
Olie
6
apa contoh gambar?
Tom Roggero
1
dapatkah Anda memberikan contoh gambar?
Jonguo
1
Jonguo Misalnya, jika Anda menambahkan gambar dengan resolusi yang tepat seperti misalkan ukuran gambar normal Anda adalah 120x120 dan namanya adalah test.png kemudian buat dua gambar lainnya dengan nama [email protected] dan [email protected] dengan ukuran 240x240 dan 360x360 yang digunakan di semua perangkat apple secara otomatis dengan nama yang terkait. (yaitu test.png digunakan di iPhone 4, test @ 2x akan berguna untuk iPhone 4s, 5, 5s, 6, 6s dan twst @ 3x akan berguna untuk iPhone 6 plus, 6s plus.
Paras Joshi
273

Metode lain jika Anda suka sublayers. Di init tampilan khusus Anda, masukkan ini (_border adalah 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];

Dan dalam tampilan layout Anda, taruh ini:

_border.path = [UIBezierPath bezierPathWithRect:self.bounds].CGPath;
_border.frame = self.bounds;
Chris
sumber
41
Bagus! Anda juga dapat menggunakan sesuatu seperti ini untuk efek membulat:_border.path = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:5.f].CGPath;
Everton Cunha
Maaf! Saya tidak mengerti. Ada contoh? @EvertonCunha
Yi Jiang
3
@ VanDuTran Dalam cuplikan pertama,_border.lineWidth = 3
Chris
1
hei saya menerapkan kode ini ke label pada sel tampilan tabel tetapi memberikan ukuran perbatasan kecil bagaimana saya bisa memperbaikinya.
Chaudhary Ankit Deshwal
3
Swift 3: border = CAShapeLayer() border.strokeColor = yourColor border.fillColor = nil border.lineDashPattern = [4, 2] self.layer.addSublayer(border)
Geek20
71

Bagi Anda yang bekerja di Swift, ekstensi kelas ini di UIView membuatnya mudah. Ini didasarkan pada jawaban 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)
    }
}

Untuk menggunakannya:

anyView.addDashedBorder()
rmooney
sumber
2
Sepotong kode hebat! Hanya satu masalah, ketika saya menerapkannya pada UIImageView itu tidak mengenali lebar penuh, ia berjalan sekitar 80% dari itu.
arielcr
1
saya pikir Anda mungkin memanggil addDashBorder terlalu dini, coba panggil di dalam didLayoutSubviews
Godfather
3
Saya membuat UIView khusus dan memasukkan ekstensi ini ke dalamnya. Kemudian saya menelepon addDashedBorder()selama didMoveToSuperview()berpikir autolayout akan selesai pada saat itu dan ukuran frame akan benar tetapi tidak. Lebar batas putus-putus melampaui lebar tampilan. Garis putus-putus terlihat sangat bagus! Itu self.frame.sizetidak benar.
levibostian
self.layer.masksToBounds = true Gunakan ini jika keluar dari batas
Ankish Jain
@rmooney bekerja dengan sangat baik tetapi masalahnya adalah ketika Anda menambahkan sublapisan dalam sel dinamis UITableView lapisan yang dianggap sebagai lapisan storyboard dan tidak bekerja di customcell itu ukurannya berbeda jika lebar storyboard Anda 375px itu akan selalu dianggap perbatasan dengan sama ukuran dan itu tidak akan berfungsi di perangkat yang lebih besar seperti 414px dan sebagainya.
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()
    }
}

Gunakan di storyboard (sebagai kelas khusus) atau langsung dalam kode:

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

Hasil:

masukkan deskripsi gambar di sini

selempang
sumber
Mengejutkan bahwa tidak ada lagi upvotes dalam hal ini. Solusi ini bekerja paling baik dengan tata-letak otomatis dibandingkan dengan jawaban lain.
Yuchen Zhong
17

Berdasarkan apa yang disarankan Prasad G, saya membuat metode di dalam kelas UIImage Extras dengan berikut:

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

Penting untuk menunjukkan bahwa jika Anda menentukan posisi bentuk Anda sebagai (0,0), sudut bawah perbatasan akan ditempatkan di tengah gambar, itu sebabnya saya mengaturnya ke: (frameSize.width / 2, frameSize .tinggi / 2)

Saya kemudian menggunakan metode saya untuk mendapatkan garis putus-putus menggunakan UIImage dari UIImageView saya dan menambahkan CAShapeLayer sebagai sublayer dari lapisan UIImageView:

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

Gunakan metode CGContextSetLineDash ().

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

Saya pikir ini akan sangat membantu Anda.

Prasad G
sumber
1
Apa konteksnya di sini?
Avinash Sharma
11

Berikut ini adalah subkelas UIView yang dapat bekerja untuk proyek apa pun, dan juga berfungsi untuk tampilan bulat :

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

Dengan cara ini Anda dapat mengedit dari Storyboard seperti ini:

masukkan deskripsi gambar di sini

Sepasang hasil:

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

xavi.pedrals
sumber
10

Untuk ini, Anda perlu menambahkan CAShapeLayer untuk objek tertentu

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

Cepat 4.2

Didasarkan pada jawaban rmooney sebagai UIViewekstensi dengan parameter yang dapat dikonfigurasi yang memiliki nilai default yang ditetapkan.

Catatan ini tidak berfungsi jika tampilan telah 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
sumber
shapeLayer.lineJoin = CAShapeLayerLineJoin.roundseharusnyayourViewBorder.lineJoin = kCALineJoinRound
pw2
6

Versi cepat jawaban QuartzCore.

import QuartzCore    

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

The CAShapeLayerpendekatan bekerja, tapi pendekatan QuartzCore adalah lebih baik dalam menangani sebuah Table View ulang, jika UIViewberada di dalam sel.

Untuk gambar, Anda dapat menggunakan sesuatu seperti ini (sangat kecil):

masukkan deskripsi gambar di sini

Saya cenderung lebih suka vektor daripada PNG ketika saya bisa lolos begitu saja:

  • Di dalam Sketsa, buat persegi panjang 4x4 piksel.
  • Buat total empat di antaranya
  • Kelompokkan mereka menjadi foursquare, warna bergantian
  • Ekspor grup sebagai PDF
  • Di dalam Images.xcassets, buat New Image Setdisebut dottedPattern
  • Ubah Scale FactorskeSingle Vector
  • Masukkan PDF Anda
Robert Chen
sumber
6

Untuk Xamarin.iOS garis putus-putus / putus-putus.

        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
sumber
Harap uraikan jawaban Anda sedikit alih-alih hanya menempatkan cuplikan kode.
kabirbaidhya
1
Catatan untuk pembaca masa depan: Anda harus menggunakan namespace CoreAnimation untuk menggunakan konstruktor CAShapeLayer.
jnel899
6

Dalam 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
sumber
4

Ini jika Anda menginginkannya di Swift 2

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
sumber
3

coba kode di bawah ini

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

untuk yang seperti di bawah masukkan deskripsi gambar di sini

Ali Shabeer
sumber
Jagung tidak semakin melengkung.
Vivek Tyagi
3

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

Bagaimana cara menambahkan

vw.addDashBorder()

Cara menghapus perbatasan lagi

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

Saya akhirnya membuat IB Designable menggunakan beberapa implementasi @Chris:

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

maka cukup atur di xib / storyboard:

masukkan deskripsi gambar di sini

Iain Smith
sumber
2

Solusi cepat dengan kelas kustom berfungsi dengan autolayout

dikustomisasi dari @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
sumber
2

Anda cukup membuat kelas IBDesignable seperti ini:

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

}

Kemudian, cukup subkelas tampilan Anda dengan BorderedView dari Xcode. Dengan cara ini Anda dapat mengatur warna tepi dan lebar tepi dengan sangat mudah dari pembuat antarmuka!

Zahidur Rahman Faisal
sumber
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)
}

} dan panggil fungsi ini di viewdidLoad () dengan penundaan:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { 
            // Your code with delay
            self.YourView.addDashedBorder()
        }
Ayush Dixit
sumber
Ini akan mencakup bagian 100% dari tampilan Anda.
Ayush Dixit
1

• Cepat 5

• Bekerja dengan pembayaran otomatis

• Bekerja dengan jari-jari sudut

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
sumber
0

Di swift 4 saya membuat ekstensi UIView dengan fungsi berikut:

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
sumber
0

Jika Anda ingin ini berfungsi dengan cornerRadius maka coba ini

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

Cara Penggunaan:

// f.e. inside UIViewController

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