我的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;
}
}
Segment 4在awakeFromNib方法中附加了一个菜单。当用户点击细分时,我希望此菜单下拉。此时,只有当用户点击&按住菜单。从我的在线研究来看,这是因为关联行动。
我正在解决这个问题,通过使用一些代码来获取段控件的原点并使用NSMenu的popUpContextMenu:withEvent:forView
弹出上下文菜单,但这相当于hacktastic并且与标准行为相比看起来很糟糕将菜单下拉到分段控制单元下方。
有没有一种方法可以让菜单下拉,只需单击一下,而不是做hacky上下文菜单的事情?
答案 0 :(得分:17)
子类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];
}
}
答案 1 :(得分:4)
这是J Hoover的答案的Swift版本和Adam Treble的模型。覆盖不像我想象的那么直观,所以这有望帮助其他人。
override var action : Selector {
get {
if self.menuForSegment(self.selectedSegment) != nil {
return nil
}
return super.action
}
set {
super.action = newValue
}
}
答案 2 :(得分:3)
我不确定是否有任何内置方法(虽然它确实是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
它并不完美或理想,但它应该完成工作并提供用户期望的外观/行为。
(另外,NSSegmentedControl 真的需要-rectForSegment:
方法)
答案 3 :(得分:2)
widthForSegment:如果段自动调整大小,则返回零。如果您不关心未记录的API,则有一个rectForSegment:
但是要回答原始问题,让菜单立即弹出的更简单方法是继承NSSegmentedCell并返回0(再次,未记录)