Sonoma系统下NSMenuItem自定义字体keyEquivalent修饰符对齐异常求解
问题原因
Sonoma系统对NSMenuItem的文本渲染逻辑做了调整:当直接为attributedTitle设置自定义字体(如Kanit-Light)时,系统不会自动同步keyEquivalent(快捷键命令符号)的基线对齐属性,导致两者错位;而使用系统字体时,系统会统一处理标题与快捷键的布局匹配。
解决方法
方法1:直接设置NSMenuItem的font属性(推荐)
放弃设置attributedTitle,直接给菜单项目指定自定义字体,让系统自动处理标题和快捷键的对齐逻辑:
// 替换原attributedTitle设置代码 quitMenuItem.font = NSFont.settingsLightFont(withSize: 14.0)
这种方式会让系统保持标题文本与keyEquivalent的布局一致性,完全适配Sonoma的渲染规则。
方法2:修正attributedTitle的属性设置(若需保留复杂文本样式)
如果必须使用attributedTitle实现特殊文本样式,需显式添加基线对齐相关属性,确保自定义字体与系统快捷键符号的基线匹配:
let paraStyle: NSMutableParagraphStyle = NSMutableParagraphStyle() paraStyle.lineBreakMode = .byTruncatingTail paraStyle.alignment = .left // 显式设置对齐方式,与系统菜单默认一致 var titleAttributes: [NSAttributedString.Key : Any] = [ .font: NSFont.settingsLightFont(withSize:14.0), .paragraphStyle: paraStyle, .baselineOffset: 0 // 强制设置基线偏移,消除自定义字体的基线差异 ] quitMenuItem.attributedTitle = NSAttributedString( string: NSLocalizedString("Quit", comment: ""), attributes: titleAttributes )
方法3:自定义NSMenuItem子类重写绘制逻辑(极端场景)
如果上述方法都无效,可通过子类化NSMenuItem,重写drawKeyEquivalent(withFrame:in:)方法,手动调整keyEquivalent的绘制位置:
class CustomMenuItem: NSMenuItem { override func drawKeyEquivalent(withFrame frame: NSRect, in view: NSView) { // 调整frame的y坐标来修正对齐,根据自定义字体的基线差异计算偏移量 var adjustedFrame = frame adjustedFrame.origin.y += 1 // 示例偏移值,需根据实际字体调整 super.drawKeyEquivalent(withFrame: adjustedFrame, in: view) } }
使用时将nib中的NSMenuItem类改为CustomMenuItem即可。
内容的提问来源于stack exchange,提问作者Babitha shetty k
相关产品推荐
相关产品推荐

