如何检查是否启用了“按钮形状”设置?

14

iOS 7.1新增了一个辅助功能设置项Button Shapes,会自动给一些按钮文本添加下划线。有没有办法检测这个模式,或者为单个UIButton自定义它呢?

(这是为了允许更改按钮标签,例如破折号或下划线,使其在加下划线时不会看起来像等于号等等.)


1
我自己没有找到任何东西,无论是在文档中还是在头文件中。我建议你提交一个雷达报告,这样我就可以复制它 ;) - David Rönnqvist
希望在下一个SDK发布时,苹果公司能够提供以下内容:UIKIT_EXTERN BOOL UIAccessibilityAreButtonShapesEnabled() NS_AVAILABLE_IOS(7_1); - dave
7个回答

5

从iOS 14开始,你可以使用 UIAccessibility.buttonShapesEnabled 或者 UIAccessibilityButtonShapesEnabled(),当设置启用时它们的值为true。


3

虽然这个问题比较老,但希望能对某些人有所帮助。目前iOS仍没有内置方法来检查按钮形状是否启用,因此我们添加了以下代码:

#pragma mark - Accessibility

/**
 * There's 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];
}

因为在应用程序运行时,如果按钮形状被禁用/启用,也没有任何通知。因此,在applicationDidBecomeActive:中运行checkIfButtonShapesEnabled,并在值发生变化时推送我们自己的通知。这应该适用于所有情况,因为目前无法将按钮形状切换添加到“辅助功能快捷方式”中。


1

我知道这是一个老问题,但这段代码确实有效。已在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's enabled for this button
                             }
                         }];

禁用特定按钮的按钮形状:
[btn.titleLabel.attributedText addAttribute: NSUnderlineStyleAttributeName value: @(0) range: NSMakeRange(0, [attributedText length])];

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;
}

1

我将this帖子中的代码转换为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中进行测试并可正常工作。

最初发布于我的问题:点击此处


0

我曾经遇到同样的问题,但没有找到官方解决方案。所以在苹果发布解决方案之前,我唯一找到的解决方法是将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”下方像素中是否有下划线。我知道如果苹果更改了UIToolbar的呈现方式,这很容易出问题。但也许这种方法可以得到改进,并且至少比没有强?抱歉,这不是一个好的解决方案,但我还没有找到更好的东西。


对于小型游戏/应用程序,这可能是一个合理的静态检查,但在大型项目中则不太适合和粗糙。不过还是一个不错的发现。 - Ńike Kamstra

0

这只是半相关的,但我会自己制作按钮形状,并通过设置菜单向用户提供选项。

很抱歉我的回答可能不完全符合问题,但这是我思考同样问题后得出的答案。

(示例始终使用半圆来实现圆角,不论大小,请根据您的需要进行修改)。

-(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;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接