読者です 読者をやめる 読者になる 読者になる

NSBlogger

意識高いブログ

UIImageがベタ塗りされたときの対処法

UIImageがベタ塗りされる

ちゃんと画像を指定しているのに、真っ白になったり真っ黒になったり画像が1色でベタ塗りされたことがありました。そういえば、iOS7対応したときにいろんな画像が青色にベタ塗りされた記憶が…。ということで調べてみた結果が下記です。

UIImageの塗り方

iOS7から画像を指定した色でベタ塗りすることができるようになりました。
UIImageRenderingMode」というモードです。以下の3種類のモードがあります。

モード どうなるか
UIImageRenderingModeAlwaysOriginal 画像をそのまま利用
UIImageRenderingModeAlwaysTemplate 画像を指定した色でベタ塗りする
UIImageRenderingModeAutomatic クラスごとのデフォルト設定にしたがう

実際に各パターンについて設定して動作確認してみました。

UIImageRenderingModeAlwaysOriginal

    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    imageView.center = self.view.center;
    imageView.tintColor = [UIColor redColor];
    UIImage *image = [UIImage imageNamed:@"star"];
    image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    imageView.image = image;
    [self.view addSubview:imageView];

結果はこちら。
f:id:Kamekiti:20150401233435p:plain
画像がそのまま表示されました。

UIImageRenderingModeAlwaysTemplate

    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    imageView.center = self.view.center;
    imageView.tintColor = [UIColor redColor];
    UIImage *image = [UIImage imageNamed:@"star"];
    image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
    imageView.image = image;
    [self.view addSubview:imageView];

結果はこちら。
f:id:Kamekiti:20150401233540p:plain
UIImageViewのtintColorに設定した色でベタ塗りされました。透過が効いている部分はそのまま透過されています。アルファ値が50%など不透明な場合はベタ塗りの色もそれにあわせて透過されます。

UIImageRenderingModeAutomatic

    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    imageView.center = self.view.center;
    imageView.tintColor = [UIColor redColor];
    UIImage *image = [UIImage imageNamed:@"star"];
    image = [image imageWithRenderingMode:UIImageRenderingModeAutomatic];
    imageView.image = image;
    [self.view addSubview:imageView];

結果はこちら。
f:id:Kamekiti:20150401233740p:plain
そのまま画像が表示されました。これはUIImageViewの場合。
UISegmentedControlの場合はどうなるか試してみます。

    UIImage *image = [UIImage imageNamed:@"star"];
    image = [image imageWithRenderingMode:UIImageRenderingModeAutomatic];
    UISegmentedControl *segment = [[UISegmentedControl alloc] initWithItems:@[image, image]];
    segment.tintColor = [UIColor greenColor];
    segment.frame = CGRectMake(0, 0, 200, 100);
    segment.center = self.view.center;
    [self.view addSubview:segment];

結果はこちら。
f:id:Kamekiti:20150401233941p:plain
緑色にベタ塗りされました。UIImageViewでは画像がそのまま出ましたが、UISegmentedControlではベタ塗りで表示されています。これは、UIImageViewのデフォルト設定がUIImageRenderingModeAlwaysOriginal、UISegmentedControlではUIImageRenderingModeAlwaysTemplateであるためです。UITabbarやUINavigationControllerなどもベタ塗り設定がデフォルトのようです。

    UIImage *image = [UIImage imageNamed:@"star"];
    image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    UISegmentedControl *segment = [[UISegmentedControl alloc] initWithItems:@[image, image]];
    segment.tintColor = [UIColor greenColor];
    segment.frame = CGRectMake(0, 0, 200, 100);
    segment.center = self.view.center;
    [self.view addSubview:segment];

f:id:Kamekiti:20150401234440p:plain
このように明示的にUIImageRenderingModeAlwaysOriginalを指定してあげると、UISegmentedControlでも画像がそのまま表示されるようになりますよ。