Использование цвета оттенка в UIImageView

118

У меня есть собственный подкласс UIButton. Я добавляю UIImageViewи добавляю изображение. Я хотел бы закрасить изображение оттенком, но это не работает.

Пока у меня есть:

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {

        self.backgroundColor = [UIColor clearColor];
        self.clipsToBounds = YES;

        self.circleView = [[UIView alloc]init];
        self.circleView.backgroundColor = [UIColor whiteColor];
        self.circleView.layer.borderColor = [[Color getGraySeparatorColor]CGColor];
        self.circleView.layer.borderWidth = 1;
        self.circleView.userInteractionEnabled = NO;
        self.circleView.translatesAutoresizingMaskIntoConstraints = NO;
        [self addSubview:self.circleView];

        self.iconView = [[UIImageView alloc]init];
        [self.iconView setContentMode:UIViewContentModeScaleAspectFit];
        UIImage * image = [UIImage imageNamed:@"more"];
        [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
        self.iconView.image = image;
        self.iconView.translatesAutoresizingMaskIntoConstraints = NO;
        [self.circleView addSubview:self.iconView];
        ...

и по выбору:

- (void) setSelected:(BOOL)selected
{
    if (selected) {
        [self.iconView setTintColor:[UIColor redColor]];
        [self.circleView setTintColor:[UIColor redColor]];
    }
    else{
        [self.iconView setTintColor:[UIColor blueColor]];
        [self.circleView setTintColor:[UIColor blueColor]];
    }  
}

Что я сделал не так? (Цвет изображения всегда остается таким же, каким был изначально.)

Марко Задравец
источник
вы можете это сделать, setTintColorкогда создаете iconView ?
Химаншу Джоши
1
вы имеете в виду после self.iconView = [UIImageView alloc] ...? Да, могу, но не работает.
Marko Zadravec
Тогда используйте CGContext. Может быть, вы можете найти свой ответ здесь stackoverflow.com/a/19275079/1790571
Химаншу Джоши
Да, я вижу этот пост, но действительно не понимаю, почему мой код не работает. Использование оттенка - гораздо более чистый путь.
Marko Zadravec

Ответы:

237

Вместо этого кода:

[image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];

у вас должно быть:

image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];

Используйте это в Swift 4.1

image = UIImage(named: "name")!.withRenderingMode(.alwaysTemplate)
Марко Задравец
источник
9
Не глупая ошибка, а очень важная деталь. Спасибо, что разместили это. Вы только что сэкономили мне много времени. (исправленная опечатка)
Alex Zavatone
47
Вы можете выбрать изображение в активах и выбрать в правой панели режим рендеринга по умолчанию
Николай Шубенков
Превосходно! Но как вернуться к исходному не тонированному изображению?
Marsman
Если вы хотите получить не тонированное изображение, вы можете: сохранить тонированное изображение в другой переменной: UIImage image2 = [image imageWithR ....], или вы можете снова загрузить изображение из файла: image = [UIImage imageNamed: @ "more" ];
Марко Задравец
89

Вы также можете просто установить это на своем активе. Убедитесь, что ваше изображение содержит все белые + прозрачные пиксели. введите описание изображения здесь

StackUnderflow
источник
6
Я все это делал, но у меня почему-то tintColor не работает. Есть идеи, что еще я могу попробовать?
Banana
1
Какой формат изображения вы используете? И изображение все белое + альфа?
StackUnderflow
3
Как ни странно, в моих первых двух прогонах только 2/3 изображения получали оттенок. После очистки и сборки все изображения приобрели оттенок.
MathewS
Может быть, вы могли бы сообщить об этом в Apple?
StackUnderflow
11
@Banana, это известная проблема изображений, в которых не используется оттенок. Некоторое время назад я сообщил об этом в Apple, и они пометили его как дубликат, чтобы точно знать об этом. Обходной путь - не устанавливать в UIImageView изображение в раскадровке. Так что просто создайте пустой UIImageView, а затем установите его в viewDidLoad (или где-нибудь еще), и тогда вы увидите tintColor на изображении.
Марк Мойкенс
38

(Не могу редактировать сообщение @Zhaolong Zhong)

В Swift 3.0 вы можете:

let image = UIImage(named: "your_image_name")!.withRenderingMode(.alwaysTemplate)

yourImageView.image = image

yourImageView.tintColor = UIColor.blue
odemolliens
источник
19

В Swift 2.0+ вы можете:

let image = UIImage(named: "your_image_name")!.imageWithRenderingMode(.AlwaysTemplate)

yourImageView.image = image

yourImageView.tintColor = UIColor.blueColor()
Чжаолун Чжун
источник
11

Быстрая версия: 5.2

let tintableImage = UIImage(named: "myImage")?.withRenderingMode(.alwaysTemplate)
imageView.image = tintableImage
imageView.tintColor = UIColor.red

Цель C

self.imgView.image = [self.imgView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[self.imgView setTintColor:[UIColor darkGrayColor]];

Или

Вы также можете просто установить это на своем активе.

введите описание изображения здесь

Нишал Хада
источник
7

На шаг впереди. Это подкласс UIImageView. (Не точное решение исходного вопроса.) Используйте в Интерфейсном Разработчике, установив имя класса в TintedImageView. Обновления в реальном времени внутри дизайнера по мере изменения цвета оттенка.

(Swift 3.1, Xcode 8.3)

import UIKit

@IBDesignable class TintedImageView: UIImageView {
    override func prepareForInterfaceBuilder() {
        self.configure()
    }

    override func awakeFromNib() {
        super.awakeFromNib()

        self.configure()
    }

    @IBInspectable override var tintColor: UIColor! {
        didSet {
            self.configure()
        }
    }

    private func configure() {
        self.image = self.image?.withRenderingMode(UIImageRenderingMode.alwaysTemplate)
    }
}
Даниил
источник
2
не работает, но он изменяет конфигурацию func на: self.image = self.image? .withRenderingMode (UIImageRenderingMode.alwaysTemplate) let color = super.tintColor super.tintColor = UIColor.clear super.tintColor = color
lolo_house
5

Сделайте imageView

    let imageView = UIImageView(frame: frame!)
    imageView.contentMode = .ScaleAspectFit
    imageView.tintColor = tintColor

Сделайте изображение

    let mainBundle = NSBundle.mainBundle()
    var image = UIImage(named: filename!, inBundle: mainBundle, compatibleWithTraitCollection: nil)
    image = image?.imageWithRenderingMode(.AlwaysTemplate)

Соедините их вместе

    imageView?.image = image

Показать это

view.addSubview(imageView)
Гэри Дэвис
источник
1

все сказано правильно. мой вклад Если вы не можете / не хотите применять к каждому UiImageView, ИЛИ для эффективности вам нужно визуализировать ОДИН РАЗ (или, например, для ячеек таблиц)

func tint(with color: UIColor) -> UIImage {
        var image = withRenderingMode(.alwaysTemplate)
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        color.set()

        image.draw(in: CGRect(origin: .zero, size: size))
        image = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return image
    }

И установите для всех элементов пользовательского интерфейса этот UIImage.

ingconti
источник
1

@odemolliens ответ должен работать.

Но если у вас все еще есть проблемы, убедитесь, что цвет оттенка, который вы применяете к UIImageView, отличается от цвета, определенного в Interface Builder.

rockdaswift
источник