1

誰かが私に次のことがうまくいかない理由を教えてもらえますか?ボタンが選択に設定されることはありません。

[self.boldButton setSelected:isBold];

上記をifelseステートメントに置き換えると、正常に機能します。setSelectedの値をYESまたはNOではなく1または0に変更することもできますが、それでも正常に機能します。

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

ですから、私は作業中のプロジェクトを持っていますが、これら2つの実装が同じ結果をもたらさない理由がわかりません。ありがとう。

FWIW-別の方法で太字をテストします。テストに欠陥がある場合でも、2番目のアプローチがどのように機能するかはわかりませんが、最初のアプローチはまだ機能しません。

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

1 に答える 1

15

BOOLでこのように定義されてい<objc/objc.h>ます:

typedef signed char     BOOL;

つまり、aBOOLは実際には-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ホッパーでのシミュレーターバージョンを分解しました。)

したがって、2つのことに注意してください。

  • ステートメント条件は、またはifの場合にのみ真になります。他の値がある場合、それは決して真ではありません。selected == 0selected == 1selected

  • (更新する)代入ステートメント_controlFlagsは、のビット0(1のビット)のみを使用しますselected。したがって、たとえば、selected == -2Cで論理的に真であり、ビット0を除くすべてのビットが設定されている場合でも、代入ステートメントは。のビットをオンにしません_controlFlags

これは、に0または1を渡す必要があることを意味します-[UIControl setSelected:]。他の値は確実に機能しません。

Cでゼロ以外のすべての値を1に変換する最短の方法は、!演算子を2回適用することです。

[self.boldButton setSelected:!!isBold];

ただし、代わりに-isBold「安全」を返すようにメソッドを修正する方がおそらく良いでしょう。BOOL

- (BOOL)isBold {
    CTFontRef fontRef = (CTFontRef)CFBridgingRetain(self);
    CTFontSymbolicTraits symbolicTraits = CTFontGetSymbolicTraits(fontRef);
    return !!(symbolicTraits & kCTFontTraitBold);
}
于 2012-12-06T19:14:48.117 に答える