gpt4 book ai didi

macos - 不使用 NSMatrix 的单选按钮

转载 作者:行者123 更新时间:2023-12-03 16:15:21 28 4
gpt4 key购买 nike

AppKit release notes for OS X 10.10 ,苹果写道:

Use of NSMatrix is informally deprecated. We expect to add the formal deprecation macros in a subsequent release, but its use is discouraged in the mean time. The primary use of NSMatrix is for radio button groups, so recall that for applications linked on 10.8 or later, radio buttons that share the same parent view and action will operate as a group.

这一切都很好,但是使用独立按钮时管理单选按钮组很烦人。

我搜索了其他人关于如何处理此问题的建议,以避免为每个按钮单独设置状态,找到选定的 radio 等,但找不到太多讨论。我想大多数人都在等待 Apple 正式弃用 NSMatrix,并希望提供更好的机制。

最佳答案

因此,为了回答我自己的问题,我在 DejalAppKitCategories open source project 中添加了一些方法为了让这件事变得更容易,我想我应该在这里分享给那些现在想要避免 NSMatrix 的人。

这是标题:

@interface NSButton (DejalRadios)

@property (nonatomic, setter=dejal_setRadiosEnabled:) BOOL dejal_radiosEnabled;

- (void)dejal_selectRadioWithTag:(NSInteger)tag;
- (NSInteger)dejal_selectedRadioTag;

- (NSButton *)dejal_radioPassingTest:(BOOL (^)(NSButton *radio, BOOL *stop))predicate;
- (void)dejal_enumerateRadiosUsingBlock:(void (^)(NSButton *radio, BOOL *stop))block;

@end

以及实现:

@implementation NSButton (DejalRadios)

/**
Assuming the receiver is a radio button, finds other radio buttons in the group (i.e. in the same superview and with the same action) and selects the one with the specified tag. Invoke this on any of the radios in the group. A replacement for -[NSMatrix selectCellWithTag:].

@param tag The tag value to select.

@author DJS 2015-01.
*/

- (void)dejal_selectRadioWithTag:(NSInteger)tag;
{
[self dejal_enumerateRadiosUsingBlock:^(NSButton *radio, BOOL *stop)
{
radio.state = radio.tag == tag;
}];
}

/**
Assuming the receiver is a radio button, finds other radio buttons in the group (i.e. in the same superview and with the same action) and returns the tag value of the selected radio. Invoke this on any of the radios in the group. A replacement for -[NSMatrix selectedTag].

@returns A tag value integer.

@author DJS 2015-01.
*/

- (NSInteger)dejal_selectedRadioTag;
{
NSButton *foundRadio = [self dejal_radioPassingTest:^BOOL(NSButton *radio, BOOL *stop)
{
return radio.state;
}];

return foundRadio.tag;
}

/**
Returns YES if the radio group is enabled, or NO if not. Simply returns the state of the receiver; the others are assumed to be the same. (If you want to know if they are all enabled or disabled, probably best to use -dejal_enumerateRadiosUsingBlock: to scan the group, and handle a mixed case as needed.)

@author DJS 2015-01.
*/

- (BOOL)dejal_radiosEnabled;
{
return self.enabled;
}

/**
Sets all of the radios in the group to be enabled or disabled. A replacement for -[NSMatrix setEnabled:].

@author DJS 2015-01.
*/

- (void)dejal_setRadiosEnabled:(BOOL)enabled;
{
[self dejal_enumerateRadiosUsingBlock:^(NSButton *radio, BOOL *stop)
{
radio.enabled = enabled;
}];
}

/**
Assuming the receiver is a radio button, finds other radio buttons in the group (i.e. in the same superview and with the same action) and performs the block for each of them, passing the radio to the block. Returns the one that returns YES, or nil if the block requests to stop before completion, or it completes without the block returning YES. Invoke this on any of the radios in the group.

@param block A block that takes a radio button and stop boolean reference as parameters and returns a boolean.
@returns The found radio button, or nil if none is found.

@author DJS 2015-01.
*/

- (NSButton *)dejal_radioPassingTest:(BOOL (^)(NSButton *radio, BOOL *stop))predicate;
{
for (NSButton *radio in self.superview.subviews)
{
// There's no reliable way to determine if a button is actually a radio button, but it's reasonable to assume that no non-radio will have the same action (and having the same action is what makes it a member of the group):
if ([radio isKindOfClass:[NSButton class]] && radio.action == self.action && predicate)
{
BOOL stop = NO;

if (predicate(radio, &stop))
{
return radio;
}

if (stop)
{
return nil;
}
}
}

return nil;
}

/**
Assuming the receiver is a radio button, finds other radio buttons in the group (i.e. in the same superview and with the same action) and performs the block for each of them, passing the radio to the block. Invoke this on any of the radios in the group.

@param block A block that takes a radio button and stop boolean reference as parameters and returns void.

@author DJS 2015-01.
*/

- (void)dejal_enumerateRadiosUsingBlock:(void (^)(NSButton *radio, BOOL *stop))block;
{
for (NSButton *radio in self.superview.subviews)
{
// There's no reliable way to determine if a button is actually a radio button, but it's reasonable to assume that no non-radio will have the same action (and having the same action is what makes it a member of the group):
if ([radio isKindOfClass:[NSButton class]] && radio.action == self.action && block)
{
BOOL stop = NO;

block(radio, &stop);

if (stop)
{
return;
}
}
}
}

@end

要使用这些方法,只需调用组中的任何 radio 即可,例如

[self.iconNoneRadio dejal_selectRadioWithTag:self.statusIconKind];
self.iconNoneRadio.dejal_radiosEnabled = use;

还有:

- (IBAction)chooseIcon:(id)sender;
{
self.statusIconKind = self.iconNoneRadio.dejal_selectedRadioTag;

[self maintainControls];
}

我希望这对其他人有帮助!当然,如果我遗漏了任何明显的内容,或者您​​有任何建议或意见,请告诉我。

关于macos - 不使用 NSMatrix 的单选按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28132253/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com