我正在尝试创建一个Cocoa UI,它由两组正方形(象棋状网格)组成,它们在底层算法运行时会呈现不同的颜色。当算法的执行结束时,UI应该能够处理点击,平移和其他手势。
我到目前为止的层次结构如下(请查看附带的代码以获取具体信息):
1)主窗口是窗口控制器的窗口
2)包含两个自定义视图的拆分视图,mainView和sideView(每个视图都包含一组方块)
3)两个视图控制器(mainViewController和sideViewController)
我希望能够将正方形加载为mainView和sideView的子视图。
我想到了另一个自定义视图,比如说SquareView和另一个nib文件。我的问题是:
a)我如何创建这个SquareView,以便它可以用来创建将添加到mainView和sideView作为子视图的方块,以形成象棋状网格?
b)如何将主视图添加到mainView和sideView以构建两个网格?为简单起见,我们假设前面提到的每个视图都有四个非重叠的正方形。
谢谢!
MainView.m
#import "MainView.h"
@implementation MainView
- (void)drawRect:(NSRect)TheRect
{
[[NSColor grayColor] set];
[NSBezierPath fillRect:[self bounds]];
}
SideView.m
#import "SideView.h"
@implementation MainView
- (void)drawRect:(NSRect)TheRect
{
[[NSColor whiteColor] set];
[NSBezierPath fillRect:[self bounds]];
}
MainWindowController.h
#import <Cocoa/Cocoa.h>
@class SideViewController;
@class MainViewController;
@interface MainWindowController : NSWindowController
{
IBOutlet NSSplitView* oMainSplitView;
SideViewController* sideViewController;
MainViewController* mainViewController;
}
@end
MainWindowController.m
#import "MainWindowController.h"
#import "SideViewController.h"
#import "MainViewController.h"
@implementation MainWindowController
- (void)windowDidLoad
{
sideViewController = [[SideViewController alloc] initWithNibName:@"SideView" bundle:nil];
NSView* splitViewLeftView = [[oMainSplitView subviews] objectAtIndex:0];
NSView* sideView = [sideViewController view];
[sideView setFrame:[splitViewLeftView bounds]];
[sideView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
[splitViewLeftView addSubview:sideView];
mainViewController = [[MainViewController alloc] initWithNibName:@"MainView" bundle:nil];
NSView* splitViewRightView = [[oMainSplitView subviews] objectAtIndex:1];
NSView* mainView = [mainViewController view];
[mainView setFrame:[splitViewRightView bounds]];
[mainView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
[splitViewRightView addSubview:mainView];
}
答案 0 :(得分:0)
a)我认为最简单的方法是创建一个NSBoxes矩阵,你可以在代码或IB中完成。将矩形放在矩阵中可以很容易地遍历它们或访问特定的矩形。
b)我不确定你的问题是什么 - 你会像你在发布的代码中那样使用[mainView addSubview:squareMatrix];
编辑之后:实际上,看起来IB不会让你在一个矩阵中嵌入NSBoxes。在过去,我已经制作了一个子类化的NSButtonCells矩阵(允许没有边框的背景颜色),它有一个64x64单元格的网格,可以点击,并会随着这些点击改变颜色。我不知道您的视图中是否需要固定数量的单元格,还是需要动态更改数字?这样的事情可能对你有用 - 我实际上是在代码中创建的,因为IB在使用那么多单元格进行更新时效果很慢。
这就是我所做的。在我的情况下,我需要没有边框但背景颜色的单元格,所以我必须子类化NSButtonCell,如下所示:
-(id)initWithRGBAlpha:(NSArray *)rgbAlpha {
if (self == [super init]) {
NSColor *color = [NSColor colorWithCalibratedRed:[[rgbAlpha objectAtIndex:0]doubleValue]
green:[[rgbAlpha objectAtIndex:1]doubleValue]
blue:[[rgbAlpha objectAtIndex:2]doubleValue]
alpha:[[rgbAlpha objectAtIndex:3]doubleValue]];
[self setBackgroundColor:color];
[self setTitle:@""];
[self setBordered:NO];
[self setTag:0];
[self setImageScaling:3];
return self;
}else{
return nil;
}
}
-(void) setState:(NSInteger)value {
if (value == 1) {
self.backgroundColor = self.selectedColor;
[super setState:value];
}else {
self.backgroundColor = self.backgroundColor;
[super setState:value];
}
}
-(void) setBackgroundColor:(NSColor *)color {
backgroundColor = color;
selectedColor = [color colorWithAlphaComponent:.75];
}
- (void)encodeWithCoder:(NSCoder *)encoder {
[super encodeWithCoder:encoder];
[encoder encodeObject:self.backgroundColor forKey:@"bColor"];
}
- (id)initWithCoder:(NSCoder *)decoder {
[super initWithCoder:decoder];
self.backgroundColor = [decoder decodeObjectForKey:@"bColor"];
return self;
}
我在代码中创建了矩阵,如下所示:
@implementation RDMatrix
-(void) initWithParentView:(NSView *) cv {
NSNumber *one = [NSNumber numberWithInt:1];
NSArray *colors = [NSArray arrayWithObjects:one,one,one,one,nil];
RDButtonCell *theCell = [[RDButtonCell alloc ]initWithRGBAlpha:colors];
[self initWithFrame:NSMakeRect(200,100,1,1) mode:2 prototype:theCell numberOfRows:64 numberOfColumns:64];
[self setSelectionByRect:TRUE];
[self setCellSize:NSMakeSize(8,8)];
[self sizeToCells];
self.target = self;
self.action = @selector(matrixClick:);
self.backgroundColor = [NSColor lightGrayColor];
self.drawsBackground = TRUE;
self.autoresizingMask = 8;
self.allowsEmptySelection = TRUE;
[cv addSubview:self];
}
-(void) matrixClick: (id) sender {
for (RDButtonCell *aCell in self.selectedCells){
if ([self.selectedCells count] < 64) {
aCell.backgroundColor = [NSColor colorWithCalibratedRed:1 green:0 blue:0 alpha:1];
}else{
aCell.backgroundColor = [NSColor colorWithCalibratedRed:0 green:.5 blue:1 alpha:1];
}
}
[self deselectAllCells];
}
@end
答案 1 :(得分:0)
你可以根据自己的意愿使这简单或复杂:简单吗?在MainView的drawRect方法中做你想做的一切;复杂:嵌套NSViews(或NSCell,或NSBox等)并让每个人自己绘制。
就个人而言,我会投票保持简单......