Cocoa 在NSView中重复背景图像

Cocoa 在NSView中重复背景图像,cocoa,drawing,nsview,nsimage,Cocoa,Drawing,Nsview,Nsimage,我正在尝试在NSView中绘制一个重复的背景图像,到目前为止我有: // INIT - (id)initWithFrame:(NSRect)frame { if (self = [super initWithFrame:frame]) { self.backgroundImage = [NSImage imageNamed:@"progressBackground.pdf"]; } return self; } // DRAW - (void)drawRect:(NSRe

我正在尝试在NSView中绘制一个重复的背景图像,到目前为止我有:

// INIT
- (id)initWithFrame:(NSRect)frame {
  if (self = [super initWithFrame:frame]) {
    self.backgroundImage = [NSImage imageNamed:@"progressBackground.pdf"];
  }

  return self;
}

// DRAW
- (void)drawRect:(NSRect)dirtyRect {
  // Draw the background
  [backgroundImage drawInRect:[self bounds]
                     fromRect:NSMakeRect(0.0f, 0.0f, backgroundImage.size.width, backgroundImage.size.height)
                    operation:NSCompositeSourceAtop
                     fraction:1.0f];
  NSLog(@"%dx%d", backgroundImage.size.width, backgroundImage.size.height);
}
但是,视图会拉伸图像以填充自身。我希望图像可以重复

(黑色笔划已修复)

此外,出现了一些奇怪的情况,因为控制台显示图像的大小等于
-2109897792x0
,但图像实际上是
32x32
!WTF


有人能帮帮我吗?谢谢。

您可以使用创建图案颜色,然后用该“颜色”填充背景矩形。这应该是您想要完成的。

我在这里找到了答案,以防止模式从底部绘制,并在调整窗口大小时产生奇怪的效果:

基本上,在drawRect中需要做的就是保存图形上下文状态,调用该方法,绘制图案,然后恢复状态

方法是:

- (void)drawRect:(NSRect)dirtyRect {
    NSGraphicsContext* theContext = [NSGraphicsContext currentContext];
    [theContext saveGraphicsState];
    [[NSGraphicsContext currentContext] setPatternPhase:NSMakePoint(0,[self frame].size.height)];
    [self.customBackgroundColour set];
    NSRectFill([self bounds]);
    [theContext restoreGraphicsState]; 
}
我在init方法中初始化了背景色图案:

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.customBackgroundColour = [NSColor colorWithPatternImage:[NSImage imageNamed:@"light-linen-texture.png"]];
    }

    return self;
}

在Github上查看
rmskindview


编辑:
rmskindview
是一个
NSView
子类,您可以通过界面生成器中的用户定义的运行时属性直接设置多个选项,包括圆角、背景颜色、背景图像图案等。

请注意这是相对于窗口底部的(根据文档). 当您调整窗口的大小(视图也随之调整大小)时,图案的左上角点将移动(导致背景“游移”到图案视图的任何子视图后面)。这可能令人恶心。:-)我知道这个帖子很老了,但我确实有这个问题。有没有可能让“背景图片”靠拢到顶部?可能不是威胁对你可能收到的不相关答案进行否决投票的最好办法。它甚至会让人们不去打扰。@Joshua但收到关于错误平台的答案是非常非常烦人的。你肯定看到了在任何人做错事情之前警告别人和因为实际违规而这样做之间的区别。前者充其量是不友好的;后者更值得。您看到的是-2109897792x0,因为backgroundImage.size.width是CGFloat,但是您以表示参数将是int的格式字符串传递了%d。添加一些关键字以帮助其他人找到:将平铺图像视图固定到top/top pinning是否有人知道是什么原因导致这样的代码仍然拉伸模式而不是平铺模式?我注意到我的drawRect没有在视图调整大小时被调用,也许这与此有关?在上面的评论中回答了我自己的问题:我必须使我的视图集needsDisplay在其帧更改时显示为YES,并且我重写了setFrame本身来执行此操作。我不确定这是否是正常的方法,或者是否有一些内置机制类似于CALayer的需求Displaynboundschange,但它是有效的。