Jus*_*ams 7 macos usability cocoa controls
我的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;
}
}
Run Code Online (Sandbox Code Playgroud)
段4在awakeFromNib方法中附加了一个菜单.当用户点击细分时,我希望此菜单下拉.此时,只有当用户点击并按住菜单时,它才会下降.从我的在线研究来看,这是因为关联行动.
我现在通过使用一些代码来获取段控件的原点并使用NSMenu弹出上下文菜单来解决这个问题,popUpContextMenu:withEvent:forView
但是相比于将菜单下拉到分段下方的标准行为,这是非常hacktastic并且看起来很糟糕对照细胞.
有没有一种方法可以让菜单下拉,因为它应该单击一下,而不是做hacky上下文菜单的事情?
小智 19
子类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];
}
}
Run Code Online (Sandbox Code Playgroud)
我不确定是否有任何内置方法可以做到这一点(尽管它确实是 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
Run Code Online (Sandbox Code Playgroud)
它不是完美或理想的,但它应该可以完成工作并提供用户期望的外观/行为。
(顺便说一句,NSSegmentedControl确实需要一个-rectForSegment:
方法)
这是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
}
}
Run Code Online (Sandbox Code Playgroud)