tuna
tuna

Reputation: 931

How to make a grid background pattern for NSView?

is there an easy way to get this grid background? Or do I have to do it something like this [NSColor colorWithPatternImage:[NSImage ...]]?

Screenshot of interface

I don't want complete code. I just want to know if there is an easy way to do that and if yes how.

Upvotes: 4

Views: 2070

Answers (6)

Mike James
Mike James

Reputation: 471

The same but for Swift 4

override func draw(_ dirtyRect: NSRect) {
    super.draw(dirtyRect)

    if let context = NSGraphicsContext.current?.cgContext {
        NSColor.white.setFill()
        context.fill(dirtyRect)
        context.flush()
    }

    for i in 1...(Int(self.bounds.size.height) / 10) {
        if i % 10 == 0 {
            NSColor.init(red: 100/255.0, green: 149/255.0, blue: 237/255.0, alpha: 0.3).set()
        }else if i % 5 == 0 {
            NSColor.init(red: 100/255.0, green: 149/255.0, blue: 237/255.0, alpha: 0.2).set()
        }else{
            NSColor.init(red: 100/255.0, green: 149/255.0, blue: 237/255.0, alpha: 0.1).set()
        }            
        NSBezierPath.strokeLine(from: CGPoint(x: 0, y: CGFloat(i) * 10 - 0.5), to: CGPoint(x: self.bounds.size.width, y: CGFloat(i) * 10 - 0.5))
    }

    for i in 1...(Int(self.bounds.size.width) / 10) {
        if i % 10 == 0 {
            NSColor.init(red: 100/255.0, green: 149/255.0, blue: 237/255.0, alpha: 0.3).set()
        }else if i % 5 == 0 {
            NSColor.init(red: 100/255.0, green: 149/255.0, blue: 237/255.0, alpha: 0.2).set()
        }else{
            NSColor.init(red: 100/255.0, green: 149/255.0, blue: 237/255.0, alpha: 0.1).set()
        }
        NSBezierPath.strokeLine(from: CGPoint(x: CGFloat(i) * 10 - 0.5, y:0), to: CGPoint(x: CGFloat(i) * 10 - 0.5, y: self.bounds.size.height))
    }
}

Upvotes: 4

pascalbros
pascalbros

Reputation: 16452

The same of "sad tuna" but in Swift 3

override func drawRect(dirtyRect: NSRect) {
    super.drawRect(dirtyRect)
    if let context = NSGraphicsContext.currentContext()?.CGContext {
        NSColor.whiteColor().setFill()
        CGContextFillRect(context, dirtyRect)
        CGContextFlush(context)
    }

    for i in 1...(Int(self.bounds.size.height) / 10) {
        if i % 10 == 0 {
            NSColor(SRGBRed: 100/255.0, green: 149/255.0, blue: 237/255.0, alpha: 0.3).set()
        }else if i % 5 == 0 {
            NSColor(SRGBRed: 100/255.0, green: 149/255.0, blue: 237/255.0, alpha: 0.2).set()
        }else{
            NSColor(SRGBRed: 100/255.0, green: 149/255.0, blue: 237/255.0, alpha: 0.1).set()
        }

        NSBezierPath.strokeLineFromPoint(CGPointMake(0, CGFloat(i) * 10 - 0.5), toPoint: CGPointMake(self.bounds.size.width, CGFloat(i) * 10 - 0.5))
    }

    for i in 1...(Int(self.bounds.size.width) / 10) {
        if i % 10 == 0 {
            NSColor(SRGBRed: 100/255.0, green: 149/255.0, blue: 237/255.0, alpha: 0.3).set()
        }else if i % 5 == 0 {
            NSColor(SRGBRed: 100/255.0, green: 149/255.0, blue: 237/255.0, alpha: 0.2).set()
        }else{
            NSColor(SRGBRed: 100/255.0, green: 149/255.0, blue: 237/255.0, alpha: 0.1).set()
        }

        NSBezierPath.strokeLineFromPoint(CGPointMake(CGFloat(i) * 10 - 0.5, 0), toPoint: CGPointMake(CGFloat(i) * 10 - 0.5, self.bounds.size.height))
    }
}

Upvotes: 1

xySVerma
xySVerma

Reputation: 971

Porting Methanol's solution for swift and resolving error in MacOS 10.10 onwards.

A simple static function could be used and called from drawRect()

static func makeGridBackground(dirtyRect: NSRect, view: NSView){
    //view.print("WMEditorUtils: initiated drawing")

    //Fill background with white color
    if let context = NSGraphicsContext.currentContext()?.CGContext {
        NSColor.whiteColor().setFill()
        CGContextFillRect(context, dirtyRect)
        CGContextFlush(context)
    }

    //Draw Lines: Horizontal
    for var i:Int = 1; i < (Int)(view.bounds.size.height / 10); i++ {
        if (i % 10 == 0) {
            NSColor(deviceRed: 100.0/255.0, green: 149.0/255.0, blue: 237.0/255.0, alpha: 0.3).set()
        }
        else if (i % 5 == 0) {
            NSColor(deviceRed: 100.0/255.0, green: 149.0/255.0, blue: 237.0/255.0, alpha: 0.2).set()
        }
        else{
            NSColor(deviceRed: 100.0/255.0, green: 149.0/255.0, blue: 237.0/255.0, alpha: 0.1).set()
        }
        NSBezierPath.strokeLineFromPoint(NSMakePoint(0, (CGFloat)(i * 10) - 0.5), toPoint: NSMakePoint(view.bounds.size.width, (CGFloat)(i * 10) - 0.5))
    }

    //Draw Lines: Vertical
    for var i:Int = 1; i < (Int)(view.bounds.size.width / 10); i++ {
        if (i % 10 == 0) {
            NSColor(deviceRed: 100.0/255.0, green: 149.0/255.0, blue: 237.0/255.0, alpha: 0.3).set()
        }
        else if (i % 5 == 0) {
            NSColor(deviceRed: 100.0/255.0, green: 149.0/255.0, blue: 237.0/255.0, alpha: 0.2).set()
        }
        else{
            NSColor(deviceRed: 100.0/255.0, green: 149.0/255.0, blue: 237.0/255.0, alpha: 0.1).set()
        }
        NSBezierPath.strokeLineFromPoint(NSMakePoint((CGFloat)(i * 10) - 0.5, 0), toPoint: NSMakePoint((CGFloat)(i * 10) - 0.5, view.bounds.size.width))
    }

}

Upvotes: 1

tuna
tuna

Reputation: 931

This is my solution:

- (void)drawRect:(NSRect)dirtyRect
{
CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
[[NSColor whiteColor] setFill];
CGContextFillRect(context, dirtyRect);

for (int i = 1; i < [self bounds].size.height / 10; i++) {
    if (i % 10 == 0) {
        [[NSColor colorWithSRGBRed:100/255.0 green:149/255.0 blue:237/255.0 alpha:0.3] set];
    } else if (i % 5 == 0) {
        [[NSColor colorWithSRGBRed:100/255.0 green:149/255.0 blue:237/255.0 alpha:0.2] set];
    } else {
        [[NSColor colorWithSRGBRed:100/255.0 green:149/255.0 blue:237/255.0 alpha:0.1] set];
    }
    [NSBezierPath strokeLineFromPoint:NSMakePoint(0, i * 10 - 0.5) toPoint:NSMakePoint([self bounds].size.width, i * 10 - 0.5)];
}
for (int i = 1; i < [self bounds].size.width / 10; i++) {
    if (i % 10 == 0) {
        [[NSColor colorWithSRGBRed:100/255.0 green:149/255.0 blue:237/255.0 alpha:0.3] set];
    } else if (i % 5 == 0) {
        [[NSColor colorWithSRGBRed:100/255.0 green:149/255.0 blue:237/255.0 alpha:0.2] set];
    } else {
        [[NSColor colorWithSRGBRed:100/255.0 green:149/255.0 blue:237/255.0 alpha:0.1] set];
    }
    [NSBezierPath strokeLineFromPoint:NSMakePoint(i * 10 - 0.5, 0) toPoint:NSMakePoint(i * 10 - 0.5, [self bounds].size.height)];
}

}

Grid

Upvotes: 7

Jay
Jay

Reputation: 6638

Just have a look at the Sketch example that comes with every Xcode installation or is available as a separate download, too.

It features a grid implementation (and many other useful demonstrations of Cocoa techniques..) allowing for zooming, etc.

Upvotes: 1

Mike Lischke
Mike Lischke

Reputation: 53407

I don't think a pattern color is a good solution here, especially since you need to vary the lines. Instead use an NSBezierPath and moveToPoint/lineToPoint pairs for each horizontal and vertical line. You can then draw the grid in one call. Do extra steps for those lines with a different color (alpha) and/or width (i.e. don't add the thicker lines to the main grid path but create a separate one for them).

Upvotes: 2

Related Questions