有没有人发现**合法**覆盖来自定义 NSTabView 的绘图?

Has anyone found **legal** overrides to customize drawing of NSTabView?

BGHUDAppKit BGHUDTabView _drawThemeTab private API 覆盖现已损坏

多年来,我一直在使用最初基于 BGHUDAppKit 的代码,并找到了 BGHUDAppKit 覆盖的所有私有 API 的替代品。

除了一个我可以不能找到一种方法来替换...

-[NSTabView _drawThemeTab:withState:inRect:]

(注意:我在很多情况下也使用古老的 PSMTabBarControl,所以如果一切都失败了,我会将我所有的选项卡视图转换为 PSMTabBarControl)

Apple 现在在 10.14 Mojave 中添加了深色 NSAppearance(所以在大约 10 年内,一旦我们停止支持 High Sierra,我就可以使用它)。

Apple 的任何自私的开发人员都认为 NSTabView 不相信让他的视图可定制,这与 all 其他可定制的 NSControls 不同。 这是 NSTabView 自定义绘图的部分 hackish 覆盖:

// until we can eliminate private API _drawThemeTab:, return nil for new NSAppearance
- (id) appearance { return nil; }
- (id) effectiveAppearance  { return nil; }

-(void)_drawThemeTab:(id) tabItem withState:(NSUInteger) state inRect:(NSRect) aRect {

    NSInteger idx = [self indexOfTabViewItem: tabItem];
    int gradientAngle = 90;
    NSBezierPath *path = nil;

    aRect = NSInsetRect(aRect, 0.5f, 0.5f);

    if([self tabViewType] == NSLeftTabsBezelBorder) {

        gradientAngle = 0;
    } else if([self tabViewType] == NSRightTabsBezelBorder) {

        gradientAngle = 180;
    }

   NSColor *specialFillColor = [tabItem color];
   NSColor *outlineColor = nil;
   NSString *name = [specialFillColor description];
   // MEC - added new prefix 12/15/17 to fix white border around last segment in High Sierra
   if ( [name hasPrefix:@"NSNamedColorSpace System"] || [name hasPrefix:@"Catalog color: System controlColor"])
      specialFillColor = nil;
   else if ( [name isEqualToString: @"NSCalibratedWhiteColorSpace 0 1"] )
      [specialFillColor set];
   else
   {
      outlineColor = specialFillColor;
      specialFillColor = nil;
   }
   ... etc ...

最好完全禁用 NSTabView 的绘图(将其 tabViewType 设置为 NSNoTabsNoBorder),并创建自定义分段条形视图以单独绘制选择(作为同级视图)。这允许您完全控制该自定义实现的外观、布局和大小,而不是依赖 NSTabView 的任何细节。

查看 NSTabViewController 的视图层次结构,您可以看到它通过使用 NSSegmentedControl 作为单独的子视图来管理来自 NSTabView 的选择,它具有相同的方法。