NSSlider に似たカスタム コントロールがあるとしますが、単一の値ではなく、値の範囲の選択をサポートしているとします。プロパティの明らかな選択は、minValue、maxValue、leftValue、rightValue、または任意の名前です。
また、おそらく leftValue と rightValue が常に minValue と maxValue の間にあることを確認することもできます。minValue と maxValue についても同じです。たとえば、maxValue を現在の rightValue よりも低い値に設定するなどして、既存の leftValue と rightValue を潜在的に無効にすることは望ましくありません。
これまでのところかなり簡単です。
ただし、適切な KVO アクセシビリティ/コンプライアンスを確保する場合はどうしますか? KVO が適切な順序でプロパティを設定することを保証することはできません (つまり、最初に最小制限と最大制限を設定し、次に他の値を設定します)。
私はたまたまそのようなUI要素を持っていて、誤って設定された値のドアを開けずにこれを実行するために熱く理解することはできません.
カスタム コントロールは、モデル オブジェクトにバインドされることを意図しています。このようなモデルを値(最小: 0.00 最大: 42.00 左: 14.00 右: 28.00)で作成すると、カスタム コントロールで次のように設定されます(最小: 0.00 最大: 42.00 左: 1.00 右: 1.00)。
これは、minValue と maxValue を最初に呼び出す代わりに、leftValue と rightValue を最初に呼び出し、両方の値が 1.0 (デフォルトの maxValue) になるためです。(その後、maxValue が適切な値に設定されます。)
//[self prepare] gets called by both, [self initWithCoder:] and [self initWithFrame:]
- (void)prepare
{
minValue = 0.0;
maxValue = 1.0;
leftValue = 0.0;
rightValue = 1.0;
}
- (void)setMinValue:(double)aMinValue
{
if (aMinValue < maxValue && aMinValue < leftValue) {
minValue = aMinValue;
[self propagateValue:[NSNumber numberWithDouble:minValue] forBinding:@"minValue"];
[self setNeedsDisplay:YES];
}
}
- (void)setMaxValue:(double)aMaxValue
{
if (aMaxValue > minValue && aMaxValue > rightValue) {
maxValue = aMaxValue;
[self propagateValue:[NSNumber numberWithDouble:maxValue] forBinding:@"maxValue"];
[self setNeedsDisplay:YES];
}
}
- (void)setLeftValue:(double)aLeftValue
{
double newValue = leftValue;
if (aLeftValue < minValue) {
newValue = minValue;
} else if (aLeftValue > rightValue) {
newValue = rightValue;
} else {
newValue = aLeftValue;
}
if (newValue != leftValue) {
leftValue = newValue;
[self propagateValue:[NSNumber numberWithDouble:leftValue] forBinding:@"leftValue"];
[self setNeedsDisplay:YES];
}
}
- (void)setRightValue:(double)aRightValue
{
double newValue = leftValue;
if (aRightValue > maxValue) {
newValue = maxValue;
} else if (aRightValue < leftValue) {
newValue = leftValue;
} else {
newValue = aRightValue;
}
if (newValue != rightValue) {
rightValue = newValue;
[self propagateValue:[NSNumber numberWithDouble:rightValue] forBinding:@"rightValue"];
[self setNeedsDisplay:YES];
}
Apple が Cocoa のソースを公開していればよかったのにと思うのは、このようなときです。または、より詳細な検査のための少なくともいくつかのコントロール。
そのような制御をどのように実装しますか?
または、より一般的な: KVO に準拠しながら、相互に依存するプロパティを持つクラスを実装するためのベスト プラクティスは何ですか?