来自数组的随机颜色,用于不同的字符串

时间:2016-06-02 14:12:49

标签: objective-c random uikit uicolor arc4random

我想为不同的字符串选择随机数。以下示例与我的场景类似:

+ (UIColor *)ivl_randomColorWithSeedString:(NSString *)seedString {

    srand48(seedString ? seedString.hash : arc4random());

    float red = 0.0;
    while (red < 0.1 || red > 0.84) {
        red = drand48();
    }

    float green = 0.0;
    while (green < 0.1 || green > 0.84) {
        green = drand48();
    }

    float blue = 0.0;
    while (blue < 0.1 || blue > 0.84) {
        blue = drand48();
    }

    return [UIColor colorWithRed:red green:green blue:blue alpha:1.0f];
}

我想要实现的是为不同的字符串获取随机颜色,如果我有相同的字符串然后返回相同的索引。

- (void)setImageWithImage:(UIImage *)image orString:(NSString *)string colorArray:(NSArray *)colorArray circular:(BOOL)isCircular textAttributes:(NSDictionary *)textAttributes {
  if (!textAttributes) {
    textAttributes = @{
                       NSFontAttributeName: [self fontForFontName:nil],
                       NSForegroundColorAttributeName: [UIColor whiteColor]
                       };
  }

  NSMutableString *displayString = [NSMutableString stringWithString:@""];

  NSMutableArray *words = [[string componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] mutableCopy];

  //
  // Get first letter of the first and last word
  //
  if ([words count]) {
    NSString *firstWord = [words firstObject];
    if ([firstWord length]) {
      // Get character range to handle emoji (emojis consist of 2 characters in sequence)
      NSRange firstLetterRange = [firstWord rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, 1)];
      [displayString appendString:[firstWord substringWithRange:firstLetterRange]];
    }

    if ([words count] >= 2) {
      NSString *lastWord = [words lastObject];

      while ([lastWord length] == 0 && [words count] >= 2) {
        [words removeLastObject];
        lastWord = [words lastObject];
      }

      if ([words count] > 1) {
        // Get character range to handle emoji (emojis consist of 2 characters in sequence)
        NSRange lastLetterRange = [lastWord rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, 1)];
        [displayString appendString:[lastWord substringWithRange:lastLetterRange]];
      }
    }
  }

  srand48(string ? string.hash : arc4random());

  NSUInteger randomIndex = arc4random() % [colorArray count];
  UIColor *backgroundColor = colorArray[randomIndex];

  if (image != nil) {
    self.image = image;
  } else {
    self.image = [self imageSnapshotFromText:[displayString uppercaseString] backgroundColor:backgroundColor circular:isCircular textAttributes:textAttributes];
  }
}

这方面的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

使用arc4random您将无法实现这一目标。您需要使用随机数生成器random的种子版本,并使用来自字符串的值对其进行播种,这对于不同的字符串值将是唯一的。

这种生成的结果完全符合您的要求 - 对于相同的种子,生成的序列每次都完全相同。 对于不同的种子值,随机序列将不同。

例如,您可以将字符串长度作为种子,但为了使其更具可变性,您可以计算表示为int值的字符总数,或者您现在正在使用hash函数。

因此,在您的方法中,您应该在开头调用srandom(seed)并使用random代替arc4randomsrand48

我还为这样的场景编写了一个库,这在这里很有用:

https://github.com/grzegorzkrukowski/RandomUtils

要获得随机颜色,只需使用:

+ (void) setSeed:(unsigned)seed;
+ (UIColor*) randomColorUseSeed:(BOOL)useSeed

如果你想在数组中使用颜色并只采用其中一个索引,那么解决方案是相同的:

+ (void) setSeed:(unsigned)seed;
+ (id) randomElementFromArray:(NSArray*) array useSeed:(BOOL) useSeed;

setSeed的参数传递基于上述字符串生成的值。