我在自定义视图中遇到这个奇怪的错误。自定义视图应显示评级分布的米。它被添加到大纲视图的单元格视图中。
当我调整窗口大小时,自定义视图会以某种方式被压扁并且看起来很破碎。我已粘贴下面自定义视图的drawRect
。
override func drawRect(r: NSRect) {
super.drawRect(r)
var goodRect: NSRect?
var okRect: NSRect?
var badRect: NSRect?
let barHeight = CGFloat(10.0)
if self.goodPercent != 0.0 {
goodRect = NSRect(x: 0, y: 0, width: r.width * CGFloat(goodPercent), height: barHeight)
let goodPath = NSBezierPath(roundedRect: goodRect!, xRadius: 6, yRadius: 6)
RatingDistributionView.goodColor.setFill()
goodPath.fill()
}
if self.okPercent != 0.0 {
let okX = CGFloat(goodRect?.width ?? 0.0)
okRect = NSRect(x: okX, y: 0, width: r.width * CGFloat(okPercent), height: barHeight)
let okPath = NSBezierPath(roundedRect: okRect!, xRadius: 6, yRadius: 6)
RatingDistributionView.okColor.setFill()
okPath.fill()
}
if self.badPercent != 0.0 {
var badX: CGFloat
//Cases:
//Good persent and OK present - badX = okRect.x + okRect.width
//Good persent and OK missing - badX = goodRect.x + goodRect.width
//Good missing and OK present - badX = okRect.x + okRect.width
//Both missing -
if okRect != nil {
badX = okRect!.origin.x + okRect!.width
}else if goodRect != nil {
badX = goodRect!.origin.x + goodRect!.width
} else {
badX = 0.0
}
badRect = NSRect(x: badX, y: 0, width: r.width * CGFloat(badPercent), height: barHeight)
let badPath = NSBezierPath(roundedRect: badRect!, xRadius: 6, yRadius: 6)
RatingDistributionView.badColor.setFill()
badPath.fill()
}
//Draw dividers
let divWidth = CGFloat(6.75)
if self.goodPercent != 0.0 && (self.okPercent != 0.0 || self.badPercent != 0.0) {
let divX = goodRect!.origin.x + goodRect!.width
let divRect = NSRect(x: divX - (divWidth / 2.0), y: 0.0, width: divWidth, height: barHeight)
let divPath = NSBezierPath(roundedRect: divRect, xRadius: 0, yRadius: 0)
NSColor.whiteColor().setFill()
divPath.fill()
}
if self.okPercent != 0.0 && self.badPercent != 0.0 {
let divX = okRect!.origin.x + okRect!.width
let divRect = NSRect(x: divX - (divWidth / 2.0), y: 0.0, width: divWidth, height: barHeight)
let divPath = NSBezierPath(roundedRect: divRect, xRadius: 0, yRadius: 0)
NSColor.whiteColor().setFill()
divPath.fill()
}
}
答案 0 :(得分:2)
您的问题的替代解决方案是使用NSView。您可以使用带圆角的容器视图,然后在该容器中绘制子视图(红色,橙色,绿色)。像这样;
我为它编写了一个课程,您可以根据自己的要求进行自定义;
public class CProgressView:NSView {
private lazy var goodView:NSView = {
let viw:NSView = NSView(frame: NSRect.zero);
viw.layer = CALayer();
viw.layer?.backgroundColor = NSColor.greenColor().CGColor;
self.addSubview(viw)
return viw;
} ();
private lazy var okView:NSView = {
let viw:NSView = NSView(frame: NSRect.zero);
viw.layer = CALayer();
viw.layer?.backgroundColor = NSColor.orangeColor().CGColor;
self.addSubview(viw)
return viw;
} ();
private lazy var badView:NSView = {
let viw:NSView = NSView(frame: NSRect.zero);
viw.layer = CALayer();
viw.layer?.backgroundColor = NSColor.redColor().CGColor;
self.addSubview(viw)
return viw;
} ();
private var _goodProgress:CGFloat = 33;
private var _okProgress:CGFloat = 33;
private var _badProgress:CGFloat = 34;
private var goodViewFrame:NSRect {
get {
let rect:NSRect = NSRect(x: 0, y: 0, width: (self.frame.size.width * (_goodProgress / 100.0)), height: self.frame.size.height);
return rect;
}
}
private var okViewFrame:NSRect {
get {
let rect:NSRect = NSRect(x: self.goodViewFrame.size.width, y: 0, width: (self.frame.size.width * (_okProgress / 100.0)), height: self.frame.size.height);
return rect;
}
}
private var badViewFrame:NSRect {
get {
let width:CGFloat = (self.frame.size.width * (_badProgress / 100.0));
let rect:NSRect = NSRect(x: self.frame.size.width - width, y: 0, width: width, height: self.frame.size.height);
return rect;
}
}
override public init(frame frameRect: NSRect) {
super.init(frame: frameRect);
//--
self.commonInit();
}
required public init?(coder: NSCoder) {
super.init(coder: coder);
}
override public func awakeFromNib() {
super.awakeFromNib();
//--
self.commonInit();
}
private func commonInit() {
self.layer = CALayer();
self.layer!.cornerRadius = 15;
self.layer!.masksToBounds = true
//-
self.updateFrames();
}
public func updateProgress(goodProgressV:Int, okProgressV:Int, badProgressV:Int) {
guard ((goodProgressV + okProgressV + badProgressV) == 100) else {
NSLog("Total should be 100%");
return;
}
_goodProgress = CGFloat(goodProgressV);
_okProgress = CGFloat(okProgressV);
_badProgress = CGFloat(badProgressV);
//--
self.updateFrames();
}
private func updateFrames() {
self.layer?.backgroundColor = NSColor.grayColor().CGColor;
self.goodView.frame = self.goodViewFrame;
self.okView.frame = self.okViewFrame;
self.badView.frame = self.badViewFrame;
}
public override func resizeSubviewsWithOldSize(oldSize: NSSize) {
super.resizeSubviewsWithOldSize(oldSize);
//--
self.updateFrames();
}
}
注意:调用updateProgress()方法更改进度默认值为33,33& 34(33 + 33 + 34 = 100);
您也可以从以下链接下载示例项目;
答案 1 :(得分:1)
来自Spring Security
的文档:
dirtyRect: 定义视图部分的矩形,需要重绘。此矩形通常表示需要更新的视图部分。启用响应式滚动时,此矩形还可以表示AppKit要缓存的视图的不可见部分。
请勿使用drawRect(_ dirtyRect: NSRect)
进行计算,请使用dirtyRect
。