按钮设置通过BOOL选择

时间:2012-12-06 18:44:49

标签: ios uibutton boolean

有人可以教育我为什么以下不起作用?该按钮永远不会被设置为选中。

[self.boldButton setSelected:isBold];

如果我用if else语句替换上面的内容,它可以正常工作。我也可以将setSelected值更改为1或0,而不是YES或NO,它仍然可以正常工作。

if (isBold)
{
    [self.boldButton setSelected:YES];
}
else
{
    [self.boldButton setSelected:NO];
}

所以我有一个工作项目,但我不明白为什么这两个实现不能提供相同的结果。感谢。

FWIW - 我用另一种方法测试粗体。虽然如果测试有缺陷,我看不出第二种方法是如何工作的,而第一种方法仍然没有。

- (BOOL)isBold
{
    CTFontRef fontRef = (CTFontRef)CFBridgingRetain(self);
    CTFontSymbolicTraits symbolicTraits = CTFontGetSymbolicTraits(fontRef);
    return (symbolicTraits & kCTFontTraitBold);
}

1 个答案:

答案 0 :(得分:15)

BOOL<objc/objc.h>中定义如下:

typedef signed char     BOOL;

这意味着BOOL实际上可以保留-128到127(含)范围内的任何值。

-[UIControl setSelected:]大致如下:

#define kSelectedBitPosition 10
#define kSelectedBit (1 << kSelectedBitPosition)

- (void)setSelected:(BOOL)selected {
    if (((self->_controlFlags >> kSelectedBitPosition) & 1) == selected) {
        return;
    } else {
        self->_controlFlags = (self->_controlFlags & ~kSelectedBit)
            | ((selected & 1) << kSelectedBitPosition);
        [self setNeedsDisplay];
    }
}

(我将UIKit的模拟器版本与Hopper一起反汇编,以明白这一点。)

所以,请注意两件事:

  • if语句条件只有selected == 0selected == 1才能生效。如果selected具有任何其他值,则永远不会成立。

  • 赋值语句(更新_controlFlags)仅使用selected的第0位(1位)。因此,例如,如果selected == -2在C中逻辑上为真并且每个位都设置为,除了位0,则赋值语句仍然不会打开_controlFlags中的位

这意味着您必须将0或1 传递给-[UIControl setSelected:]。没有其他价值可靠地发挥作用。

在C中将所有非零值转换为1的最短方法是应用!运算符两次:

[self.boldButton setSelected:!!isBold];

但是,最好修改-isBold方法以返回“安全”BOOL

- (BOOL)isBold {
    CTFontRef fontRef = (CTFontRef)CFBridgingRetain(self);
    CTFontSymbolicTraits symbolicTraits = CTFontGetSymbolicTraits(fontRef);
    return !!(symbolicTraits & kCTFontTraitBold);
}