我目前正在学习如何实现自定义控件。我不可避免地偶然发现了CALayer的可能性,因为当需要执行复杂的动画时,使用UIImage不够灵活。
我想将UIView用作CALayer的“容器”,以便其宽度和高度始终与UIView相同(出于灵活性目的)。
我将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;博士:您必须将图层的contentsScale
设置为大于默认值1.0的值。
图层的比例因子默认为1。这将更改该图层的内容缓冲区的大小:
适用于-drawInContext:
和通过contentsScale
提供的内容(即,如果-drawInContext:
为两个,则2.0
将绘制到缓冲区中,其大小是图层边界的两倍)
由于您要在比设备屏幕少的像素的上下文中进行自定义绘制,因此该图形看起来像是像素化的。对于传统的“视网膜”屏幕,您期望的比例因子为3.0
,但是随着iPhone 6+的最新推出,还有UIScreen
的比例因子。好消息是您可以从ojit_code获得设备规模。
关于ios - Swift中的自定义UI元素:子类化CALayer并覆盖drawInContext会导致像素化绘图,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25958600/