2015-01-25 4 views
4

В AppKit release notes for OS X 10.10, Apple пишет:Радио кнопки без использования NSMatrix

Использование NSMatrix неофициально не рекомендуется. Мы ожидаем добавить формальные макросы устаревания в последующем выпуске, но его использование не рекомендуется в среднем. Основное использование NSMatrix - для групп переключателей, поэтому помните, что для приложений, связанных с 10.8 или новее, переключатели, которые имеют один и тот же родительский вид и действие, будут работать как группа.

Что все хорошо, но управление радиогруппой раздражает при использовании автономных кнопок.

Я искал предложения от других о том, как с этим обращаться, чтобы не устанавливать для каждой кнопки state для каждой кнопки отдельно, найти выбранную радиостанцию ​​и т. Д., Но не смогли найти много дискуссий об этом. Думаю, большинство людей ждет, пока Apple официально откажется от NSMatrix и, надеюсь, предоставит лучший механизм.

ответ

1

Итак, отвечая на мой вопрос, я добавил некоторые методы в мой 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 

Чтобы использовать эти методы, просто вызовите на любой из радиостанций в группе, например,

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

И:

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

    [self maintainControls]; 
} 

Я надеюсь, что это помогает другим! И, конечно, если мне не хватает ничего очевидного или у вас есть какие-либо предложения или комментарии, пожалуйста, дайте мне знать.

 Смежные вопросы

  • Нет связанных вопросов^_^