我目前正在学习如何实现自定义控件。我不可避免地偶然发现了 CALayer 的可能性,因为在需要执行复杂的动画时使用 UIImage 不够灵活。
我想将 UIView 用作 CALayer 的“容器”,以便它的宽度和高度始终与 UIView 相同(出于灵 active 目的)。
我继承了 CALayer 并重写了 drawInContext() 方法。
这是我在屏幕上得到的结果:
这幅画看起来像素化且模糊。我正在使用 PaintCode 为我生成绘图代码。
这是自定义 CALayer:
class SegmentActive: CALayer {
func frameSetup() -> CGRect {
let frameWidth:CGFloat = superlayer.frame.width
let frameHeight:CGFloat = superlayer.frame.height
let frame = CGRectMake(0, 0, frameWidth, frameHeight)
println("\(superlayer.frame.width) // \(superlayer.frame.height)")
return frame
}
override func drawInContext(ctx: CGContext!) {
UIGraphicsPushContext(ctx)
CalorieCalculatorUI.drawSegControlActiveBase(frameSetup())
UIGraphicsPopContext()
}
下面是我如何使用它:
class ViewController: UIViewController {
@IBOutlet weak var leftSegmentUIView: UIView!
override func viewDidLoad() {
let activeSegment:SegmentActive = SegmentActive()
leftSegmentUIView.layer.addSublayer(activeSegment)
activeSegment.frame = activeSegment.frameSetup()
activeSegment.setNeedsDisplay()
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
我在这里做错了什么? :(
最佳答案
tl;dr:您必须将层的 contentsScale
设置为大于默认 1.0 的值。
层的比例因子默认为 1。这会改变该层的内容缓冲区的大小:
Applies to [...] and content provided via
-drawInContext:
(i.e. ifcontentsScale
is two-drawInContext:
will draw into a buffer twice as large as the layer bounds)
由于您在像素比设备屏幕少的上下文中进行自定义绘图,因此绘图看起来像素化。对于传统的“视网膜”屏幕,您期望的比例因子是 2.0
,但最近推出的 iPhone 6+ 也有 3.0
的比例因子。好消息是您可以从 UIScreen
获取设备比例。
关于ios - Swift 中的自定义 UI 元素 : Subclassing CALayer and overriding drawInContext results in pixelated drawing,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25958600/