RubyMotion:尝试遵循Mac的Quartz 2D编程指南

时间:2014-10-03 12:14:46

标签: objective-c macos quartz-graphics quartz-2d rubymotion

我正在尝试使用RubyMotion关注Quartz 2D programming guide

这是我的AppDelegate

class AppDelegate
  def applicationDidFinishLaunching(notification)
    buildMenu
    buildWindow
  end

  def buildWindow
    @window = NSWindow.alloc.initWithContentRect([[240, 180], [480, 360]],
      styleMask: NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask,
      backing: NSBackingStoreBuffered,
      defer: false)
    @window.title = NSBundle.mainBundle.infoDictionary['CFBundleName']
    @window.orderFrontRegardless

    @view = MyQuartzView.alloc.initWithFrame(@window.frame)
    @window.contentView.addSubview @view
  end
end

这是我的MyQuartzView,它应该是指南中代码的直接翻译:

class MyQuartzView < NSView
  def drawRect(rect)
    myContext = NSGraphicsContext.currentContext.graphicsPort
    CGContextSetRGBFillColor(myContext, 1, 0, 0, 1)
    CGContextFillRect(myContext, CGRectMake(0, 0, 200, 100))
    CGContextSetRGBFillColor(myContext, 0, 0, 1, 0.5)
    CGContextFillRect(myContext, CGRectMake(0, 0, 100, 200))
  end
end

我收到以下错误:

<Error>: CGContextSetRGBFillColor: invalid context 0x10222bad0
<Error>: CGContextFillRects: invalid context 0x10222bad0
<Error>: CGContextSetRGBFillColor: invalid context 0x10222bad0
<Error>: CGContextFillRects: invalid context 0x10222bad0

为什么上下文无效?我在drawRect方法内。

修改 如果我将窗口rect更改为[[340, 380], [480, 360]],则错误消失,但不会调用drawRect。但是,当我调整窗口大小时,它会被调用同样的错误。

编辑2 这是一个OS X应用程序。

编辑3 有趣的是,Objective-C中的相同程序运行良好:

// main.m
#import <Cocoa/Cocoa.h>
#import "MyQuartzView.h"

int main(int argc, const char * argv[])
{
    NSApplication *app = [NSApplication sharedApplication];
    NSRect frame = NSMakeRect(100., 100., 300., 300.);

    NSWindow *window = [[NSWindow alloc]
        initWithContentRect: frame
                  styleMask: NSTitledWindowMask | NSClosableWindowMask
                    backing: NSBackingStoreBuffered
                      defer: false];

    [window setTitle: @"Test"];

    id view = [[MyQuartzView alloc] initWithFrame: frame];
    [window setContentView: view];
    [window setDelegate: view];
    [window orderFrontRegardless];

    [app run];

    return EXIT_SUCCESS;
}

// MyQuartzView.m
#import "MyQuartzView.h"

@implementation MyQuartzView

- (id)initWithFrame:(NSRect)frame
{
    return[super initWithFrame:frame];
}

- (void)drawRect:(NSRect)dirtyRect
{
    CGContextRef myContext = [[NSGraphicsContext currentContext] graphicsPort];
    CGContextSetRGBFillColor (myContext, 1, 0, 0, 1);
    CGContextFillRect (myContext, CGRectMake (0, 0, 200, 100));
    CGContextSetRGBFillColor (myContext, 0, 0, 1, .5);
    CGContextFillRect (myContext, CGRectMake (0, 0, 100, 200));
}

@end

1 个答案:

答案 0 :(得分:1)

这是让它发挥作用的神奇之处:当你获得上下文时,你需要调用to_object

myContext = NSGraphicsContext.currentContext.graphicsPort.to_object

我在RubyMotion项目中实现了您的代码,结果就是这样:

enter image description here