【问题标题】:Dashed line border around UIViewUIView 周围的虚线边框
【发布时间】:2012-11-20 17:20:15
【问题描述】:

如何在UIView 周围添加虚线边框。

类似的东西

【问题讨论】:

标签: ios objective-c iphone uiview


【解决方案1】:

改进@Chris 的回答。

extension UIView {
    func dashLinedBorder() -> CAShapeLayer {
        let viewBorder = CAShapeLayer()
        viewBorder.strokeColor = UIColor.black.cgColor
        viewBorder.lineDashPattern = [4, 2]
        viewBorder.fillColor = nil
        self.layer.addSublayer(viewBorder)
        return viewBorder
    }
}

ViewController 中定义您的CAShapeLayer

var viewBillingProofCAShapeLayer: CAShapeLayer!

override func viewDidLoad() {
    self.viewBillingProofCAShapeLayer = self.viewBillingProofInner.dashLinedBorder()
}

然后覆盖viewDidLayoutSubviews

override func viewDidLayoutSubviews() {
    self.viewBillingProofCAShapeLayer.path = UIBezierPath(roundedRect: self.viewBillingProofInner.bounds, byRoundingCorners: .allCorners, cornerRadii: CGSize(width: 4, height: 4)).cgPath
    self.viewBillingProofCAShapeLayer.frame = self.viewBillingProofInner.bounds
}

【讨论】:

    【解决方案2】:

    Swift 4,5 :- addDashedBorder

    extension UIView {
        func addDashedBorder(color: UIColor) {
            let color = color.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 = 1.5
            shapeLayer.lineJoin = CAShapeLayerLineJoin.round
            shapeLayer.lineDashPattern = [4, 4]
            shapeLayer.path = UIBezierPath(roundedRect: shapeRect, cornerRadius: 0).cgPath
            self.layer.addSublayer(shapeLayer)
        }
    }
    

    【讨论】:

      【解决方案3】:

      Swift 4.2

      基于 rmooney 的回答,作为 UIView 扩展,带有设置了默认值的可配置参数。

      请注意,如果视图有 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)
        }
      }
      

      【讨论】:

      • shapeLayer.lineJoin = CAShapeLayerLineJoin.round 应该是yourViewBorder.lineJoin = kCALineJoinRound
      • 它是否适用于自动布局?因为它不适合我
      • @Jalil 是的,它应该,但在添加虚线之前,您需要已经拥有应用它的视图的宽度和高度。因为它基于视图边界。
      【解决方案4】:

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

      使用方法:

      // f.e. inside UIViewController
      
      let viewWithDashedBorder = DashedBorderView(color: .red, width: 2)
      view.addSubview(viewWithDashedBorder)
      

      【讨论】:

        【解决方案5】:

        • 斯威夫特 5

        • 适用于自动布局

        • 适用于圆角半径

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

        【讨论】:

          【解决方案6】:

          这是一个 UIView 子类,它可以用于任何项目,它也适用于 round 视图:

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

          这样您就可以像这样从情节提要中进行编辑:

          一对结果:

          【讨论】:

          • 这是最好的解决方案。适用于自动布局、自动调整大小的视图,并且与其他答案不同,当视图高度增加时,这不会增加虚线高度(这是一件好事)。
          • 非常有帮助,自动布局也可以正常工作,我添加了一个使用动画的选项。gist.github.com/fhefh2015/96f02d82eb9546c4b51eb79c51d33846
          • 优于其他解决方案。其他答案中的解决方案仅适用于视图的heightwidth 具有固定值的情况。但是有一个问题是view上设置的值不能在storyboard中预览,有什么解决办法吗?
          【解决方案7】:

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

          如何添加

          vw.addDashBorder()
          

          如何再次去除边框

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

          【讨论】:

          • 我已将此添加到集合视图单元格内的 UIImageView 中,它仅覆盖图像视图的 70%。
          【解决方案8】:

          对于那些在 Swift 中工作的人来说,UIView 上的这个类扩展让你很容易。这是基于 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)
              }
          }
          

          使用它:

          anyView.addDashedBorder()
          

          【讨论】:

          • 一段很棒的代码!只是一个问题,当我将它应用到 UIImageView 时,它无法识别它的整个宽度,它大约占了 80%。
          • 我认为您可能调用 addDashBorder 为时过早,请尝试在 didLayoutSubviews 中调用它
          • 我创建了一个自定义 UIView 并将这个扩展放在里面。然后我在didMoveToSuperview() 期间打电话给addDashedBorder() 认为到那时自动布局将完成并且帧大小将是正确的,但事实并非如此。虚线边框的宽度超出了视图的宽度。顺便说一下,虚线看起来很好! self.frame.size 不正确。
          • self.layer.masksToBounds=true 如果超出范围使用这个
          • 如果有人在 UITableViewCells 上得到了不正确的 CGSize 我通过在 contentView 上调用 layoutIfNeeded() 来修复它 ``` override func layoutSubviews() { super.layoutSubviews() contentView.layoutIfNeeded( ) } ```
          【解决方案9】:

          如果你想让它与cornerRadius一起工作,那么试试这个

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

          【讨论】:

            【解决方案10】:

            您可以使用图层和贝塞尔路径设置此模式的边框,如下例所示。

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

            斯威夫特 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)
            

            您还可以使用以下示例中的图案图像设置不同类型的设计。

            [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
            

            这里你需要在项目中添加<QuartzCore/QuartzCore> 框架并在YourViewController.m 文件中使用下面的行导入它。

            #import <QuartzCore/QuartzCore.h>
            

            【讨论】:

            • 在谈论 iPhone6 plus 时,这不是一个完美的方式。虚线可能会变得模糊。
            • @Jacky:使用更高分辨率的图像。 :)
            • 图片的例子是什么?
            • 你能举个例子吗?
            • Jonguo 例如,如果您添加任何具有适当分辨率的图像,例如假设您的正常图像大小为 120x120 并且名称为 test.png,则创建另外两个名称为 test@2x.png 和 test@ 的图像3x.png 大小为 240x240 和 360x360,在所有苹果设备中自动使用它的相关名称。 (即 test.png 用于 iPhone 4,test@2x 将适用于 iPhone 4s、5、5s、6、6s,twst@3x 将适用于 iPhone 6 plus、6s plus。
            【解决方案11】:
            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)
            }
            

            } 并在 viewdidLoad() 中延迟调用此函数:

            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { 
                        // Your code with delay
                        self.YourView.addDashedBorder()
                    }
            

            【讨论】:

            • 这将覆盖您视图的 100%。
            【解决方案12】:

            您可以像这样简单地创建一个 IBDesignable 类:

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

            然后只需使用 Xcode 中的 BorderedView 子类化您的视图。 这样您就可以在界面生成器中轻松设置边框颜色和边框宽度!

            【讨论】:

              【解决方案13】:

              带有自定义类的 Swift 解决方案与自动布局一起使用

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

              【讨论】:

                【解决方案14】:

                在 swift 4 中,我创建了一个具有以下功能的 UIView 扩展:

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

                【讨论】:

                  【解决方案15】:

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

                  【讨论】:

                    【解决方案16】:

                    对于 Xamarin.iOS 虚线/点线边框。

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

                    【讨论】:

                    • 请稍微详细说明您的答案,而不是只输入代码 sn-p。
                    • 未来读者请注意:您必须使用命名空间 CoreAnimation 才能使用 CAShapeLayer 构造函数。
                    【解决方案17】:

                    我最终使用@Chris 的一些实现创建了一个 IB Designable:

                    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
                    

                    然后在 xib/storyboard 中设置它:

                    【讨论】:

                      【解决方案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()
                          }
                      }
                      

                      在情节提要中使用(作为自定义类)或直接在代码中使用:

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

                      结果:

                      【讨论】:

                      • 惊讶于没有更多的赞成票。与其他答案相比,此解决方案最适合自动布局。
                      【解决方案19】:

                      试试下面的代码

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

                      对于像下面这样的人

                      【讨论】:

                      • 眼角没有弯曲。
                      【解决方案20】:

                      为此,您需要为该特定对象添加 CAShapeLayer

                       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;
                      

                      【讨论】:

                        【解决方案21】:

                        如果你想在 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);
                        
                        }
                        

                        【讨论】:

                          【解决方案22】:

                          QuartzCore 答案的 Swift 版本。

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

                          CAShapeLayer 方法有效,但如果 UIView 在单元格内,QuartzCore 方法更擅长处理表视图重新加载。

                          对于图像,你可以使用这样的东西(它真的很小):

                          当我可以摆脱它时,我倾向于更喜欢矢量而不是 PNG:

                          • 在 Sketch 中,创建一个 4x4 像素的矩形。
                          • 一共做四个
                          • 将它们组合成一个四方形,颜色交替
                          • 将组导出为 PDF
                          • Images.xcassets 中,创建一个名为dottedPattern 的New Image Set
                          • Scale Factors 更改为Single Vector
                          • 放入您的 PDF

                          【讨论】:

                            【解决方案23】:

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

                            我认为这对你会有帮助。

                            【讨论】:

                            • 这里的上下文是什么?
                            【解决方案24】:

                            如果你喜欢子层,另一种方法。在自定义视图的 init 中,输入以下内容(_border 是 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];
                            

                            在你的布局子视图中,放这个:

                            _border.path = [UIBezierPath bezierPathWithRect:self.bounds].CGPath;
                            _border.frame = self.bounds;
                            

                            【讨论】:

                            • 不错!你也可以使用这样的东西来获得圆润的效果:_border.path = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:5.f].CGPath;
                            • 对不起!我不明白。有什么例子吗? @EvertonCunha
                            • @VanDuTran 在第一个 sn-p 中,_border.lineWidth = 3
                            • 嘿,我将此代码应用于表格视图单元格上的标签,但它的边框尺寸很小,我该如何纠正这个问题。
                            • Swift 3: border = CAShapeLayer() border.strokeColor = yourColor border.fillColor = nil border.lineDashPattern = [4, 2] self.layer.addSublayer(border)
                            【解决方案25】:

                            根据 Prasad G 的建议,我在 UIImage Extras 类中创建了一个方法,其中包含以下内容:

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

                            需要指出的是,如果将形状的位置定义为 (0,0),边框的底角将位于图像的中心,这就是我将其设置为:(frameSize.width/ 2、frameSize.height/2)

                            然后我使用我的方法使用我的 UIImageView 的 UIImage 获取虚线边框,并将 CAShapeLayer 添加为 UIImageView 层的子层:

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

                            【讨论】:

                              猜你喜欢
                              • 2017-07-20
                              • 1970-01-01
                              • 1970-01-01
                              • 2021-04-07
                              • 2014-01-30
                              • 2020-10-15
                              • 1970-01-01
                              • 1970-01-01
                              • 2018-07-18
                              相关资源
                              最近更新 更多