Swift 3.0 iOS 如何绘制 1px 宽的描边

来源:互联网 发布:黑莓q10安装软件 编辑:程序博客网 时间:2024/06/05 10:23

自定义 UIView 绘制 1px 边框描边

我也是初学者,在研究如何制作 1px 的圆角矩形边框时整了半天,也查了半天,终于整出来了,分享下给新手们。
推荐教程 斯坦福大学 和 iOS 10 swift 教程 ,可以直接在 iTunes U 中下载,国内下载的话,需要代理才会快, 不然特别慢 每个视频在 1.2G左右 90分钟(https://itunes.apple.com/cn/course/developing-ios-10-apps-with-swift/id1198467120)
这个讲的特别系统

1, 原理 pt 与 px

苹果手机的原始尺寸是 375 x 667, 也是最初手机的屏幕尺寸,后来的手机都是以这个为原始值缩放的。
比如 iphone 6/7 屏幕是 750 x 1334 正好是这个长宽的 2 倍 iPhone 6/7 和 iPhone 6/7 Plus 都是它的 3
在 UI 中,我们是以 pt (point 即 ) 为单位的,要获取当前手机 1pt 是多少 px 用下面的方法获得

  • 1pt = 1px ( iPhone 5s 之前 )
  • 1pt = 2px ( iPhone 6/7 )
  • 1pt = 3px ( iPhone 6/7 Plus )
let screenScale = UIScreen.main.scale// 如上所说 iPhone 6/7 上该值是 2.0

知道了这个之后,我们就可以计算出1px 在屏幕上所占的距离是多少,也就是

let 1pxWidth = 1 / UIScreen.main.scale

1pt = 2px

2,自定义 UIView 圆角矩形+描边

下面是基础知识了,不知道的可以再百度搜搜别的教程,这里只是讲1px的事,我只注释一些地方
这里假设你已经知道如何自己绘制东西了

// 因为我们要做一个能在 `StoryBoard` 中使用的 `UIView`var radius: CGFloat = 10    // 圆角var lineWidth: CGFloat = 1   // 描边宽度var lineColor: UIColor = UIColor.orange    // 描边颜色var fillColor: UIColor = UIColor.white      // 填充颜色let contentRect = self.bounds       //绘制圆角矩形的「面板」大小let path = UIBezierPath(roundedRect: contentRect, cornerRadius: radius)     //创建圆角矩形路径path.lineWidth = lineWidth      //设置描边颜色lineColor.setStroke()   //设置描边颜色fillColor.setFill()     //设置填充颜色path.fill()             //填充path.stroke()           //描边

这样得出的结果是这样的,有没有发现有点问题,继续看下面

1

3,解决描边问题

2

其实代码都是对的,只是描边的时候它会以路径为中心向两边描边,如图: 黑线是 Bounds, 它只会显示Bounds 内的东西。所以描边被裁掉了外面的问题

那么如何解决呢?
答案: 在绘制的时候定义 圆角矩形的绘制边界小于现在的 Bounds

let contentRect = self.boundslet path = UIBezierPath(roundedRect: contentRect, cornerRadius: radius) // 也就是定义 该方法中的参数  roundedRect 小一些// 幸运的是 CGRect 里有一个方法可以实现向内部偏移 insetBy(dx: CGFloat, dy: CGFloat)// 左右收缩 dx 大小, 上下收缩 dy 大小let contentRect = self.bounds.insetBy(dx: lineWidth/2, dy: lineWidth/2)// 如上,向内收缩描边的一半大小,这样可以在占满两个 Bounds 的同时描边正常。

现在是这样的: (黑边只是为了标明 Bounds,那个是没有的,不要在意)

3

4, 背景问题

是不是感觉到这了就没什么问题了? 其实还是有问题的,在使用中就会发现
问题是这样的:
如果你在一个非纯白背景中使用这个自定义的 UIView,你就会发现会出现下面这样的情况

4

我们设置了自己的 填充色描边色, 那么为什么四角还是白色的呢?
其实我们还需要设置一个地方,就是设置初始背景色是透明,然后再在上面绘制东西
也就是 UIColor.clear //透明色

这个需要写在 init() 方法中
说几点先: 因为我们是自定义的 UIView 我们需要重写 init(frame: CGRect)init(coder: NSCoder) 两个方法,我们的背景设置就写在这两个方法中。

override init(frame: CGRect) {    super.init(frame: frame)    self.backgroundColor = UIColor.clear    // 设置背景透明}required init?(coder: NSCoder) {      // 注意,这个init 方法是 required 而且是 Optional 值    super.init(coder: coder)    self.backgroundColor = UIColor.clear    // 设置背景透明}

然后我们得到我们需要的结果了

5

总结:完整代码

说了这么多希望你能有自己思路了,现在可以在 StoryBoard 中嵌套这个 UIView 得到你想要的结果了。
这里还说一下,现在这个代码是可以在 StoryBoard 中设置参数的, 如果不了解,百度 @IBDesinable

效果如图

StoryBoard Design

import UIKit@IBDesignable // 让该UIView 可以显示在 StoryBoardclass RoundedRectView: UIView {    // MARK: - 设置参数    @IBInspectable // 该关键字让该参数可以显示在 StoryBoard 的右边设置面板中    var radius: CGFloat = 10 { didSet{ setNeedsDisplay() } }    @IBInspectable    var lineWidth: CGFloat = 1 / UIScreen.main.scale { //初始值也设为 1px        didSet{            lineWidth = lineWidth / UIScreen.main.scale            setNeedsDisplay() // 我们如果想调用 Draw() 方法的时候使用这个方法,!!!不能直接调用draw()方法!!!        }    }    @IBInspectable    var lineColor: UIColor = UIColor.lightGray { didSet{ setNeedsDisplay() } }    @IBInspectable    var fillColor: UIColor = UIColor.white { didSet{ setNeedsDisplay() } }    //MARK: - Draw()    override func draw(_ rect: CGRect) {        let contentRect = self.bounds.insetBy(dx: lineWidth/2, dy: lineWidth/2)        let path = UIBezierPath(roundedRect: contentRect, cornerRadius: radius)        path.lineWidth = lineWidth        lineColor.setStroke()        fillColor.setFill()        path.fill()        path.stroke()    }    override init(frame: CGRect) {        super.init(frame: frame)        self.backgroundColor = UIColor.clear    }    required init?(coder: NSCoder) {        super.init(coder: coder)        self.backgroundColor = UIColor.clear    }}

使用效果图: 1px 描边

Dis

其它用处

效果图

原创粉丝点击