当窗口改变大小时,带有填充(图案图像)的NSView会滚动

时间:2012-09-04 12:10:29

标签: objective-c macos cocoa nsview 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]];
}

它完美地绘制了我的图案,但是当我改变窗口的大小时,我可以看到图案滚动。

我试图将视图isFlipped设置为YES,但这不会改变任何内容。

2 个答案:

答案 0 :(得分:1)

您需要先进行一些离屏绘制,然后将该结果绘制到视图上。例如,您可以使用与视图完全相同大小的空白NSImage,在该图像上绘制图案,然后在视图上绘制该图像。

您的代码可能看起来像这样:

- (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;
}

答案 1 :(得分:0)

迅速

发生了很大的变化,现在事情变得更容易了,不幸的是,Objective-C的遗产消失了,当谈到可可时,斯威夫特就像个孤儿。无论如何,基于Neovibrant的方法,我们可以推断出解决方案。

  1. 子类NSView
  2. 覆盖绘制方法
    • 调用父方法(这很重要)
    • 在视图范围内设置缓冲区填充
    • 在缓冲区上绘制填充

代码

    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)
    }