通过BOOLselectbutton组
有人可以教育我为什么以下不起作用? 该button从不被设置为选中状态。
[self.boldButton setSelected:isBold];
如果我用if else语句replace上面,它工作正常。 我也可以改变setSelected值为1或0,而不是YES或NO,它仍然正常工作。
if (isBold) { [self.boldButton setSelected:YES]; } else { [self.boldButton setSelected:NO]; }
所以我有一个工作项目,但我不明白为什么这两个实现不能提供相同的结果。 谢谢。
FWIW – 我用另一种方法进行粗体testing。 虽然如果testing是有缺陷的,我不明白第二种方法是可行的,而第一种方法不行。
- (BOOL)isBold { CTFontRef fontRef = (CTFontRef)CFBridgingRetain(self); CTFontSymbolicTraits symbolicTraits = CTFontGetSymbolicTraits(fontRef); return (symbolicTraits & kCTFontTraitBold); }
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]; } }
(我用Hopper反汇编了UIKit
的模拟器版本来弄清楚。)
所以,注意两点:
-
如果
selected == 0
或selected == 1
,if
语句条件只能为true。 如果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); }