NSGradient 删除颜色的问题 - Cocoa/Objective-C

发布于 2024-12-05 01:33:54 字数 2781 浏览 0 评论 0原文

我正在使用 NSGradient 来处理一些东西,有时我需要添加/更改/删除颜色。现在据我所知,NSGradient 是不可变的,所以我知道如何做到这一点的唯一方法是创建一个新的渐变并在过程中更改颜色及其位置。我对这种添加颜色和更改颜色位置的方法没有任何问题,但删除颜色时会发生一些奇怪的事情。

这是从给定索引的渐变“gradient”中删除颜色的函数:

- (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);
    }
}

重要的代码主要在两个“// --------------------- 之间--------”的东西。其余的仅用于调试目的。


问题

当我使用 |-white----gray----black-| 之类的渐变运行此代码时并尝试删除第二种颜色(灰色,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

为什么会发生这种情况???根本没有任何意义!! (好吧,想想看,在找到解决方案之前几乎没有错误,但仍然......)。谢谢!

I'm using an NSGradient for some stuff and at some point I need to add/change/delete colors. Now NSGradient is immutable as far as I know so the only way I know how to do this is by creating a new gradient and changing the colors and their locations in the process. I have had no problem with this approach for adding colors and for changing the colors' position but for deleting colors something weird happens.

Here's the function that deletes a color from the gradient 'gradient' being given its index:

- (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);
    }
}

The important code is mainly between the two "// ----------------------------" thingies. The rest is just for debugging purposes.


The problem

When I run this code with a gradient like |-white----gray----black-| and try to delete the second color (gray, colorIndex = 1) I get this gradient: |-whiteblack---------|. The last color jumps to position 0.0. Here's the printed text of that code:

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

Why does this happen??? It makes no sense at all!! (well, come to think of it, almost no bug does until you have found the solution, but still....). Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

朕就是辣么酷 2024-12-12 01:33:54

线路

locations[i] = location;

不正确。这里,i 是原始渐变的索引,而不是新颜色数组的索引。在其他解决方案中,您可以使用:

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

或者仅添加一个新的索引计数器 j,仅在添加到 newColors 数组时递增,并在分配给 locations 时使用该索引:

[newColors addObject:color];
locations[j++] = location;

The line

locations[i] = location;

is incorrect. Here, i is index into the original gradient rather than the index into the new color array. Among other solutions, you could use:

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

or just add a new index counter j that you increment only when adding to the newColors array, and use that index when assigning to locations:

[newColors addObject:color];
locations[j++] = location;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文