我想根据从数组中获取的数据在UIView
中创建多个水平条。
我想要这样的东西:
但是当我试图让它变得通用时,它会显示如下:
这是我的draw
功能:
override func draw(_ rect: CGRect) {
guard let currentGraphicsContext = UIGraphicsGetCurrentContext() else { return }
var sumOfAllSegments : CGFloat = 0
dataToRepresent.forEach {(element) in
sumOfAllSegments += CGFloat(element["value"] as! CGFloat)
}
var lastSegmentRect = CGRect()
var progressRect = rect
dataToRepresent.forEach { (element) in
let currentSegmentValue = element["value"] as! CGFloat
let color = element ["color"] as! CGColor
let percentage = (currentSegmentValue/sumOfAllSegments) * frame.width
progressRect.size.width = percentage
progressRect.origin.x = lastSegmentRect.origin.x + lastSegmentRect.size.width
if(progressRect.origin.x > 0) {
progressRect.origin.x += 2.0
}
lastSegmentRect = progressRect
makingBars(rect: progressRect , color: color , context: currentGraphicsContext)
}
}
和makingBars
功能:
func makingBars(rect : CGRect , color : CGColor , context : CGContext) {
context.addRect(rect)
context.setFillColor(color)
DispatchQueue.global(qos: .background).async {
DispatchQueue.main.async {
context.fill(rect)
}
}
}
编辑1:
编辑2:
答案 0 :(得分:1)
正如AitorPagán在评论中指出的那样,你没有正确设定你的作品的高度。
除此之外,视图的draw(_:)
方法必须同步运行。你不能使用GCD。摆脱DispatchQueue.global()/ DispatchQueue.main.async()代码。这会阻止您的绘制方法正常运行。 (系统在调用draw方法之前设置绘图上下文。绘图上下文在draw方法之外不再有效,并且你使用GCD的方式,直到draw方法之后才调用你的fill调用返回。)
答案 1 :(得分:0)
自动布局可以更轻松地实现此类型要求。您可以找到此线程有用。 Creating a 3x3 grid with auto layout constraints 但在这种情况下,你必须以编程方式进行约束。基于手动框架的布局会产生问题,因为我们有不同的屏幕尺寸和旋转。
答案 2 :(得分:0)
这个gist是一个自定义的UIView,用于绘制水平块,它是一个绘制电池量表的视图。它只是通过添加子视图来实现。
我怀疑你的代码只是错误地计算了一些帧 - 为了测试这个你可以改变每个条的颜色和/或只是绘制少量的条来检查重叠的帧。
答案 3 :(得分:0)
尝试通过以下方式改变您的代码:
#ifdef RegisterClass
#undef RegisterClass
#endif