选择突出显示在NSCollectionView中 [英] Selection Highlight in NSCollectionView
问题描述
我有一个工作 NSCollectionView
有一个次要,但关键的异常。获取和突出显示集合中的所选项。
我已经在Snow Leopard之前工作,但是一些东西似乎已经改变,我不能放置我的手指上,所以我把我的 NSCollectionView
回到一个基本测试,并按照苹果的文档创建一个NSCollectionView这里:
快速入门指南后,集合视图效果很好。但是,本指南不讨论除之外的选择。有诸如合并图像视图,将对象设置为可选择或不可选择以及如果选择
时更改颜色等功能。
使用这个例子,我进入下一步将控制器绑定到 NSCollectionView
键 selectionIndexes
,认为这会绑定在 NSCollectionView
和数组控制器之间进行的任何选择,因此触发KVO通知。我还设置 NSCollectionView
在IB中可选。
似乎没有选择委托 NSCollectionView
并且与大多数Cocoa UI视图不同,似乎没有默认选择的高亮。
所以我的问题真的归结为
- 如何捕获某个项目的选择?
- 如何显示项目的突出显示?
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: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 keyselectionIndexes
, thinking that this would bind any selection I make between theNSCollectionView
and the array controller and thus firing off a KVO notification. I also set theNSCollectionView
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.
- How do I capture a selection of an item?
- 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屋!