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

网友投稿 1186 2022-09-10

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

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

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

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

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

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() //描边

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

3,解决描边问题

其实代码都是对的,只是描边的时候它会以路径为中心向两边描边,如图: 黑线是 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,那个是没有的,不要在意)

4, 背景问题

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

我们设置了自己的 ​​填充色​​​ 和 ​​描边色​​​, 那么为什么四角还是白色的呢? 其实我们还需要设置一个地方,就是设置初始背景色是透明,然后再在上面绘制东西 也就是 ​​​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 // 设置背景透明}

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

总结:完整代码

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

效果如图

import UIKit@IBDesignable // 让该UIView 可以显示在 StoryBoard 中class 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 描边

其它用处

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:自己写的一个连数据库的音乐调用模块 MusicRj
下一篇:Windows nginx 操作和配置
相关文章

 发表评论

暂时没有评论,来抢沙发吧~