[英]Show NSSegmentedControl menu when segment clicked, despite having set action
[英]Show NSSegmentedControl menu when segment clicked, despite having set action
我的UI上有一個帶有4個按鈕的NSSegmentedControl。 控件連接到一個方法,該方法將根據單擊的段來調用不同的方法:
- (IBAction)performActionFromClick:(id)sender {
NSInteger selectedSegment = [sender selectedSegment];
NSInteger clickedSegmentTag = [[sender cell] tagForSegment:selectedSegment];
switch (clickedSegmentTag) {
case 0: [self showNewEventWindow:nil]; break;
case 1: [self showNewTaskWindow:nil]; break;
case 2: [self toggleTaskSplitView:nil]; break;
case 3: [self showGearMenu]; break;
}
}
段4在awakeFromNib方法中附加了一個菜單。 我希望用戶單擊細分時此菜單下拉。 此時,只有在用戶單擊並按住菜單時,它才會掉落。 根據我的在線研究,這是因為存在關聯行為。
我目前正在通過使用一些代碼來獲取段控件的原點並使用NSMenu的popUpContextMenu:withEvent:forView
彈出上下文菜單的方法來解決此popUpContextMenu:withEvent:forView
但這很hacktastic,與具有菜單的標准行為相比,它看起來很糟糕下拉到分段的控制單元下方。
有沒有一種方法可以使菜單一次單擊就可以下拉菜單,而不需要執行駭人的上下文菜單操作?
子類NSSegmentedCell,在下面覆蓋方法,並替換IB中的單元格類。 (不需要私有API)。
- (SEL)action
{
//this allows connected menu to popup instantly (because no action is returned for menu button)
if ([self tagForSegment:[self selectedSegment]]==0) {
return nil;
} else {
return [super action];
}
}
這是J Hoover的答案的Swift版本和Adam Treble的mod版本。 覆蓋不如我想象的那樣直觀,因此希望可以對其他人有所幫助。
override var action : Selector {
get {
if self.menuForSegment(self.selectedSegment) != nil {
return nil
}
return super.action
}
set {
super.action = newValue
}
}
我不確定執行此操作的任何內置方法(盡管它確實是NSSegmentedControl API中的一個明顯漏洞)。
我的建議是繼續執行您正在做的事情,彈出上下文菜單。 但是,不僅可以使用分段控件的原點,還可以通過執行以下操作將其直接定位在該段下(如您所願):
NSPoint menuOrigin = [segmentedControl frame].origin;
menuOrigin.x = NSMaxX([segmentedControl frame]) - [segmentedControl widthForSegment:4];
// Use menuOrigin where you _were_ just using [segmentedControl frame].origin
它不是完美或理想的,但它應該完成工作並提供用戶期望的外觀/行為。
(順便說 -rectForSegment:
,NSSegmentedControl 確實需要-rectForSegment:
方法)
widthForSegment:如果分段自動調整大小,則返回零。 如果您不關心未記錄的API,則可以使用rectForSegment:
但是要回答最初的問題,讓菜單立即彈出的一種更簡便的方法是將NSSegmentedCell子類化,並返回0(同樣,未記錄)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.