选择突出显示在NSCollectionView中 [英] Selection Highlight in NSCollectionView

查看:271
本文介绍了选择突出显示在NSCollectionView中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个工作 NSCollectionView 有一个次要,但关键的异常。获取和突出显示集合中的所选项。



我已经在Snow Leopard之前工作,但是一些东西似乎已经改变,我不能放置我的手指上,所以我把我的 NSCollectionView 回到一个基本测试,并按照苹果的文档创建一个NSCollectionView这里:



http:// developer。 apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/CollectionViews/Introduction/Introduction.html



快速入门指南后,集合视图效果很好。但是,本指南不讨论除之外的选择。有诸如合并图像视图,将对象设置为可选择或不可选择以及如果选择时更改颜色等功能。



使用这个例子,我进入下一步将控制器绑定到 NSCollectionView selectionIndexes ,认为这会绑定在 NSCollectionView 和数组控制器之间进行的任何选择,因此触发KVO通知。我还设置 NSCollectionView 在IB中可选。



似乎没有选择委托 NSCollectionView 并且与大多数Cocoa UI视图不同,似乎没有默认选择的高亮。



所以我的问题真的归结为


  1. 如何捕获某个项目的选择?

  2. 如何显示项目的突出显示?

NSCollectionView 编程指南似乎很少,而且大部分通过Google的搜索似乎是在Snow Leopard之前实现的,或者在单独的XIB文件中使用视图。



后者(单独的XIB文件的视图),我不明白为什么这应该是一个先决条件,否则我会怀疑苹果不会包括在相同的捆绑包作为集合视图项目。



我知道这将是一个看不见树的树木的问题 - 所以我准备了doh!


$ b

像往常一样,任何人都非常感激。



>



确定,所以我想找到所选项目,但尚未计算突出显示。对于感兴趣的计算选择的项目(假设你遵循苹果指南):



在控制器(在我的测试用例中的应用程序委托)我添加了以下:



在awakeFromNib中

  [personArrayController addObserver:self 
forKeyPath:@selectionIndexes
options:NSKeyValueObservingOptionNew
context:nil];

新方法



   - (void)observeValueForKeyPath:(NSString *)keyPath 
ofObject:(id)object
change:(NSDictionary *)change
context: (void *)context
{
if([keyPath isEqualTo:@selectionIndexes])
{
if([[personArrayController selectedObjects] count]> 0)
{
if([[personArrayController selectedObjects] count] == 1)
{
personModel * pm =(PersonModel *)
[[personArrayController selectedObjects] objectAtIndex:0] ;
NSLog(@Only 1 selected:%@,[pm name]);
}
else
{
//多于一个选择 - 如果需要则迭代
}
}
}



不要忘记dealloc用于非GC

   - (void)dealloc 
{
[personArrayController removeObserver:self
forKeyPath:@selectionIndexes];
[super dealloc]
}

仍在搜索高亮显示分辨率...



更新2



收回Macatomy的建议,但仍有问题。发布相关类方法以查看我出错的位置。



MyView.h

  #import< Cocoa / Cocoa.h> 

@interface MyView:NSView {
BOOL selected;
}

@property(readwrite)BOOL selected;

@end

MyView.m / p>

  #importMyView.h

@implementation MyView

@合成选择;

- (id)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
if(self){
//初始化代码在这里。
}
return self;
}

- (void)drawRect:(NSRect)dirtyRect
{
NSRect outerFrame = NSMakeRect(0,0,143,104)
NSRect selectedFrame = NSInsetRect(outerFrame,2,2);

if(selected)
[[NSColor yellowColor] set];
else
[[NSColor redColor] set];

[NSBezierPath strokeRect:selectedFrame];
}

@end

MyCollectionViewItem.h



  #import< Cocoa / Cocoa.h> 
@class MyView;

@interface MyCollectionViewItem:NSCollectionViewItem {

}

@end

MyCollectionViewItem.m *

  #importMyCollectionViewItem.h
#importMyView.h

@implementation MyCollectionViewItem

- (void)setSelected:(BOOL)flag
{

[(MyView *)[self view] setSelected:flag];
[(MyView *)[self view] setNeedsDisplay:YES];
}

@end


解决方案

在Interface Builder中为NSCollectionView启用,然后在您用于原型视图的NSView子类中声明一个名为selected的属性:

  @property(readwrite)BOOL selected; 

UPDATED CODE HERE:超级调用)



子类NSCollectionViewItem和override -setSelected:

   - (void)setSelected:(BOOL)flag 
{
[super setSelected:flag];
[(PrototypeView *)[self view] setSelected:flag];
[(PrototypeView *)[self view] setNeedsDisplay:YES];
}

然后,您需要在原型视图的drawRect:突出显示:

   - (void)drawRect:(NSRect)dirtyRect 
{
if
[[NSColor blueColor] set];
NSRectFill([self bounds]);
}
}

,但是可以自定义以任何方式绘制突出显示。我已经在我自己的应用程序中使用这个工具,它的效果很好。


I have a working NSCollectionView with one minor, but critical, exception. Getting and highlighting the selected item within the collection.

I've had all this working prior to Snow Leopard, but something appears to have changed and I can't quite place my finger on it, so I took my NSCollectionView right back to a basic test and followed Apple's documentation for creating an NSCollectionView here:

http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/CollectionViews/Introduction/Introduction.html

The collection view works fine following the quick start guide. However, this guide doesn't discuss selection other than "There are such features as incorporating image views, setting objects as selectable or not selectable and changing colors if they are selected".

Using this as an example I went to the next step of binding the Array Controller to the NSCollectionView with the controller key selectionIndexes, thinking that this would bind any selection I make between the NSCollectionView and the array controller and thus firing off a KVO notification. I also set the NSCollectionView to be selectable in IB.

There appears to be no selection delegate for NSCollectionView and unlike most Cocoa UI views, there appears to be no default selected highlight.

So my problem really comes down to a related issue, but two distinct questions.

  1. How do I capture a selection of an item?
  2. How do I show a highlight of an item?

NSCollectionView's programming guides seem to be few and far between and most searches via Google appear to pull up pre-Snow Leopard implementations, or use the view in a separate XIB file.

For the latter (separate XIB file for the view), I don't see why this should be a pre-requisite otherwise I would have suspected that Apple would not have included the view in the same bundle as the collection view item.

I know this is going to be a "can't see the wood for the trees" issue - so I'm prepared for the "doh!" moment.

As usual, any and all help much appreciated.

Update 1

OK, so I figured finding the selected item(s), but have yet to figure the highlighting. For the interested on figuring the selected items (assuming you are following the Apple guide):

In the controller (in my test case the App Delegate) I added the following:

In awakeFromNib

[personArrayController addObserver:self
       forKeyPath:@"selectionIndexes" 
       options:NSKeyValueObservingOptionNew
       context:nil];

New Method

-(void)observeValueForKeyPath:(NSString *)keyPath 
                     ofObject:(id)object
                       change:(NSDictionary *)change
                      context:(void *)context
{
    if([keyPath isEqualTo:@"selectionIndexes"])
    {
        if([[personArrayController selectedObjects] count] > 0)
        {
            if ([[personArrayController selectedObjects] count] == 1)
            {
                personModel * pm = (PersonModel *) 
                       [[personArrayController selectedObjects] objectAtIndex:0];
                NSLog(@"Only 1 selected: %@", [pm name]);
            }
            else
            {
                // More than one selected - iterate if need be
            }
        }
    }

Don't forget to dealloc for non-GC

-(void)dealloc
{
    [personArrayController removeObserver:self 
                               forKeyPath:@"selectionIndexes"];
    [super dealloc];
}

Still searching for the highlight resolution...

Update 2

Took Macatomy's advice but still had an issue. Posting the relevant class methods to see where I've gone wrong.

MyView.h

#import <Cocoa/Cocoa.h>

@interface MyView : NSView {
    BOOL selected;
}

@property (readwrite) BOOL selected;

@end

MyView.m

#import "MyView.h"

@implementation MyView

@synthesize selected;

-(id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code here.
    }
    return self;
}

-(void)drawRect:(NSRect)dirtyRect
{
    NSRect outerFrame = NSMakeRect(0, 0, 143, 104);
    NSRect selectedFrame = NSInsetRect(outerFrame, 2, 2);

    if (selected)
        [[NSColor yellowColor] set];
    else
        [[NSColor redColor] set];

    [NSBezierPath strokeRect:selectedFrame];
}

@end

MyCollectionViewItem.h

#import <Cocoa/Cocoa.h>
@class MyView;

@interface MyCollectionViewItem : NSCollectionViewItem {

}

@end

"MyCollectionViewItem.m*

#import "MyCollectionViewItem.h"
#import "MyView.h"

@implementation MyCollectionViewItem

-(void)setSelected:(BOOL)flag
{

    [(MyView *)[self view] setSelected:flag];
    [(MyView *)[self view] setNeedsDisplay:YES];
}

@end

解决方案

Its not too hard to do. Make sure "Selection" is enabled for the NSCollectionView in Interface Builder. Then in the NSView subclass that you are using for your prototype view, declare a property called "selected" :

@property (readwrite) BOOL selected;

UPDATED CODE HERE: (added super call)

Subclass NSCollectionViewItem and override -setSelected:

- (void)setSelected:(BOOL)flag
{
    [super setSelected:flag];
    [(PrototypeView*)[self view] setSelected:flag];
    [(PrototypeView*)[self view] setNeedsDisplay:YES];
}

Then you need to add code in your prototype view's drawRect: method to draw the highlight:

- (void)drawRect:(NSRect)dirtyRect 
{
    if (selected) {
       [[NSColor blueColor] set];
       NSRectFill([self bounds]);
    }
}

That just simply fills the view in blue when its selected, but that can be customized to draw the highlight any way you want. I've used this in my own apps and it works great.

这篇关于选择突出显示在NSCollectionView中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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