首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >调整窗口大小时,自定义视图中断(Cocoa)

调整窗口大小时,自定义视图中断(Cocoa)
EN

Stack Overflow用户
提问于 2016-10-04 19:39:57
回答 2查看 88关注 0票数 0

我正在用我的自定义视图来体验这个奇怪的bug。自定义视图应该显示等级分布的仪表。它被添加到大纲视图的单元格视图中。

当我调整窗口的大小时,这个自定义视图不知怎么就会被压碎,看起来也会被破坏。下面我已经粘贴了自定义视图的drawRect

代码语言:javascript
复制
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()
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-10-05 21:47:28

来自drawRect(_ dirtyRect: NSRect)的文档

dirtyRect:定义视图中需要重绘的部分的矩形。此矩形通常表示视图中需要更新的部分。启用响应滚动时,此矩形还可以表示AppKit希望缓存的视图中不可见的部分。

不要在计算中使用dirtyRect,使用self.bounds

票数 1
EN

Stack Overflow用户

发布于 2016-10-05 04:23:45

解决问题的另一种解决方案是使用NSView。您可以有一个带有圆角的容器视图,然后在该容器中绘制子视图(红色、橙色、绿色)。就像这样;

我已经为它写了一个课程,你可以根据你的要求定制;

代码语言:javascript
复制
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();
    }

}

注:用于更改进度默认值的 Call updateProgress()方法为33、33 & 34 (33+33+34 = 100);

您还可以从下面的链接下载一个示例项目;

http://www.filedropper.com/osxtest

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39860471

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档