E 'possibile modificare un UIImage's renderingModeda un editor di storyboard o XI ter?
L'obiettivo è applicare all'oggetto tintColorparticolare UIImageView.
E 'possibile modificare un UIImage's renderingModeda un editor di storyboard o XI ter?
L'obiettivo è applicare all'oggetto tintColorparticolare UIImageView.
Risposte:
Ecco come puoi farlo nei file .xib o storyboard:
(Obj-C) Crea una categoria su 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) Crea un'estensione per 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)
}
}
Quindi nell'Identity Inspector nel file xib, aggiungi un attributo di runtime:

È possibile impostare la modalità di rendering dell'immagine non nel .xibfile, ma in una .xcassetslibreria.
Dopo aver aggiunto un'immagine a una libreria di risorse, seleziona l'immagine e apri l'ispettore degli attributi sul lato destro di Xcode. Trova l'attributo "Rendering come" e impostalo su "modello".
Dopo aver impostato la modalità di rendering di un'immagine, è possibile aggiungere un colore di tinta al file UIImageViewin a .xibo .storyboardper regolare il colore dell'immagine.
Questo imposta la proprietà sull'immagine ovunque sia utilizzata piuttosto che in un solo file di creazione dell'interfaccia, ma in quasi tutti i casi (che ho riscontrato) questo è il comportamento che desideri.

Alcune cose da notare:
UIImageView. Non l'ho approfondito.UIKitComponents, come le immagini in UIButton"e UIBarButtonItem".UIImageView, quindi il colore della tinta non viene sempre mostrato durante l'esecuzione dell'app.
L'uso della modalità di rendering del modello con un UIImageView in uno storyboard o xib è molto difettoso, sia su iOS 7 che su iOS 8.
L'UIImage non è stato decodificato correttamente dallo storyboard / xib. Se controlli la imageView.image.renderingModeproprietà nel viewDidLoadmetodo, noterai che è sempre UIImageRenderingModeAutomatic, anche se lo imposti su Render As Template Image nel tuo file xcassets.
Per risolvere il problema, devi impostare manualmente la modalità di rendering:
self.imageView.image = [self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
L'UIImage è correttamente decodificato e la sua renderingModeproprietà riflette ciò che è stato scelto nel file xcassets ma l'immagine non è colorata.
Per risolvere il problema, hai due opzioni:
tintColorproprietà negli attributi di runtime definiti dall'utente invece che nel pannello di ispezione Attributi.o
UIColor *tintColor = self.imageView.tintColor;
self.imageView.tintColor = nil;
self.imageView.tintColor = tintColor;
Puoi scegliere la tua opzione preferita, entrambe colorano correttamente l'immagine.
(Se stai compilando con Xcode 6.2, self.imageView.tintColor = self.imageView.tintColor;è sufficiente farlo ma non funziona più se stai compilando con Xcode 6.3)
Se devi supportare sia iOS 7 che iOS 8, avrai bisogno di entrambe le soluzioni alternative. Se devi supportare solo iOS 8, è necessaria solo una soluzione alternativa.
L'impostazione di imageView RenderingMode per utilizzare il colore della tinta nello storyboard può essere ridotta a una riga:
[self.imageView setImage:[self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]];
Quindi l'immagine e il colore della tinta possono essere impostati nello Storyboard.
Puoi risolvere i problemi .xib con un'estensione:
import UIKit
// fixing Bug in XCode
// http://openradar.appspot.com/18448072
extension UIImageView {
override open func awakeFromNib() {
super.awakeFromNib()
self.tintColorDidChange()
}
}
Fonte: https://gist.github.com/buechner/3b97000a6570a2bfbc99c005cb010bac
Incredibile, questo bug esiste da circa 4-5 anni.
Non puoi impostare renderingModené da storyboardo xib. Potrebbe accedere in modo programmatico.
ex:
UIImage *unSeletedImage = [UIImage imageNamed:@"UnSelected.png"];
selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
UIImage *selectedImage = [unSeletedImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
Imposta tintColor e Class in Storyboard.
//
// 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
}
}
È molto facile da riparare
Basta creare la classe UIImageViewPDF e usarla nel tuo storyboard
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
Un'altra soluzione è creare una UIImageViewsottoclasse:
final class TemplateImageView: UIImageView {
override func awakeFromNib() {
super.awakeFromNib()
guard let oldImage = image else { return }
image = nil
image = oldImage.withRenderingMode(.alwaysTemplate)
}
}
Quindi imposta la classe in Interface Builder su TemplateImageView.
Modo semplice per essere impostato da Storyboard:
@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)
}
}
}
}
Funziona bene su iOS 10 e Swift 3
In iOS 9 l'impostazione della tintColorproprietà in Interface Builder è ancora buggata.
Si noti che una soluzione funzionante oltre a scrivere righe che modificano direttamente le ImageViewproprietà è impostare Render As: Template Image nel catalogo degli asset e chiamare ad esempio:
[[UIImageView appearanceWhenContainedInInstancesOfClasses:@[[MyView class]]] setTintColor:[UIColor whiteColor]];
Ho risolto questo problema aggiungendo l'attributo di runtime tintColornel generatore di interfacce.
NOTA: sarà comunque necessario impostare il rendering dell'immagine come immagine modello nel file Images.xcassets.
Se crei un IBOutlet puoi cambiarlo nel tuo metodo awakeFromNib in questo modo ...
self.myImageView.image = [self.myImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
Mentre la risposta di @ Moby è più corretta, potrebbe essere più succinta.
Pazzesco questo bug è ancora in iOS 12.1! Per storyboard / xib: l'aggiunta di un tag a UIImageView può essere una soluzione rapida.
Swift 4.2
view.viewWithTag(1)?.tintColorDidChange()
extension UIImageView {
@IBInspectable var renderModeTemplate : Bool {
get{
return image?.renderingMode == .alwaysTemplate
}
set{
image = image?.withRenderingMode(newValue ? .alwaysTemplate:.alwaysOriginal)
}
}
}
Nello storyboard selezionare UIImageView e selezionare inspector, set property renderModeTemplate= On
In Storyboard