Czy można zmodyfikować UIImagea renderingModez edytora scenorysu lub XIB?
Celem jest zastosowanie tintColorsię do konkretnego UIImageViewobiektu.
Czy można zmodyfikować UIImagea renderingModez edytora scenorysu lub XIB?
Celem jest zastosowanie tintColorsię do konkretnego UIImageViewobiektu.
Odpowiedzi:
Oto, jak możesz to zrobić w plikach .xib lub scenorysach:
(Obj-C) Utwórz kategorię na 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) Utwórz rozszerzenie dla 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)
}
}
Następnie w Inspektorze tożsamości w pliku xib dodaj atrybut środowiska uruchomieniowego:

Możesz ustawić tryb renderowania obrazu nie w .xibpliku, ale w .xcassetsbibliotece.
Po dodaniu obrazu do biblioteki zasobów, wybierz obraz i otwórz inspektor atrybutów po prawej stronie Xcode. Znajdź atrybut „Renderuj jako” i ustaw go na „szablon”.
Po ustawieniu trybu renderowania obrazu, możesz dodać kolor tinty do pliku UIImageViewa .xiblub .storyboard, aby dostosować kolor obrazu.
To ustawia właściwość na obrazie, gdziekolwiek jest używany, a nie tylko w jednym pliku konstruktora interfejsu, ale w prawie wszystkich przypadkach (z którymi się spotkałem) jest to zachowanie, które chcesz.

Kilka uwag:
UIImageView. Nie zagłębiałem się w to głęboko.UIKitComponentsobrazów, takich jak obrazy z plików UIButton„i UIBarButtonItem”.UIImageView, więc kolor odcienia nie zawsze jest wyświetlany podczas uruchamiania aplikacji.
Używanie trybu renderowania szablonu z UIImageView w scenorysie lub xib jest bardzo błędne, zarówno w systemie iOS 7, jak i iOS 8.
UIImage nie jest poprawnie dekodowany z storyboardu / xib. Jeśli sprawdzisz imageView.image.renderingModewłaściwość w viewDidLoadmetodzie, zauważysz, że tak jest zawsze UIImageRenderingModeAutomatic, nawet jeśli ustawisz ją na Renderuj jako obraz szablonu w pliku xcassets.
Aby obejść ten problem, musisz ręcznie ustawić tryb renderowania:
self.imageView.image = [self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIImage jest prawidłowo zdekodowany, a jego renderingModewłaściwość odzwierciedla to, co zostało wybrane w pliku xcassets, ale obraz nie jest zabarwiony.
Aby obejść ten problem, masz dwie możliwości:
tintColorwłaściwość w atrybutach środowiska wykonawczego zdefiniowanych przez użytkownika zamiast w panelu inspektora atrybutów.lub
UIColor *tintColor = self.imageView.tintColor;
self.imageView.tintColor = nil;
self.imageView.tintColor = tintColor;
Możesz wybrać preferowaną opcję, obie odpowiednio zabarwiają obraz.
(Jeśli kompilujesz z Xcode 6.2, wystarczy zrobić self.imageView.tintColor = self.imageView.tintColor;to, ale to już nie działa, jeśli kompilujesz z Xcode 6.3)
Jeśli chcesz obsługiwać zarówno iOS 7, jak i iOS 8, będziesz potrzebować obu obejść. Jeśli musisz obsługiwać tylko iOS 8, potrzebne jest tylko jedno obejście.
Ustawienie imageView RenderingMode tak, aby używał koloru tinta w serii ujęć, można zredukować do jednowierszowego:
[self.imageView setImage:[self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]];
Następnie obraz i kolor tinta można ustawić w Storyboard.
Możesz naprawić problemy z .xib za pomocą rozszerzenia:
import UIKit
// fixing Bug in XCode
// http://openradar.appspot.com/18448072
extension UIImageView {
override open func awakeFromNib() {
super.awakeFromNib()
self.tintColorDidChange()
}
}
Źródło: https://gist.github.com/buechner/3b97000a6570a2bfbc99c005cb010bac
Niesamowite, ten błąd istnieje już od 4-5 lat.
Nie możesz ustawić renderingModeani z, storyboardani xib. Może uzyskać dostęp programowo.
dawny:
UIImage *unSeletedImage = [UIImage imageNamed:@"UnSelected.png"];
selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
UIImage *selectedImage = [unSeletedImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
Ustaw tintColor & Class w 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
}
}
Bardzo łatwo to naprawić
Po prostu utwórz klasę UIImageViewPDF i użyj jej w swoim storyboardzie
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
Innym rozwiązaniem jest utworzenie UIImageViewpodklasy:
final class TemplateImageView: UIImageView {
override func awakeFromNib() {
super.awakeFromNib()
guard let oldImage = image else { return }
image = nil
image = oldImage.withRenderingMode(.alwaysTemplate)
}
}
Następnie po prostu ustaw klasę w Interface Builder na TemplateImageView.
Prosty sposób na ustawienie z 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)
}
}
}
}
Działa dobrze na iOS 10 i Swift 3
W systemie iOS 9 ustawienie tintColorwłaściwości w Interface Builder jest nadal błędne.
Zauważ, że działającym rozwiązaniem oprócz pisania linii bezpośrednio modyfikujących ImageViewwłaściwości jest ustawienie Renderuj jako: Obraz szablonu w katalogu zasobów i wywołanie np .:
[[UIImageView appearanceWhenContainedInInstancesOfClasses:@[[MyView class]]] setTintColor:[UIColor whiteColor]];
Jeśli tworzysz IBOutlet, możesz go zmienić w swojej metodzie awakeFromNib w ten sposób ...
self.myImageView.image = [self.myImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
Chociaż odpowiedź @ Moby'ego jest bardziej poprawna - może być bardziej zwięzła.
Szalony ten błąd nadal występuje w iOS 12.1! W przypadku scenorysów / xibs: dodanie tagu do UIImageView może być szybką naprawą.
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)
}
}
}
W scenorysie wybierz UIImageView i wybierz inspektora, ustaw właściwość renderModeTemplate= On
In Storyboard
Jak Rudolf również wspomniał powyżej , zdefiniowałbym prostą klasę, taką jak ta:
import UIKit
@IBDesignable class TintImage: UIImageView{
override func layoutSubviews() {
super.layoutSubviews()
image = image?.withRenderingMode(.alwaysTemplate)
}
}
Po tej definicji wystarczy dodać Widok obrazu do scenorysu i wybrać jego klasę niestandardową jako TintImage. Spowoduje to aktywację wyboru „Odcień” w serii ujęć.