2010-07-21 18 views
5

我要複製碼頭堆棧的背景網格和列表模式。背景是半透明的黑色模糊效果:套用CIFilter背景過濾器時,主窗口是透明

Example of dock stack in grid mode http://www.thecustommac.com/wp-content/uploads/2009/09/stack-highlight.jpg

的問題是,[CALayer的backgroundFilters]僅適用於內容在窗口中,將過濾器並不適用於其他窗口的內容。這是我的代碼:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    //make window transparent 
    self.window.backgroundColor = [NSColor clearColor]; 
    [self.window setOpaque:NO]; 
    [self.window setHasShadow:NO]; 
    [self.window setStyleMask:NSBorderlessWindowMask]; 


    //make the content view layer hosting 
    CALayer *rootLayer = [CALayer layer]; 
    [[self.window contentView] setLayer:rootLayer]; 
    [[self.window contentView] setWantsLayer:YES]; 


    //blur the background contents - NOT WORKING! 
    [rootLayer setBackgroundColor:CGColorCreateGenericGray(0.0, .716)]; 

    CIFilter *blurFilter = [CIFilter filterWithName:@"CIGaussianBlur"]; 
    [blurFilter setDefaults]; 
    [rootLayer setBackgroundFilters:[NSArray arrayWithObject: blurFilter]]; 
} 

我想不出如何實現這種效果。 (我看了顯示服務,看看是否有任何有用的功能,但我看不到任何。)

任何想法?

回答

9

這裏有私人API可用。以下是Rob Keniger的示例代碼:

在10.5中,您可以使用專用函數'CGSAddWindowFilter'將任何核心圖像過濾器添加到窗口。

typedef void * CGSConnectionID; 

extern OSStatus CGSNewConnection(const void **attr, CGSConnectionID *id); 

- (void)enableBlurForWindow:(NSWindow *)window 
{ 

CGSConnectionID _myConnection; 
uint32_t __compositingFilter; 

int __compositingType = 1; // Apply filter to contents underneath the window, then draw window normally on top 

/* Make a new connection to CoreGraphics, alternatively you could use the main connection*/ 

CGSNewConnection(NULL , &_myConnection); 

/* The following creates a new CoreImage filter, then sets its options with a dictionary of values*/ 

CGSNewCIFilterByName (_myConnection, (CFStringRef)@"CIGaussianBlur", &__compositingFilter); 
NSDictionary *optionsDict = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:3.0] forKey:@"inputRadius"]; 
CGSSetCIFilterValuesFromDictionary(_myConnection, __compositingFilter, (CFDictionaryRef)optionsDict); 

/* Now just switch on the filter for the window */ 

CGSAddWindowFilter(_myConnection, [window windowNumber], __compositingFilter, __compositingType); 
} 
+0

神奇,非常感謝你! – 2010-07-21 14:07:41

+0

FWIW,這不再顯示在優勝美地工作。 :-(CGSNewCIFilterByName()返回kCGErrorNotImplemented。 – 2014-10-25 03:26:20

1

你的代碼中有一些錯誤,這裏是剛剛工作的代碼:

typedef void * CGSConnection; 
extern OSStatus CGSNewConnection(const void **attributes, CGSConnection * id); 

-(void)enableBlurForWindow:(NSWindow *)window { 

    CGSConnection thisConnection; 
    NSUInteger compositingFilter; 
    NSInteger compositingType = 1 << 0; 

    // Make a new connection to Core Graphics 
    CGSNewConnection(NULL, &thisConnection); 

    // Create a Core Image filter and set it up 
    CGSNewCIFilterByName(thisConnection, (CFStringRef)@"CIGaussianBlur", &compositingFilter); 
    NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:2] forKey:@"inputRadius"]; 
    CGSSetCIFilterValuesFromDictionary(thisConnection, compositingFilter, (__bridge CFDictionaryRef)options); 

    // Apply the filter to the window 
    CGSAddWindowFilter(thisConnection, [window windowNumber], compositingFilter, compositingType); 
} 

然後,使用它:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 
    [_window setOpaque:NO]; 

    [_window setBackgroundColor: [NSColor colorWithCalibratedHue:0.568 saturation:0.388 brightness:0.941 alpha:0.6]]; 

    [self enableBlurForWindow:_window]; 
} 
+0

儘管我已經添加了CoreGraphics.framework和'#import「CoreGraphics/CoreGraphics.h」,但它不再適用於XCode7.1。代碼編譯失敗,因爲它找不到'CGSNewCIFilterByName','CGSSetCIFilterValuesFromDictionary'和'CGSAddWindowFilter'。我也有我的項目設置爲10.8 OSX上運行,但隨後改爲10.10 OSX,看看是否會編譯然後,和那也失敗了。 – Volomike 2015-12-31 01:40:59

1

過濾器不被使用的根層: 來自文檔:

/* An array of filters that are applied to the background of the layer. 
* The root layer ignores this property. Animatable. */ 

@property(copy) NSArray *backgroundFilters;