繁体   English   中英

禁止自动处理 NSButton 单选按钮组

[英]Suppress automatic handling of NSButton radio button groups

我正在开发一个在 macOS 和 Windows 中运行的跨平台动态对话框构建器。 我继承了这个代码库。 我正在尝试支持单选按钮。 问题是 macOS 会自动将所有单选按钮视为一个组,如果它们共享相同的超级视图和相同的操作选择器。 此代码对所有按钮使用一个动作选择器,并且所有控件只有一个超级视图。 因此,一组单选按钮就像魔术一样工作,但在 window 上没有办法拥有多个单选按钮。

我正在寻找有关如何处理的建议。

  • 有没有办法抑制NSButtonStyleRadio的自动行为?
  • 有没有办法动态创建指向相同代码的选择器? (见下文。)

一个骇人的解决方案可能是构建一些单选按钮选择器方法,然后在 window 上不允许超过那么多组。 它看起来像这样:


- (IBAction)buttonPressed:(id)sender // this is the universal NSButton action
{
    if (!_pOwner) return; // _pOwner is a member variable pointing to a C++ class that handles most of the work
    int tagid = (int) [sender tag];
    _pOwner->Notify_ButtonPressed(tagid);
}

- (IBAction)radioButtonGroup1Pressed:(id)sender
{
    if (_pOwner)
        [(id)_pOwner->_GetInstance() buttonPressed:sender];
}

- (IBAction)radioButtonGroup2Pressed:(id)sender
{
    if (_pOwner)
        [(id)_pOwner->_GetInstance() buttonPressed:sender];
}

- (IBAction)radioButtonGroup3Pressed:(id)sender
{
    if (_pOwner)
        [(id)_pOwner->_GetInstance() buttonPressed:sender];
}

- (IBAction)radioButtonGroup4Pressed:(id)sender
{
    if (_pOwner)
        [(id)_pOwner->_GetInstance() buttonPressed:sender];
}

此示例将允许 window 上最多 4 个按钮组,并且我可以跟踪我使用了哪些按钮组。 但我真的很想避免以这种方式对其进行硬编码。 有没有办法动态地做到这一点? 或者同样可以,完全禁用自动行为?

简而言之,问题是在编译时无法知道NSWindowController class 需要多少个方法用于单选按钮组。 所以解决方案是在运行时根据需要添加新方法。

我的代码有一个 window controller 部分声明如下。

@implementation MyWindowController : NSWindowController

- (IBAction)buttonPressed:(id)sender; // universal button action for all button controls
.
.
.

@end

When the program creates the window, it assigns a new window controller to the window and then creates all the controls on the window. 对于每个控件,它会根据需要分配一个操作和/或通知监视器。 对于单选按钮组,而不是将按钮直接分配给buttonPressed: ,它们可以通过根据需要创建的按钮组特定方法进行路由。

// groupId: the integer id of the group on the window. (Mine counts from 1, but it doesn't matter.)
// button: the NSButton control being created.

SEL mySelector = NSSelectorFromString([NSString stringWithFormat:@"radioButtonGroup%dPressed:", groupId]);
class_addMethod([MyWindowController class], mySelector, (IMP)_radioButtonGroupPressed, "v@:@");
[button setAction:mySelector];

如果 Objective-C++ 允许将 lambda 转换为(IMP) ,我会使用 lambda 作为方法,但我使用的是 static ZC1C425268E68385D1ABZ5074C17A94F1。

// If class_addMethod allowed lambdas, this would be a lambda in the call to class_Method below.
static void _radioButtonGroupPressed(id self, SEL, id sender)
{
    [self buttonPressed:sender];
}

NSSelectorFromString允许创建任意选择器名称,而class_addMethod允许将其附加到代码中。 如果选择器已经被添加, class_addMethod什么都不做。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM