Как проверить, включен ли параметр "Формы кнопок"?

iOS 7.1 включает новую настройку Специальные возможности, которая вызывает Формы кнопок, что приводит к автоматическому подчеркиванию текста некоторых кнопок. Есть ли способ обнаружить этот режим или настроить его для отдельных UIButton?

(Это позволяет изменять метки кнопок, такие как тире или подчеркивание, чтобы при подчеркивании они не выглядели как знак равенства и т.д.)

Ответ 1

Похоже, вы можете запросить атрибуты метки кнопки и проверить, содержит ли он атрибут NSUnderlineStyleAttributeName. Если вы удалите атрибут NSUnderlineStyleAttributeName, система вернет его обратно, поэтому кажется, что трюк заключается в том, чтобы явно установить атрибут подчеркивания метки равным 0. Я добавил следующее к моей настраиваемой кнопке:

- (void) adjustLabelProperties  // override underline attribute
{
    NSMutableAttributedString   *attributedText = [self.titleLabel.attributedText mutableCopy];

    [attributedText addAttribute: NSUnderlineStyleAttributeName value: @(0) range: NSMakeRange(0, [attributedText length])];
    self.titleLabel.attributedText = attributedText;
}

Ответ 2

Я знаю, что это старый вопрос, но этот код работает. Протестировано в iOS 9.3

NSMutableAttributedString *attrStr = [btn.titleLabel.attributedText mutableCopy];
[attrStr enumerateAttributesInRange:NSMakeRange(0, [attrStr length])
                            options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired
                         usingBlock:^(NSDictionary *attributes, NSRange range, BOOL *stop) {
                             NSMutableDictionary *mutableAttributes = [NSMutableDictionary dictionaryWithDictionary:attributes];
                             if([mutableAttributes objectForKey:NSUnderlineStyleAttributeName] != nil) {
                                 //It enabled for this button
                             }
                         }];

Чтобы отключить формы кнопок для определенной кнопки

[btn.titleLabel.attributedText addAttribute: NSUnderlineStyleAttributeName value: @(0) range: NSMakeRange(0, [attributedText length])];

Ответ 3

Старый вопрос, но, надеюсь, это кому-нибудь поможет. Там все еще нет встроенного метода для проверки того, включена ли форма кнопок на iOS, поэтому мы добавили это:

#pragma mark - Accessibility

/**
 * There currently no built-in way to ascertain whether button shapes is enabled.
 * But we want to manually add shapes to certain buttons when it is.
 */

static BOOL _accessibilityButtonShapesEnabled = NO;

+ (BOOL)accessibilityButtonShapesEnabled {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        [self checkIfButtonShapesEnabled];
    });

    return _accessibilityButtonShapesEnabled;
}

+ (void)checkIfButtonShapesEnabled {
    UIButton *testButton = [[UIButton alloc] init];
    [testButton setTitle:@"Button Shapes" forState:UIControlStateNormal];

    _accessibilityButtonShapesEnabled = (BOOL)[(NSDictionary *)[testButton.titleLabel.attributedText attributesAtIndex:0 effectiveRange:nil] valueForKey:NSUnderlineStyleAttributeName];
}

Поскольку также нет уведомлений о том, что формы кнопок отключены/включены во время работы приложения, мы запускаем checkIfButtonShapesEnabled в applicationDidBecomeActive: и checkIfButtonShapesEnabled собственное уведомление, если значение изменилось. Это должно работать во всех случаях, потому что в настоящее время невозможно добавить переключатель "Формы кнопок" в "Ярлык специальных возможностей".

Ответ 4

У меня была такая же проблема, и я не нашел официального решения. Таким образом, единственное обходное решение, которое я нашел, пока Apple не выпустит решение, - это сделать UIToolbar в изображении и проверить, подчеркнута ли кнопка:

+ (BOOL)isUsesButtonShapes {
    BOOL result = FALSE;

    CGRect rect = CGRectMake(0, 0, 320, 44);
    CGPoint point = CGPointMake(26, 33);

    UIToolbar *toolbar = [[[UIToolbar alloc] initWithFrame:rect] autorelease];
    toolbar.backgroundColor = [UIColor whiteColor];
    toolbar.tintColor = [UIColor darkGrayColor];
    toolbar.barTintColor = [UIColor whiteColor];
    [toolbar setItems:@[[[[UIBarButtonItem alloc] initWithTitle:@"Test" style:UIBarButtonItemStyleBordered target:nil action:nil] autorelease]]];
    toolbar.barStyle = UIBarStyleDefault;
    toolbar.translucent = FALSE;

    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    [toolbar.layer renderInContext:context];

    int bpr = CGBitmapContextGetBytesPerRow(context);
    unsigned char *data = CGBitmapContextGetData(context);
    if (data != NULL) {
        int offset = (int) (bpr * point.y + 4 * point.x);
        int blue = data[offset + 0];

        result = blue < 250;
    }

    UIGraphicsEndImageContext();

    return result;
}

В основном это отображает UIToolbar в изображение:

Rendered UIToolbar

Затем он проверяет, есть ли подчеркивание в пикселе под "T". Я знаю, что это может легко сломаться, если Apple изменит способ визуализации UIToolbar. Но, может быть, этот метод можно улучшить и, по крайней мере, лучше, чем ничего? Извините, это нехорошее решение, но я пока не нашел ничего лучшего.

Ответ 5

Это только полусвязанные, но я вроде как "roll my own" для форм Button и делаю опцию доступной пользователю через меню настроек.

Прошу прощения за то, что я не "спот" на вопрос, но это то, о чем я в конечном итоге подумал о том же вопросе.

(Этот пример настроен так, чтобы всегда использовать полукруг для закругленных углов независимо от размера - пожалуйста, измените, как вы пожелаете).

-(void)setBorderForButton:(UIButton*)theButton withSetting:(BOOL)theSetting{
    if (theSetting == YES){
        theButton.layer.cornerRadius = theButton.frame.size.height/2;
        theButton.layer.borderWidth = 1;
        theButton.layer.borderColor = [UIColor yourDesiredColor].CGColor;
        theButton.clipsToBounds = YES;
    }
}

Ответ 6

Я преобразовал код из этого поста в Swift (4.2):

import UIKit

public extension UIAccessibility {

    public static var isButtonShapesEnabled: Bool {
        let button = UIButton()
        button.setTitle("Button Shapes", for: .normal)
        return button.titleLabel?.attributedText?.attribute(NSAttributedString.Key.underlineStyle, at: 0, effectiveRange: nil) != nil
    }

}

Использование:

if UIAccessibility.isButtonShapesEnabled {
    // Apply button shapes style to custom button...
}

Протестировано и работает в iOS 12.

Первоначально опубликовано на мой собственный вопрос: нажмите