I have an NSView with a drawRect
我有一个带有drawRect的NSView
- (void)drawRect:(CGRect)rect {
// Drawing code
NSPoint origin = [self visibleRect].origin;
[[NSGraphicsContext currentContext]
setPatternPhase:NSMakePoint(origin.x, origin.y)];
[[NSColor colorWithPatternImage: self.image] set];
[NSBezierPath fillRect: [self bounds]];
}
It draws my pattern perfectly, but i can see the pattern scroll when i change the the size of my window.
它完美地绘制了我的图案,但是当我改变窗口的大小时,我可以看到图案滚动。
i have tried to set the view isFlipped to YES but that doesn't change anything.
我试图将视图isFlipped设置为YES,但这不会改变任何东西。
2 个解决方案
#1
1
You need to do some off-screen drawing first and then draw that result onto the view. For example you can use a blank NSImage of the exact same size as the view, draw the pattern on that image and then draw that image on the view.
您需要先进行一些离屏绘制,然后将该结果绘制到视图上。例如,您可以使用与视图完全相同大小的空白NSImage,在该图像上绘制图案,然后在视图上绘制该图像。
Your code may look something like that:
您的代码可能看起来像这样:
- (void)drawRect:(NSRect)dirtyRect
{
// call super
[super drawRect:dirtyRect];
// create blank image and lock drawing on it
NSImage* bigImage = [[[NSImage alloc] initWithSize:self.bounds.size] autorelease];
[bigImage lockFocus];
// draw your image patter on the new blank image
NSColor* backgroundColor = [NSColor colorWithPatternImage:bgImage];
[backgroundColor set];
NSRectFill(self.bounds);
[bigImage unlockFocus];
// draw your new image
[bigImage drawInRect:self.bounds
fromRect:NSZeroRect
operation:NSCompositeSourceOver
fraction:1.0f];
}
// I think you may also need to flip your view
- (BOOL)isFlipped
{
return YES;
}
#2
0
Swift
A lot has changed, now things are easier, unfortunately part of objective-C's patrimony is lost and when it comes to Cocoa, Swift is like an orphan child. Anyways, based on Neovibrant's we can deduct the solution.
很多事情发生了变化,现在事情变得更容易了,不幸的是,客观的一部分 - C的遗产已经丢失,而当谈到Cocoa时,Swift就像一个孤儿。无论如何,基于Neovibrant,我们可以扣除解决方案。
- Subclass NSView
- Override draw method
- Call parent method (this is important)
- Set a fill on buffer within the bounds of the view
- Draw fill on buffer
调用父方法(这很重要)
在视图的边界内设置填充缓冲区
在缓冲区上绘制填充
覆盖draw方法调用父方法(这很重要)在视图的边界内设置填充缓冲区
code
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
let bgimage : NSImage = /* Set the image you want */
let background = NSColor.init(patternImage: bgimage)
background.setFill()
bgimage.draw(in: self.bounds, from: NSZeroRect, operation: .sourceOver, fraction: 1.0)
}
#1
1
You need to do some off-screen drawing first and then draw that result onto the view. For example you can use a blank NSImage of the exact same size as the view, draw the pattern on that image and then draw that image on the view.
您需要先进行一些离屏绘制,然后将该结果绘制到视图上。例如,您可以使用与视图完全相同大小的空白NSImage,在该图像上绘制图案,然后在视图上绘制该图像。
Your code may look something like that:
您的代码可能看起来像这样:
- (void)drawRect:(NSRect)dirtyRect
{
// call super
[super drawRect:dirtyRect];
// create blank image and lock drawing on it
NSImage* bigImage = [[[NSImage alloc] initWithSize:self.bounds.size] autorelease];
[bigImage lockFocus];
// draw your image patter on the new blank image
NSColor* backgroundColor = [NSColor colorWithPatternImage:bgImage];
[backgroundColor set];
NSRectFill(self.bounds);
[bigImage unlockFocus];
// draw your new image
[bigImage drawInRect:self.bounds
fromRect:NSZeroRect
operation:NSCompositeSourceOver
fraction:1.0f];
}
// I think you may also need to flip your view
- (BOOL)isFlipped
{
return YES;
}
#2
0
Swift
A lot has changed, now things are easier, unfortunately part of objective-C's patrimony is lost and when it comes to Cocoa, Swift is like an orphan child. Anyways, based on Neovibrant's we can deduct the solution.
很多事情发生了变化,现在事情变得更容易了,不幸的是,客观的一部分 - C的遗产已经丢失,而当谈到Cocoa时,Swift就像一个孤儿。无论如何,基于Neovibrant,我们可以扣除解决方案。
- Subclass NSView
- Override draw method
- Call parent method (this is important)
- Set a fill on buffer within the bounds of the view
- Draw fill on buffer
调用父方法(这很重要)
在视图的边界内设置填充缓冲区
在缓冲区上绘制填充
覆盖draw方法调用父方法(这很重要)在视图的边界内设置填充缓冲区
code
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
let bgimage : NSImage = /* Set the image you want */
let background = NSColor.init(patternImage: bgimage)
background.setFill()
bgimage.draw(in: self.bounds, from: NSZeroRect, operation: .sourceOver, fraction: 1.0)
}