我有一个有投影的NSWindow,但它是黑暗的方式。影子传播得太远,对我来说太沉重了。它是NSWindow的默认阴影,我根本没有编辑它。
我想知道的是,是否有办法缩短模糊半径或降低阴影的沉重感,使其看起来更微妙。
谢谢!
答案 0 :(得分:1)
没有公共API,但您可以通过调用NSThemeFrame
上的某些方法来执行此操作(这是负责窗口框架,边框等的视图类)。
这是一个例子(NSWindow
的子类):
#import <objc/runtime.h>
@interface SOWindow : NSWindow
@end
@interface SOWindowThemeFrameOverrides : NSView
@end
@implementation SOWindow
+ (void)load
{
NSArray *methodsToOverride = @[@"_shadowOffset", @"_shadowFlags", @"_shadowType"];
for (NSString *selector in methodsToOverride) {
Method m = class_getInstanceMethod(NSClassFromString(@"NSThemeFrame"), NSSelectorFromString(selector));
Method m2 = class_getInstanceMethod([SOWindowThemeFrameOverrides class], NSSelectorFromString(selector));
class_addMethod(NSClassFromString(@"NSThemeFrame"), NSSelectorFromString([NSString stringWithFormat:@"_original%@", selector]), method_getImplementation(m), method_getTypeEncoding(m));
method_exchangeImplementations(m, m2);
}
}
@end
@implementation SOWindowThemeFrameOverrides
- (NSSize)_shadowOffset
{
if ([self.window isKindOfClass:[SOWindow class]]) {
return NSMakeSize(0, 8);
} else {
return [self _original_shadowOffset];
}
}
- (NSUInteger)_shadowFlags
{
if ([self.window isKindOfClass:[SOWindow class]]) {
return 0;
} else {
return [self _original_shadowFlags];
}
}
- (NSInteger)_shadowType
{
if ([self.window isKindOfClass:[SOWindow class]]) {
return 4;
} else {
return [self _original_shadowType];
}
}
#pragma mark Placeholder methods
- (NSSize)_original_shadowOffset
{
// implementation will be filled in at runtime
return NSZeroSize;
}
- (NSUInteger)_original_shadowFlags
{
// implementation will be filled in at runtime
return 0;
}
- (NSInteger)_original_shadowType
{
// implementation will be filled in at runtime
return 0;
}
@end
运行时加载SOWindow类时,将调用+ load
方法。该方法通过SOWindowThemeFrameOverrides
中的实现切换NSThemeFrame对3个影子方法的实现,同时将原始方法添加到具有_original
前缀的类中。
当调用swizzled方法时,我们检查窗口是否为SOWindow
,如果我们使用自定义阴影,如果不是我们将调用转发给原始实现。
这是我从4
:
_shadowType
所得到的
请注意,如果您尝试将其提交给AppStore,这可能会被拒绝。