OSX 10.10 Yosemite より NSTableView や NSOutlineView のselectionHighlightStyle を NSTableViewSelectionHighlightStyleSourceList に変えたときの見た目が以前とは別物になりました。
まあそれはいいのですが、Yosemite以前ではソースリストの下部などに表示するコントロールのコンテナはカスタムビュークラスを作りソースリストの背景色を拝借して描画していたのですが、Yosemiteでは NSVisualEffectView というクラスが用意されそれを利用するようになりました。
Yosemite以前もターゲットに入れているとOSXのバージョンによって差し替えるというアレな状態になってしまいました。
これはIBでペタペタが非常にやりにくい。
で、IBでペタペタ貼れてYosemite以前の実装にちょっと手を加えるだけですむ、ヒドイカスタムビューを作りました。
ヒドイけど動くからいいんです! 動くことが正義! コンパイラの警告もありません!
(Yosemiteで使用されるのは -initWithFrame:
のみです)
HMSourceListColoredView.h
# import <Cocoa/Cocoa.h>
@interface HMSourceListColoredView : NSView
@end
HMSourceListColoredView.m
# import "HMSourceListColoredView.h"
@interface HMSourceListColoredView ()
@property (strong, nonatomic) NSColor *backgroundColor;
@property (nonatomic, getter=isObservingKeyState) BOOL observingKeyState;
@end
@implementation HMSourceListColoredView
- (instancetype)initWithFrame:(NSRect)frameRect
{
// 使わなくてもイニシャライズはしないとダメです
self = [super initWithFrame:frameRect];
// NSVisualEffectView クラスがあればそのインスタンスを返す
if([NSVisualEffectView class]) {
NSVisualEffectView *view = [[NSVisualEffectView alloc] initWithFrame:frameRect];
return (HMSourceListColoredView *)view;
}
return self;
}
- (void)dealloc
{
if (self.isObservingKeyState) {
[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSWindowDidBecomeKeyNotification
object:[self window]];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSWindowDidResignKeyNotification
object:[self window]];
}
}
- (void)viewDidMoveToWindow
{
// NSTableViewを作ってその背景色を拝借する
NSTableView *tableView = [[NSTableView alloc] init];
[tableView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleSourceList];
_backgroundColor = [tableView backgroundColor];
[self addWindowKeyStateObservers];
}
- (void)addWindowKeyStateObservers
{
if (!self.isObservingKeyState) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(redisplay)
name:NSWindowDidBecomeKeyNotification
object:[self window]];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(redisplay)
name:NSWindowDidResignKeyNotification
object:[self window]];
}
self.observingKeyState = YES;
}
- (void)redisplay
{
[self setNeedsDisplay:YES];
}
- (void)drawRect:(NSRect)dirtyRect
{
[_backgroundColor setFill];
NSRectFill(dirtyRect);
}
@end