按钮设置通过BOOL选择 [英] Button Set Selected via BOOL

查看:505
本文介绍了按钮设置通过BOOL选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可有人请教育我,为什么下面不工作?这个按钮永远不会被设置为选中状态。

  [self.boldButton的setSelected:isBold];

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

 如果(isBold)
{
    [self.boldButton的setSelected:YES];
}
其他
{
    [self.boldButton的setSelected:NO];
}

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

FWIW - 我测试用大胆的另一种方法。但如果测试是有缺陷的,我怎么看不到第二个方法可以工作,而第一个还是没有。

   - (BOOL)isBold
{
    CTFontRef fontRef =(CTFontRef)CFBridgingRetain(个体经营);
    CTFontSymbolicTraits symbolicTraits = CTFontGetSymbolicTraits(fontRef);
    返回(symbolicTraits&安培; kCTFontTraitBold);
}


解决方案

BOOL &LT的定义是这样的; objc / objc.h>

 的typedef签署的char BOOL;

这意味着 BOOL 通过127在-128实际上可以持有任何值(含)。

- [UIControl的setSelected:] 作品大致是这样的:

 的#define kSelectedBitPosition 10
的#define kSelectedBit(1 <<;&下; kSelectedBitPosition) - (无效)的setSelected:选择(BOOL){
    如果(((自&GT; _controlFlags&GT;&GT; kSelectedBitPosition)及1)==选择){
        返回;
    }其他{
        自&GT; _controlFlags =(自&GT; _controlFlags&安培;〜kSelectedBit)
            | ((选择&放大器; 1) - ;&下; kSelectedBitPosition);
        [自我setNeedsDisplay];
    }
}

(我拆开的UIKit 霍珀模拟器版本的数字,出。)

所以,注意两件事情:


  • 如果语句的条件只能是真,如果选择== 0 选择== 1 。如果为其他值它永远不会为真。


  • 赋值语句(即更新 _controlFlags )只使用选。因此,举例来说,如果选择== -2 ,这是逻辑真在C和有每一位设置的除了的位0,赋值语句仍然不会在 _controlFlags 对位开启。


这意味着您必须通过0或1 - [UIControl的setSelected:] 。没有其他的值将可靠地工作。

所有非零值转换为1 C语言中的最短途径是通过应用 操作符两次:!

  [self.boldButton的setSelected:!! isBold];

但是,它很可能是更好的解决您的 -isBold 方法返回一个安全的 BOOL 代替

   - (BOOL)isBold {
    CTFontRef fontRef =(CTFontRef)CFBridgingRetain(个体经营);
    CTFontSymbolicTraits symbolicTraits = CTFontGetSymbolicTraits(fontRef);
    返回!!(symbolicTraits&安培; kCTFontTraitBold);
}

Can someone please educate me why the following does not work? The button never gets set to selected.

[self.boldButton setSelected:isBold];

If I replace the above with an if else statement it works fine. I can also change the setSelected values to 1 or 0, instead of YES or NO and it still works fine.

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

So I have a working project, but I don't understand why these two implementations don't deliver the same results. Thanks.

FWIW - I test for bold with another method. Though if the test were flawed, I don't see how the second approach could work, while the first still doesn't.

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

解决方案

BOOL is defined like this in <objc/objc.h>:

typedef signed char     BOOL;

That means a BOOL can actually hold any value in the range -128 through 127 (inclusive).

-[UIControl setSelected:] works roughly like this:

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

(I disassembled the simulator version of UIKit with Hopper to figure that out.)

So, notice two things:

  • The if statement condition can only be true if selected == 0 or selected == 1. It will never be true if selected has any other value.

  • The assignment statement (that updates _controlFlags) only uses bit 0 (the 1's bit) of selected. So, for example, if selected == -2, which is logically true in C and has every bit set except bit 0, the assignment statement will still not turn on the bit in _controlFlags.

This means that you must pass 0 or 1 to -[UIControl setSelected:]. No other value will work reliably.

The shortest way to convert all non-zero values to 1 in C is by applying the ! operator twice:

[self.boldButton setSelected:!!isBold];

However, it would probably be better to fix your -isBold method to return a "safe" BOOL instead:

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

这篇关于按钮设置通过BOOL选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆