【问题标题】:UIBezierpath is not drawing a smooth imageUIBezierpath 没有绘制平滑的图像
【发布时间】:2016-10-09 09:54:18
【问题描述】:

我想快速创建一个自定义按钮,结果不太令人满意。 UIBezierpath 未绘制平滑路径。请看下面的图片和代码。

let roundRect = UIBezierPath(roundedRect: CGRectMake(0, 0, 156, 60), byRoundingCorners:.AllCorners, cornerRadii: CGSizeMake(200, 200))

玩了一会儿,我发现将路径向下和向右移动 1 点并将矩形大小缩小 1 可以解决问题。但我不喜欢这种解决方案,我认为这不是正确的做法。我觉得框架正在剪裁我的形象。有人可以帮我解决这个问题吗?

let roundRect = UIBezierPath(roundedRect: CGRectMake(1, 1, 154, 59), byRoundingCorners:.AllCorners, cornerRadii: CGSizeMake(200, 200))

整个 CustomButton 子类:

import UIKit

class DesignableButtons: UIButton {
    let black = UIColor(red: 33/255, green: 33/255, blue: 33/255, alpha: 1.0) /* #212121 */

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
        self.setTitle("Go to Google", forState: UIControlState.Normal)
        self.titleLabel!.font = UIFont(name: "GT Walsheim", size: 14)
        self.setTitleColor(black, forState: .Normal)
        self.setTitleColor(UIColor.whiteColor(), forState: .Highlighted)
        self.setTitleColor(UIColor.whiteColor(), forState: .Selected)
        self.titleLabel!.alpha = 1.0
    }

    let roundRect = UIBezierPath(roundedRect: CGRectMake(0, 0, 156, 60), byRoundingCorners:.AllCorners, cornerRadii: CGSizeMake(200, 200))

    override func drawRect(rect: CGRect) {
        black.setStroke()
        roundRect.stroke()
        if highlighted {
            black.setFill()
            roundRect.fill()
        }
    }

    override var highlighted: Bool {
        didSet {
            setNeedsDisplay()
        }
    }
}

【问题讨论】:

  • 你能把你所有的绘图代码贴出来吗?另外,这会在物理设备上重现吗?如果您没有放大到 100%,有时会在模拟器上发生这种情况。
  • 是的,同样的事情也发生在我的物理 iphone6 上。
  • override func drawRect 否。不允许为 UIButton 覆盖 drawRect。你需要构建一个背景图片并设置按钮的背景图片,让以自己的方式进行绘制。

标签: ios swift uibezierpath


【解决方案1】:

试试这个

let roundRect = UIBezierPath(roundedRect: CGRectInset(CGRectMake(0, 0, 156, 60), 1, 1), byRoundingCorners:.AllCorners, cornerRadii: CGSizeMake(200, 200))

已编辑

或者你也可以这样做以使其更可重用,这在你的layoutSubviews

let roundRect = UIBezierPath(roundedRect: CGRectInset(self.frame, 1, 1), byRoundingCorners:.AllCorners, cornerRadii: CGSizeMake(200, 200))

代替

let roundRect = UIBezierPath(roundedRect: CGRectMake(0, 0, 156, 60), byRoundingCorners:.AllCorners, cornerRadii: CGSizeMake(200, 200))

CGRectInset 函数在原始矩形内创建一个矩形,

返回一个小于或大于源的矩形 矩形,中心点相同。

已编辑 你可以把它放在你的init 来修复可视化问题

self.contentScaleFactor = UIScreen.mainScreen().scale //SUPPORT RETINA

希望对你有帮助

【讨论】:

  • 感谢您的帮助!我查看了 CGRectInset 的文档,所做的是缩小/扩大矩形的大小。在这种情况下,将其缩小 1 点不会有很大的不同。但是,这意味着它的尺寸并不完全相同,在生产时不会被接受。
  • 修改的是你的贝塞尔路径,而不是原始按钮,你的意思是“生产时不会被接受。”?
  • 我的意思是在公司环境中,要与设计团队合作,用户界面需要精确到像素。有时设计团队可能不会接受将按钮缩小 1 个像素。
  • 我告诉过你,我们不会只修改 UIBezierPath 按钮的大小来制作你的边框,你的按钮有相同的大小;),如果这个答案解决了你的问题,你可以标记为接受吗?跨度>
  • 抱歉 Reinier,我可能很烦人。我了解您的代码不会修改按钮大小,但会修改按钮的外观。这就是我所说的,你正在改变这里的设计。我正在尝试寻找一种在不缩小按钮外观的情况下使其正确显示的方法。如果真的没有办法,我会接受你的回答。再次非常感谢您! :)
【解决方案2】:

你有问题,因为线条被剪裁了。当您绘制到 drawRect: 时,这种情况总是会发生。尝试在 drawRect: 之外绘制。

例如:

required init?(coder aDecoder: NSCoder) {
    // some code
    layer.masksToBounds = true
    layer.cornerRadius = 200
    layer.borderWidth = 1
    layer.borderColor = black.CGColor
}

或者如果你想使用子层:

let borderLine = CAShapeLayer()

required init?(coder aDecoder: NSCoder) {
    // some code
    frame = someFrame

    let roundRect = UIBezierPath(roundedRect: CGRectMake(0, 0, 156, 60), byRoundingCorners:.AllCorners, cornerRadii: CGSizeMake(200, 200))
    borderLine.path = roundRect.CGPath
    borderLine.frame = bounds
    borderLine.strokeColor = black.CGColor
    borderLine.fillColor = UIColor.clearColor().CGColor
    borderLine.lineWidth = 1

    layer.insertSublayer(borderLine, atIndex: 0)
}

【讨论】:

  • 当然。剪辑。
  • 如果你使用这个'self.contentScaleFactor = UIScreen.mainScreen().scale'与drawRect一起工作,我已经更新了我的答案
猜你喜欢
  • 2012-06-09
  • 1970-01-01
  • 2018-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多