Змініть режим відображення UIImage з файлу розкадрування / xib


Відповіді:


101

Ось як це можна зробити у файлах .xib або раскадровках:

(Obj-C) Створіть категорію на UIImageView:

@interface UIImageView (Utils)

- (void)setImageRenderingMode:(UIImageRenderingMode)renderMode;

@end

@implementation UIImageView (Utils)

- (void)setImageRenderingMode:(UIImageRenderingMode)renderMode
{
    NSAssert(self.image, @"Image must be set before setting rendering mode");
    self.image = [self.image imageWithRenderingMode:renderMode];
}

@end

(Swift 4) Створіть розширення для UIImageView:

extension UIImageView {
    func setImageRenderingMode(_ renderMode: UIImage.RenderingMode) {
        assert(image != nil, "Image must be set before setting rendering mode")
        // AlwaysOriginal as an example
        image = image?.withRenderingMode(.alwaysOriginal)
    }
}

Потім в інспектор ідентичності у файлі xib додайте атрибут виконання:

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


44
Що мені подобається у цій відповіді, це те, що це відповідь на питання.
водорості

1
Я вважаю за краще створити підклас UIImageView, а не робити налаштування ключового значення. Тому що це простіше налаштувати, і ми могли б уникнути встановлення числа до значення перерахунку. Наприклад: `@implementation TemplateRenderingImageView - (id) initWithCoder: (NSCoder *) aDecoder {self = [super initWithCoder: aDecoder]; if (self) {self.image = [self.image imageWithRenderingMode: UIImageRenderingModeAlwaysTemplate]; } повернути себе; } @ end`
Джон Фентезі

1
Чудова відповідь! Скріншоти були корисними.
BigSauce

1
Не працює з Launch Screen.xib, звичайно, тому що ви не можете використовувати визначені користувачем атрибути виконання.
Стів Мозер

3
жорстке кодування 2 як значення - погано погано погано .. Використання каталогу xcassets - правильна відповідь.
tGilani

198

Ви можете встановити режим візуалізації зображення не у .xibфайлі, а у .xcassetsбібліотеці.

Після додавання зображення до бібліотеки об’єктів виберіть зображення та відкрийте інспектор атрибутів праворуч від Xcode. Знайдіть атрибут 'Render As' та встановіть його на 'template'.

Після встановлення режиму візуалізації зображення ви можете додати колір відтінку UIImageViewв a .xibабо .storyboardфайл, щоб відрегулювати колір зображення.

Це встановлює властивість зображення, де б воно не використовувалося, а не тільки в одному файлі конструктора інтерфейсів, але майже у всіх випадках (з якими я стикався), це саме те, що ви хочете.

Знімок екрана Xcode, що показує атрибути інспектора для зображення

Кілька речей, які слід зазначити:

  • Колір зображення, як видається, не змінився в конструкторі інтерфейсів (станом на Xcode 6.1.1), але буде працювати при запуску програми.
  • Я відчував деяку невдачу з цією функцією, і в деяких ситуаціях мені довелося видалити та знову додати UIImageView. Я не вдивлявся в це глибоко.
  • Це також чудово підходить для інших, UIKitComponentsтаких як зображення в UIButtonUIBarButtonItem' s.
  • Якщо у вашій бібліотеці активів є маса білих зображень, які не помітні, їх чорні / прозорі зображення та зміна режиму візуалізації покращать ваше життя до 10 разів.

15
Здається, помилка з відтінком кольору UIImageView, тому колір відтінку не завжди відображається під час роботи програми.
Фог

@Fogh У мене також були такі непослідовні помилки. Чи правильно це виправляє налаштування кольору відтінку?
Ентоні Маттокс

2
Я можу підтвердити, що під час встановлення кольору відтінку в ІБ є проблема. Налаштування програмно працює. Я подав помилку №20305518.
Микола Деркач

1
@AxelGuilmin Yup Насправді використовується лише альфа-канал, тому він може бути будь-якого кольору, якщо прозорість - те, що ви хочете.
Ентоні Маттокс

1
Зараз він працює з Xcode 7.3 (7D175)! Хоча прийнята відповідь є дуже інтуїтивним вирішенням, я вважаю за краще цю відповідь.
nstein

43

Використання режиму візуалізації шаблонів з UIImageView на аркуші розкадрування або xib дуже помилкова, як на iOS 7, так і на iOS 8.

На iOS 7

UIImage неправильно розшифровується з раскадровки / xib. Якщо ви переглянете imageView.image.renderingModeвластивість у viewDidLoadметоді, ви помітите, що це завжди UIImageRenderingModeAutomatic, навіть якщо ви встановите його на зображення відобразити як шаблон у вашому файлі xcassets.

Для вирішення проблеми потрібно вручну встановити режим візуалізації:

self.imageView.image = [self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];

На iOS 8

UIImage правильно декодується, і його renderingModeвластивість відображає те, що було обрано у файлі xcassets, але зображення не тоноване.

Щоб вирішити, у вас є два варіанти:

  1. Встановіть tintColorвластивість у визначених користувачем атрибутах виконання замість панелі інспектора атрибутів.

або

  1. Вручну скинути tintColor:
UIColor *tintColor = self.imageView.tintColor;
self.imageView.tintColor = nil;
self.imageView.tintColor = tintColor;

Ви можете вибрати бажаний варіант, обидва належним чином підфарбовувати зображення.

(Якщо ви компілюєте з Xcode 6.2, просто робите self.imageView.tintColor = self.imageView.tintColor; , але це більше не працює, якщо ви компілюєте з Xcode 6.3)

Висновок

Якщо вам потрібно підтримувати і iOS 7, і iOS 8, вам знадобляться обидва способи вирішення. Якщо вам потрібно підтримувати лише iOS 8, потрібен лише один спосіб вирішення.


2
Дякую. У Xcode 7 та iOS 8. для мене працює лише
обхід №2.

3
Я підтверджую, що рішення для iOS 8 також є корисним для iOS 9.
Michael Pirotte

1
Я точно бачу те ж саме на Xcode 7 - вирішення атрибутів користувача було чудово. Дякую!
Джеффрі Вісман

вручну скинути tintColor в режимі пробудженняFromNib зробив це! (зображення було встановлено як шаблон у каталозі .xcassets теж, інакше вам доведеться зробити шаблон шаблону з оригіналу). Дякую!!
підкова7

15

Встановлення imageView RenderingMode для використання кольору відтінку на дошці даних може бути зменшено до однолінійного:

[self.imageView setImage:[self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]];

Тоді все зображення та кольори відтінку можна встановити на Дошці розкадрувань.


13

Ви можете виправити проблеми .xib із розширенням:

import UIKit

// fixing Bug in XCode
// http://openradar.appspot.com/18448072
extension UIImageView {
    override open func awakeFromNib() {
        super.awakeFromNib()
        self.tintColorDidChange()
    }
}

Джерело: https://gist.github.com/buechner/3b97000a6570a2bfbc99c005cb010bac

Дивовижно, ця помилка існує вже як 4-5 років.


3
Це слід вибрати як відповідь
farzadshbfn

Поки що помилка, і це все-таки виправляє її як в iOS 12.0.
Сем Соффс

Все-таки помилка в iOS 12.1
Cesare

Нереальні хлопці, нереально.
Мат

8

Ви можите встановити renderingModeабо з storyboardабо xib. До нього можна було отримати доступ програмно.

напр .:

UIImage *unSeletedImage = [UIImage imageNamed:@"UnSelected.png"];
selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

3
Я думаю, ви зробили невеликі помилки в коді. Другий рядок має бутиUIImage *selectedImage = [unSeletedImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
Артем Степаненко

8

Встановіть tintColor & Class на аркуші розкадрувань.

//
//  TintColoredImageView.swift
//  TintColoredImageView
//
//  Created by Dmitry Utmanov on 14/07/16.
//  Copyright © 2016 Dmitry Utmanov. All rights reserved.
//

import UIKit

@IBDesignable class TintColoredImageView: UIImageView {

    override var image: UIImage? {
        didSet {
            let _tintColor = self.tintColor
            self.tintColor = nil
            self.tintColor = _tintColor
        }
    }


    override init(frame: CGRect) {
        super.init(frame: frame)
        initialize()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        initialize()
    }

    override init(image: UIImage?) {
        super.init(image: image)
        initialize()
    }

    override init(image: UIImage?, highlightedImage: UIImage?) {
        super.init(image: image, highlightedImage: highlightedImage)
        initialize()
    }

    func initialize() {
        let _tintColor = self.tintColor
        self.tintColor = nil
        self.tintColor = _tintColor
    }

}

Це єдина відповідь, яка працювала на нових швидких. Дякую.
Саймон Мошенко

Це не працює для мене з якихось дивних причин ... Чи слід оновлювати колір на аркуші розкадрування?
Цезаре

4

Це дуже легко виправити

Просто створіть клас UIImageViewPDF і використовуйте його у своїй розкадровці

IB_DESIGNABLE
@interface UIImageViewPDF : UIImageView

@end

@implementation UIImageViewPDF

- (void) didMoveToSuperview
{
    [super didMoveToSuperview];
    self.image = [self.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
    id color = self.tintColor;
    self.tintColor = color;
}

@end

3

Ще одне рішення - створити UIImageView підкласу:

final class TemplateImageView: UIImageView {
    override func awakeFromNib() {
        super.awakeFromNib()
        guard let oldImage = image else { return }
        image = nil
        image = oldImage.withRenderingMode(.alwaysTemplate)
    }
}

Потім просто встановіть клас у програмі Interface Builder на TemplateImageView.


найкраще рішення !!
Іршад Мохамед

2

Простий спосіб встановити з Дошки розкадрувань:

@IBDesignable
public class CustomImageView: UIImageView {
    @IBInspectable var alwaysTemplate: Bool = false {
        didSet {
            if alwaysTemplate {
                self.image = self.image?.withRenderingMode(.alwaysTemplate)
            } else {
                self.image = self.image?.withRenderingMode(.alwaysOriginal)
            }

        }
    }
}

Відмінно працює на iOS 10 та Swift 3


1

В iOS 9 налаштування tintColorвластивості в Interface Builder все ще є помилковою.

Зауважте, що робочим рішенням, крім запису рядків, що безпосередньо змінюють ImageViewвластивості, є встановлення відобразити як: зображення шаблону в каталозі активів, і зателефонувати, наприклад:

[[UIImageView appearanceWhenContainedInInstancesOfClasses:@[[MyView class]]] setTintColor:[UIColor whiteColor]];

1

Я вирішив цю проблему, додавши атрибут виконання tintColorв конструкторі інтерфейсів.

ПРИМІТКА: Вам все одно потрібно буде встановити зображення, яке відображатиметься у вигляді шаблону у вашому файлі Images.xcassets.

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


0

Якщо ви створюєте IBOutlet, ви можете змінити його у вашому методі awakeFromNib, наприклад ...

self.myImageView.image = [self.myImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];

Хоча відповідь @ Мобі правильніша - це може бути більш стислим.


1
Питання полягало в тому, як це зробити в раскадровці (або xib), а не в коді.
Артем Степаненко

@artem - так, вибачте, я не мав сенсу робити висновок, що у мене була відповідь на ваше запитання. Лише вказуючи на простий спосіб боротьби з цим через IBOutlet
amergin

0

Божевільна ця помилка все ще в iOS 12.1! Для розповідей / xibs: Додавання тегу до UIImageView може бути швидким виправленням.

Швидкий 4.2

view.viewWithTag(1)?.tintColorDidChange()

0
extension UIImageView {

   @IBInspectable var renderModeTemplate : Bool {
       get{
           return image?.renderingMode == .alwaysTemplate
       }

       set{
          image = image?.withRenderingMode(newValue ? .alwaysTemplate:.alwaysOriginal)
       }
   }
}

У дошці розкадру виберіть UIImageView та виберіть інспектора, встановіть властивість renderModeTemplate= On In In Storyboard

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.