选择突出显示在NSCollectionView
-
23-09-2019 - |
题
我有个工作 NSCollectionView
一个未成年人,但关键的,例外。得到并且突出显示选择的项目内收集。
我有这个工作之前雪豹,但一些似乎已经改变,我不能把我的手指就可以了,所以我拿了我的 NSCollectionView
回到一个基本的测试及随后的苹果的文件,用于创建一个NSCollectionView在这里:
该图集工作的现以下快速启动指南。然而,本指南不讨论选择的其他比 "There are such features as incorporating image views, setting objects as selectable or not selectable and changing colors if they are selected"
.
使用这个作为一个例子,我去下一个步骤的结合阵控制的 NSCollectionView
与关键控制器 selectionIndexes
, ,认为这会结合任何选择我之间的 NSCollectionView
和阵控制器,并因此发了韩国国际志愿者组织的通知。我也设置 NSCollectionView
要是可选择在IB。
似乎没有选择的委托 NSCollectionView
并不象大多数可可UI景,似乎没有默认选择的亮点。
所以我的问题真正涉及到一个相关的问题,但是两个不同的问题。
- 我怎么捕捉一种选择的一个项目?
- 我怎么展示一个突出的一个项目?
NSCollectionView
's编程指南似乎是少之又少,大多数通过谷歌搜索显示,拉起预雪豹的实现方式,或使用图在一个单独的XIB文件。
对于后者的(单独的XIB文件图),我看不出为什么这应该是一个先决条件,否则我会怀疑那苹果也不会有包含在同捆绑为收藏图项目。
我知道这将是一个"看不见树木不见森林"的问题-所以我准备"doh!"的时刻。
像往常一样,任何和所有帮助非常赞赏。
1更新
好的,所以我想找到所选项目(s),但还没有图的强调。为感兴趣的计算选定的项目(假设你是下的苹果指南):
在控制器(在我的测试情况下的应用程序托)我加入以下:
在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
{
// More than one selected - iterate if need be
}
}
}
不要忘记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
#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
解决方案
它不是太难做到的。确保"选择"的启用NSCollectionView在接口的建设者。然后在NSView子类,你使用的你的原型来看,宣布财产称为"选定的":
@property (readwrite) BOOL selected;
更新的代码这里:(增加超级呼叫)
类NSCollectionViewItem和复盖setSelected:
- (void)setSelected:(BOOL)flag
{
[super setSelected:flag];
[(PrototypeView*)[self view] setSelected:flag];
[(PrototypeView*)[self view] setNeedsDisplay:YES];
}
然后你需要添加码,在你的原型观的drawRect:方法绘制的突出显示:
- (void)drawRect:(NSRect)dirtyRect
{
if (selected) {
[[NSColor blueColor] set];
NSRectFill([self bounds]);
}
}
这只是简单地填补了查看在蓝色时它的选择,但可以定制的绘制的突出任何你想要的方式。我用这个在我自己的应用程序和它的伟大工程。
其他提示
如果不同背景的颜色就足够了作为一个亮点,你可以简单地使用NSBox作的根本项目为你收集项目图。填补NSBox与突出色的你的选择。设置NSBox以定义以便填补会的工作。设置NSBox到透明。
绑定的透明度属性的NSBox到选定的属性的文件所有者(收项目) 设定值的变压器的透明结合NSNegateBoolean.
我试图附加接口的建设者的截图,但我无论如何不能拒绝我是一个新手:-(
你也可以去的另一种方式,如果你不继承NSView你protoype图。
在你的子类NSCollectionViewItem复盖 setSelected:
- (void)setSelected:(BOOL)selected
{
[super setSelected:selected];
if (selected)
self.view.layer.backgroundColor = [NSColor redColor].CGColor;
else
self.view.layer.backgroundColor = [NSColor clearColor].CGColor;
}
当然,正如所说过的所有明智的人在我之前,确保"选择"的启用NSCollectionView在接口的建设者。
由于没有任何现有答复工作超好吧对我来说,这是我带上它。更改类别的CollectionView项SelectableCollectionViewItem.这里是它的代码。带有一个可绑定的文字颜色的财产挂钩你的文本的文字颜色的标签结合。
@implementation SelectableCollectionViewItem
+ (NSSet *)keyPathsForValuesAffectingTextColor
{
return [NSSet setWithObjects:@"selected", nil];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.wantsLayer = YES;
}
- (void) viewDidAppear
{
// seems the inital selection state is not done by Apple in a KVO compliant manner, update background color manually
[self updateBackgroundColorForSelectionState:self.isSelected];
}
- (void)updateBackgroundColorForSelectionState:(BOOL)flag
{
if (flag)
{
self.view.layer.backgroundColor = [[NSColor alternateSelectedControlColor] CGColor];
}
else
{
self.view.layer.backgroundColor = [[NSColor clearColor] CGColor];
}
}
- (void)setSelected:(BOOL)flag
{
[super setSelected:flag];
[self updateBackgroundColorForSelectionState:flag];
}
- (NSColor*) textColor
{
return self.selected ? [NSColor whiteColor] : [NSColor textColor];
}
在我的情况下,我想要一个像(检查标)来表示选择的对象。将ImageWell收集项目的笔尖。设置所需的图像和标记它作为隐藏。去绑定检查员和绑隐藏属性以收集的图项目。
(在我的情况下,我设立了一个单独的笔尖为CollectionViewItem,使其绑定文件的所有者。如果不是这种情况下,项目视为在同一笔作为CollectionView然后结合收集查看项目)
设的模型的关键路径 selected
和价值的变压器 NSNegateBoolean
.这就是它现在每当个体细胞/项目选定的图象将是可见的,因此指示的选择。
添加以改变的答复。
设置NSBox作为根本项目。只是创建一个新的文件IB(说CollectionItem)和拖NSBox的空区域。现在,添加所有的元素都作为需要方框内。现在按文件的所有者而设的自定义类 NSCollectionViewItem
.
和尖那里 NSCollectionView
加入变化的笔名 CollectionViewItem
在NSBox,结合剩余的元素 Files Owner
.对于一个标签,这将是类似的:
现在让亮的颜色 改变 提到在他的回答,设置所需的颜色组合在填补颜色的选择,设置 NSBox
以透明和绑定的透明度的属性如下:
现在,当收集查看项目被选中你应该能够看到填补颜色的箱子。
在你 NSCollectionViewItem
子类,复盖 isSelected
和变化的背景的颜色层。测试在mac os10.14和迅速的4.2
class Cell: NSCollectionViewItem {
override func loadView() {
self.view = NSView()
self.view.wantsLayer = true
}
override var isSelected: Bool {
didSet {
self.view.layer?.backgroundColor = isSelected ? NSColor.gray.cgColor : NSColor.clear.cgColor
}
}
}
这是真棒,非常感谢!我是在努力与这个!
以澄清对于其他人:
[(PrototypeView*)[self view] setSelected:flag];
[(PrototypeView*)[self view] setNeedsDisplay:YES];
替换PrototypeView*名称的原型类名称。
在你们周围挖的更新的迅速解决方案, 看到这种反应.
class MyViewItem: NSCollectionViewItem {
override var isSelected: Bool {
didSet {
self.view.layer?.backgroundColor = (isSelected ? NSColor.blue.cgColor : NSColor.clear.cgColor)
}
}
etc...
}
这里是完整的迅速NSCollectionViewItem用的选择。不要忘记,设置NSCollectioView可选择在IB或编程。测试下mac os莫哈韦(10.14)和高塞拉利昂(10.13.6).
import Cocoa
class CollectionViewItem: NSCollectionViewItem {
private var selectionColor : CGColor {
let selectionColor : NSColor = (isSelected ? .alternateSelectedControlColor : .clear)
return selectionColor.cgColor
}
override var isSelected: Bool {
didSet {
super.isSelected = isSelected
updateSelection()
// Do other stuff if needed
}
}
override func viewDidLoad() {
super.viewDidLoad()
view.wantsLayer = true
updateSelection()
}
override func prepareForReuse() {
super.prepareForReuse()
updateSelection()
}
private func updateSelection() {
view.layer?.backgroundColor = self.selectionColor
}
}