如何从头开始以编程方式创建NSCollectionView? [英] How to create NSCollectionView programmatically from scratch?

查看:67
本文介绍了如何从头开始以编程方式创建NSCollectionView?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

NSCollectionView 仍然是我所见过的Cocoa API中最神秘的部分之一。文档很差,并且有很多活动部件,其中很多都是在Interface Builder中实现的,这使文档具有挑战性。



请提供示例代码来创建最简单的 NSCollectionView 可以显示文本字段或按钮,而无需使用Xcode,其中每个文本字段或按钮都有不同的标题。假设有一个默认的窗口 IBOutlet的新Xcode项目。



对于此示例,不需要绑定即可更新NSCollectionView随着数据源的更改。只需显示原型对象的网格并将每个对象的Title设置为某个值即可。



如果我们可以找到很多人可以使用的示例,我认为它将帮助使用 NSCollectionViews 并且与我一样困惑的所有人。



请求摘要




  • 提供示例代码以在新的Xcode项目中呈现NSCollectionView

  • Do不使用Interface Builder,请使用提供的默认窗口IBOutlet

  • NSCollectionView应该包含文本字段或按钮,您选择

  • 视图中的每个项目都应标题不同

  • 不需要绑定



如果有满足条件的示例代码这些要求,请提供一个链接,那就好了!

解决方案

我不确定创建一个集合视图以编程方式且没有绑定,但是在这里我



简介



使用集合视图时,基本上有四个组成部分:




  • 视图: NSView 的子类,负责显示信息;

  • 集合视图本身;

  • 视图控制器: NSCollectionViewItem 的子类,用作集合视图项的原型;
  • 模型:对象数组。



通常,视图是在Interface Builder中设计的,并且



以编程方式执行:



常量



  static const NSSize buttonSize = {80,20}; 
静态常量NSSize itemSize = {100,40};
static const NSPoint buttonOrigin = {10,10};



视图



这是标准视图(在Interface Builder术语中为自定义视图)包含一个按钮。注意,视图的大小是固定的。

  @interface BVView:NSView 
@属性(弱)NSButton * button;
@end

@ implementation BVView
@ synthesize按钮;
-(id)initWithFrame:(NSRect)frameRect {
self = [super initWithFrame:(NSRect){frameRect.origin,itemSize}];
if(self){
NSButton * newButton = [[NSButton alloc]
initWithFrame:(NSRect){buttonOrigin,buttonSize}];
[self addSubview:newButton];
self.button = newButton;
}
返回自我;
}
@end



View Controller(Prototype)



通常,视图控制器从nib文件加载其视图。在极少数情况下,如果视图控制器无法从nib文件获取视图,则开发人员必须在 -view之前将其发送给 -setView: 由视图控制器接收,或覆盖 -loadView 。下面的代码完成了后者。



视图控制器通过 -setRepresentedObject:接收相应的模型对象。我重写了它,以便在模型对象发生更改时更新按钮标题。请注意,这完全可以通过使用Cocoa绑定来完成,而无需任何代码。 / p>

  @interface BVPrototype:NSCollectionViewItem 
@end

@implementation BVPrototype
- (void)loadView {
[self setView:[[BVView alloc] initWithFrame:NSZeroRect]];
}
-(void)setRepresentedObject:(id)representedObject {
[super setRepresentedObject:representedObject];
[[((BVView *)[self view] button] setTitle:representedObject];
}
@end



模型



表示按钮标题的简单字符串数组:

  @property(强)NSArray * titles; 
self.titles = [NSArray arrayWithObjects:@ Case,@ Molly,@ Armitage,
@ Hideo,@ The Finn,@ Maelcum,@ Wintermute ,@ Neuromancer,nil];



收藏夹视图



到目前为止,唯一已建立的关系是项目原型( BVPrototype )使用的视图( BVView )。必须告知收集视图应该使用的原型以及从中获取数据的模型。

  NSCollectionView * cv = [[NSCollectionView alloc] 
initWithFrame:[[[self window] contentView] frame]];
[cv setItemPrototype:[BVPrototype new]];
[cv setContent:[self title]];



应用程序委托的完整源代码



  #import BVAppDelegate.h 


静态常量NSSize buttonSize = {80,20};
静态常量NSSize itemSize = {100,40};
static const NSPoint buttonOrigin = {10,10};


@interface BVView:NSView
@属性(弱)NSButton * button;
@end

@ implementation BVView
@ synthesize按钮;
-(id)initWithFrame:(NSRect)frameRect {
self = [super initWithFrame:(NSRect){frameRect.origin,itemSize}];
if(self){
NSButton * newButton = [[NSButton alloc]
initWithFrame:(NSRect){buttonOrigin,buttonSize}];
[self addSubview:newButton];
self.button = newButton;
}
返回自我;
}
@end


@interface BVPrototype:NSCollectionViewItem
@end

@implementation BVPrototype
- (void)loadView {
[self setView:[[BVView alloc] initWithFrame:NSZeroRect]];
}
-(void)setRepresentedObject:(id)representedObject {
[super setRepresentedObject:representedObject];
[[((BVView *)[self view] button] setTitle:representedObject];
}
@end


@interface BVAppDelegate()
@property(strong)NSArray * titles;
@end

@ implementation BVAppDelegate

@ synthesize window = _window;
@synthesize标题;

-(void)applicationDidFinishLaunching:(NSNotification *)aNotification {
self.titles = [NSArray arrayWithObjects:@ Case,@ Molly,@ Armitage,
@ Hideo,@ The Finn,@ Maelcum,@ Wintermute,@ Neuromancer,nil];

NSCollectionView * cv = [[NSCollectionView alloc]
initWithFrame:[[[self window] contentView] frame]];
[cv setItemPrototype:[BVPrototype new]];
[cv setContent:[self title]];

[cv setAutoresizingMask:(NSViewMinXMargin
| NSViewWidthSizable
| NSViewMaxXMargin
| NSViewMinYMargin
| NSViewHeightSizable
| NSViewMaxYMargin)];
[[[self window] contentView] addSubview:cv];
}

@end


NSCollectionView remains one of the most mysterious parts of the Cocoa API that I've ever seen. Documentation is poor and there are many moving parts, many of which are often implemented in Interface Builder, making documentation challenging.

Please provide sample code to create the simplest case of NSCollectionView which displays either Text Fields or Buttons without using Xcode where each Text Field or Button has a different Title. Assume a new Xcode project with the default window IBOutlet.

For this example, no binding is required to update the NSCollectionView as the data source changes. Simply display a grid of prototype objects and set each object's Title to some value.

If we can get a good example of how to do this available to many people, I think it will help everyone who works with NSCollectionViews and is as baffled as I am.

Summary of request

  • Provide sample code to render an NSCollectionView in a new Xcode project
  • Do not use Interface Builder, do use the default window IBOutlet provided
  • NSCollectionView should contain Text Fields or Buttons, your choice
  • Each item in the view should have a different Title
  • No binding is required

If there's sample code out there that meets these requirements, please provide a link, that'd be great!

解决方案

I’m not sure there’s much insight in creating a collection view programmatically and without bindings, but here it goes.

Introduction

There are essentially four components when using a collection view:

  • View: a subclass of NSView, responsible for displaying information;
  • The collection view itself;
  • View controller: a subclass of NSCollectionViewItem that serves as the collection view item prototype;
  • Model: an array of objects.

Usually a view is designed in Interface Builder, and a model is mediated by Cocoa bindings.

Doing it programmatically:

Constants

static const NSSize buttonSize = {80, 20};
static const NSSize itemSize = {100, 40};
static const NSPoint buttonOrigin = {10, 10};

View

This is a standard view (a custom view in Interface Builder parlance) containing a button. Note that the view has fixed size.

@interface BVView : NSView
@property (weak) NSButton *button;
@end

@implementation BVView
@synthesize button;
- (id)initWithFrame:(NSRect)frameRect {
    self = [super initWithFrame:(NSRect){frameRect.origin, itemSize}];
    if (self) {
        NSButton *newButton = [[NSButton alloc] 
            initWithFrame:(NSRect){buttonOrigin, buttonSize}];
        [self addSubview:newButton];
        self.button = newButton;
    }
    return self;
}
@end

View Controller (Prototype)

Normally a view controller loads its view from a nib file. In the rare cases where the view controller doesn’t obtain its view from a nib file, the developer must either send it -setView: before -view is received by the view controller, or override -loadView. The following code does the latter.

View controllers receive the corresponding model object via -setRepresentedObject:. I’ve overridden it so as to update the button title whenever the model object changes. Note that this can be accomplished by using Cocoa bindings without any code at all.

Note that none of this code is specific to collection views — it’s general view controller behaviour.

@interface BVPrototype : NSCollectionViewItem
@end

@implementation BVPrototype
- (void)loadView {
    [self setView:[[BVView alloc] initWithFrame:NSZeroRect]];
}
- (void)setRepresentedObject:(id)representedObject {
    [super setRepresentedObject:representedObject];
    [[(BVView *)[self view] button] setTitle:representedObject];
}
@end

Model

A simple array of strings representing button titles:

@property (strong) NSArray *titles;
self.titles = [NSArray arrayWithObjects:@"Case", @"Molly", @"Armitage",
    @"Hideo", @"The Finn", @"Maelcum", @"Wintermute", @"Neuromancer", nil];

Collection View

So far, the only relation that’s been established is the view (BVView) used by the item prototype (BVPrototype). The collection view must be informed of the prototype it should be using as well as the model from which to obtain data.

NSCollectionView *cv = [[NSCollectionView alloc]
    initWithFrame:[[[self window] contentView] frame]]; 
[cv setItemPrototype:[BVPrototype new]];
[cv setContent:[self titles]];

Full Source Code for the Application Delegate

#import "BVAppDelegate.h"


static const NSSize buttonSize = { 80, 20 };
static const NSSize itemSize = { 100, 40 };
static const NSPoint buttonOrigin = { 10, 10 };


@interface BVView : NSView
@property (weak) NSButton *button;
@end

@implementation BVView
@synthesize button;
- (id)initWithFrame:(NSRect)frameRect {
    self = [super initWithFrame:(NSRect){frameRect.origin, itemSize}];
    if (self) {
        NSButton *newButton = [[NSButton alloc]
            initWithFrame:(NSRect){buttonOrigin, buttonSize}];
        [self addSubview:newButton];
        self.button = newButton;
    }
    return self;
}
@end


@interface BVPrototype : NSCollectionViewItem
@end

@implementation BVPrototype
- (void)loadView {
    [self setView:[[BVView alloc] initWithFrame:NSZeroRect]];
}
- (void)setRepresentedObject:(id)representedObject {
    [super setRepresentedObject:representedObject];
    [[(BVView *)[self view] button] setTitle:representedObject];
}
@end


@interface BVAppDelegate ()
@property (strong) NSArray *titles;
@end

@implementation BVAppDelegate

@synthesize window = _window;
@synthesize titles;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    self.titles = [NSArray arrayWithObjects:@"Case", @"Molly", @"Armitage",
        @"Hideo", @"The Finn", @"Maelcum", @"Wintermute", @"Neuromancer", nil];

    NSCollectionView *cv = [[NSCollectionView alloc]
        initWithFrame:[[[self window] contentView] frame]]; 
    [cv setItemPrototype:[BVPrototype new]];
    [cv setContent:[self titles]];

    [cv setAutoresizingMask:(NSViewMinXMargin
                             | NSViewWidthSizable
                             | NSViewMaxXMargin
                             | NSViewMinYMargin
                             | NSViewHeightSizable
                             | NSViewMaxYMargin)];
    [[[self window] contentView] addSubview:cv];
}

@end

这篇关于如何从头开始以编程方式创建NSCollectionView?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆