0

私はいくつかのものにNSGradientを使用していますが、ある時点で色を追加/変更/削除する必要があります。現在、NSGradientは私が知る限り不変であるため、これを行う方法を知る唯一の方法は、新しいグラデーションを作成し、プロセス内の色とその位置を変更することです。色を追加したり、色の位置を変更したりするためのこのアプローチには問題はありませんでしたが、色を削除すると何か奇妙なことが起こります。

インデックスが与えられているグラデーション「グラデーション」から色を削除する関数は次のとおりです。

- (void)_deleteColorAtIndex: (NSInteger)colorIndex
{
    if (!([self.gradient numberOfColorStops] > 2)) { return; }

    NSMutableArray* newColors = [NSMutableArray arrayWithCapacity: [self.gradient numberOfColorStops] - 1];
    CGFloat locations[[self.gradient numberOfColorStops] - 1];

    NSLog(@"Gradient before:");
    int i;
    for (i = 0; i < [self.gradient numberOfColorStops]; i++) {
        NSColor* color;
        CGFloat location;
        [self.gradient getColor: &color location: &location atIndex: i];
        NSLog(@" - Color: %@ / Location: %.2f", color, location);
    }

    //int i;
    NSLog(@"Adding this to new gradient:");

    // ----------------------------
    for (i = 0; i < [self.gradient numberOfColorStops]; i++) {
        NSColor* color;
        CGFloat location;
        [self.gradient getColor: &color location: &location atIndex: i];

        if (colorIndex != i) {
            [newColors addObject: color];
            locations[i] = location;
            NSLog(@" - Color: %@ / Location: %.2f", color, location);
        }
    }

    self.gradient = [[NSGradient alloc] initWithColors: newColors atLocations: locations colorSpace: [self.gradient colorSpace]];

    // ----------------------------        

    NSLog(@"Gradient after:");
    //int i;
    for (i = 0; i < [self.gradient numberOfColorStops]; i++) {
        NSColor* color;
        CGFloat location;
        [self.gradient getColor: &color location: &location atIndex: i];
        NSLog(@" - Color: %@ / Location: %.2f", color, location);
    }
}

重要なコードは、主に2つの「//----------------------------」のものの間にあります。残りはデバッグ目的のためだけです。


問題

このコードを|-white---- gray ----black-|のようなグラデーションで実行すると 2番目の色(灰色、colorIndex = 1)を削除してみてください。次のグラデーションが表示されます:| -whiteblack---------|。最後の色は0.0の位置にジャンプします。そのコードの印刷されたテキストは次のとおりです。

Gradient before:
- Color: NSCustomColorSpace Generic RGB colorspace 1 1 1 1 / Location: 0.00
- Color: NSCustomColorSpace Generic RGB colorspace 0.5 0.5 0.5 1 / Location: 0.50
- Color: NSCustomColorSpace Generic RGB colorspace 0 0 0 1 / Location: 1.00
Adding this to new gradient:
- Color: NSCustomColorSpace Generic RGB colorspace 1 1 1 1 / Location: 0.00
- Color: NSCustomColorSpace Generic RGB colorspace 0 0 0 1 / Location: 1.00 <- cool here
Gradient after:
- Color: NSCustomColorSpace Generic RGB colorspace 1 1 1 1 / Location: 0.00
- Color: NSCustomColorSpace Generic RGB colorspace 0 0 0 1 / Location: 0.00 <- disaster here

なぜこれが起こるのですか?まったく意味がありません!! (まあ、考えてみると、解決策が見つかるまでバグはほとんどありませんが、それでも...)。ありがとう!

4

1 に答える 1

4

この線

locations[i] = location;

間違っている。ここでiは、新しいカラー配列へのインデックスではなく、元のグラデーションへのインデックスです。他のソリューションの中で、あなたは使用することができます:

locations[[newColors count]-1] = location;

jまたは、newColors配列に追加するときにのみインクリメントする新しいインデックスカウンターを追加し、 locations:に割り当てるときにそのインデックスを使用します。

[newColors addObject:color];
locations[j++] = location;
于 2011-09-17T22:40:07.413 に答える