I implement a NSMenu with NSMenuItem and set custom view to it. When menu is scrollable, mouse hovering on ▼ button to scroll will cause some menuItem disappear (or not draw correctly). Hope someone give me some help. I will appreciate that.
Here's video about this issue: https://streamable.com/obrbon
Here's my code:
private func setupMenuItemView(_ menu: NSMenu) {
let menuItemHeight: CGFloat = 20
let menuWidth = frame.width
let textFieldPadding: CGFloat = 10
for menuItem in menu.items {
guard !menuItem.title.isEmpty else { continue }
let menuItemView = MenuItemView(frame: NSRect(x: 0, y: 0, width: Int(menuWidth), height: menuItemHeight))
let textField = MenuItemTextField(labelWithString: menuItem.title)
textField.frame = NSRect(
x: textFieldPadding,
y: (menuItemView.frame.height-textField.frame.height)/2,
width: menuWidth-textFieldPadding*2,
height: textField.frame.height
)
textField.lineBreakMode = .byTruncatingTail
menuItemView.addSubview(textField)
menuItemView.toolTip = menuItem.title
menuItem.view = menuItemView
menuItem.target = self
menuItem.action = #selector(onMenuItemClicked(_:))
}
}
fileprivate class MenuItemView: NSView {
override func mouseUp(with event: NSEvent) {
guard let menuItem = enclosingMenuItem else { return }
guard let action = menuItem.action else { return }
NSApp.sendAction(action, to: menuItem.target, from: menuItem)
menuItem.menu?.cancelTracking()
}
override func draw(_ dirtyRect: NSRect) {
guard let menuItem = enclosingMenuItem else { return }
if menuItem.isHighlighted {
NSColor.alternateSelectedControlColor.set()
} else {
NSColor.clear.set()
}
NSBezierPath.fill(dirtyRect)
super.draw(dirtyRect)
}
}
fileprivate class MenuItemTextField: NSTextField {
override var allowsVibrancy: Bool {
return false
}
}
After calling setupMenuItemView(), i call menu.popup().
Hope this information helps.