Czy można zmodyfikować UIImage
a renderingMode
z edytora scenorysu lub XIB?
Celem jest zastosowanie tintColor
się do konkretnego UIImageView
obiektu.
ios
ios7
xcode-storyboard
Artem Stepanenko
źródło
źródło
Możesz ustawić tryb renderowania obrazu nie w
.xib
pliku, ale w.xcassets
bibliotece.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
UIImageView
a.xib
lub.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.UIKitComponents
obrazów, takich jak obrazy z plikówUIButton
„iUIBarButtonItem
”.źródło
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.
W systemie iOS 7
UIImage nie jest poprawnie dekodowany z storyboardu / xib. Jeśli sprawdzisz
imageView.image.renderingMode
właściwość wviewDidLoad
metodzie, zauważysz, że tak jest zawszeUIImageRenderingModeAutomatic
, nawet jeśli ustawisz ją na Renderuj jako obraz szablonu w pliku xcassets.Aby obejść ten problem, musisz ręcznie ustawić tryb renderowania:
W systemie iOS 8
UIImage jest prawidłowo zdekodowany, a jego
renderingMode
wł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:
tintColor
właściwość w atrybutach środowiska wykonawczego zdefiniowanych przez użytkownika zamiast w panelu inspektora atrybutów.lub
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)Wniosek
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.
źródło
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.
źródło
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.
źródło
Nie możesz ustawić
renderingMode
ani z,storyboard
anixib
. Może uzyskać dostęp programowo.dawny:
UIImage *unSeletedImage = [UIImage imageNamed:@"UnSelected.png"]; selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
źródło
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 } }
źródło
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
źródło
Innym rozwiązaniem jest utworzenie
UIImageView
podklasy: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
.źródło
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
źródło
W systemie iOS 9 ustawienie
tintColor
wł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
ImageView
właściwości jest ustawienie Renderuj jako: Obraz szablonu w katalogu zasobów i wywołanie np .:[[UIImageView appearanceWhenContainedInInstancesOfClasses:@[[MyView class]]] setTintColor:[UIColor whiteColor]];
źródło
Naprawiono ten problem, dodając atrybut runtime
tintColor
w konstruktorze interfejsu.UWAGA: Nadal będziesz musiał ustawić renderowanie obrazu jako obrazu szablonu w pliku Images.xcassets.
źródło
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.
źródło
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()
źródło
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źródło
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ęć.źródło