Apakah mungkin untuk memodifikasi UIImage's renderingModedari storyboard atau xib Editor?
Tujuannya adalah untuk diterapkan tintColorpada UIImageViewobjek tertentu .
Apakah mungkin untuk memodifikasi UIImage's renderingModedari storyboard atau xib Editor?
Tujuannya adalah untuk diterapkan tintColorpada UIImageViewobjek tertentu .
Jawaban:
Berikut cara melakukannya dalam file .xib atau storyboard:
(Obj-C) Buat kategori di 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) Buat ekstensi untuk 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)
}
}
Kemudian di Identity Inspector di file xib, tambahkan atribut runtime:

Anda dapat menyetel mode rendering gambar tidak dalam .xibfile, tetapi di .xcassetsperpustakaan.
Setelah menambahkan gambar ke pustaka aset, pilih gambar dan buka inspektur atribut di sisi kanan Xcode. Temukan atribut 'Render As' dan setel ke 'template'.
Setelah mengatur mode rendering gambar, Anda dapat menambahkan warna tint ke UIImageViewdalam file .xibatau .storyboarduntuk menyesuaikan warna gambar.
Ini menyetel properti pada gambar di mana pun itu digunakan, bukan hanya dalam satu file pembuat antarmuka, tetapi dalam hampir semua kasus (yang saya temui) ini adalah perilaku yang Anda inginkan.

Beberapa hal yang perlu diperhatikan:
UIImageView. Saya belum memeriksanya secara mendalam.UIKitComponentsgambar lain seperti gambar dalam UIButtondan UIBarButtonItem's.UIImageView, jadi warna tint tidak selalu ditampilkan saat menjalankan aplikasi.
Menggunakan mode rendering template dengan UIImageView di storyboard atau xib sangat bermasalah, baik di iOS 7 dan iOS 8.
UIImage tidak didekode dengan benar dari storyboard / xib. Jika Anda memeriksa imageView.image.renderingModeproperti dalam viewDidLoadmetode ini, Anda akan melihat bahwa itu selalu UIImageRenderingModeAutomatic, bahkan jika Anda menyetelnya ke Render As Gambar Template di file xcassets Anda.
Untuk mengatasinya, Anda harus mengatur mode rendering secara manual:
self.imageView.image = [self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIImage didekodekan dengan benar dan renderingModepropertinya mencerminkan apa yang dipilih dalam file xcassets tetapi gambar tidak diwarnai.
Untuk mengatasinya, Anda memiliki dua opsi:
tintColorproperti di Atribut Waktu Proses yang Ditentukan Pengguna, bukan di panel inspektur Atribut.atau
UIColor *tintColor = self.imageView.tintColor;
self.imageView.tintColor = nil;
self.imageView.tintColor = tintColor;
Anda dapat memilih opsi yang Anda sukai, keduanya mewarnai gambar dengan benar.
(Jika Anda mengkompilasi dengan Xcode 6.2, melakukan saja self.imageView.tintColor = self.imageView.tintColor;sudah cukup tetapi ini tidak berfungsi lagi jika Anda mengkompilasi dengan Xcode 6.3)
Jika Anda perlu mendukung iOS 7 dan iOS 8, Anda memerlukan kedua solusi tersebut. Jika Anda hanya harus mendukung iOS 8, hanya satu solusi yang diperlukan.
Menyetel imageView RenderingMode untuk menggunakan warna tint di storyboard bisa dikurangi menjadi satu baris:
[self.imageView setImage:[self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]];
Kemudian gambar dan warna rona semuanya dapat diatur di Papan Cerita.
Anda dapat memperbaiki masalah .xib dengan ekstensi:
import UIKit
// fixing Bug in XCode
// http://openradar.appspot.com/18448072
extension UIImageView {
override open func awakeFromNib() {
super.awakeFromNib()
self.tintColorDidChange()
}
}
Sumber: https://gist.github.com/buechner/3b97000a6570a2bfbc99c005cb010bac
Luar biasa, bug ini sudah ada sekitar 4-5 tahun sekarang.
Anda tidak dapat menyetel renderingModedari storyboardatau xib. Itu bisa diakses secara terprogram.
ex:
UIImage *unSeletedImage = [UIImage imageNamed:@"UnSelected.png"];
selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
UIImage *selectedImage = [unSeletedImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
Setel tintColor & Class di 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
}
}
Sangat mudah untuk memperbaikinya
Cukup buat kelas UIImageViewPDF dan gunakan di storyboard Anda
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
Solusi lain adalah membuat UIImageViewsubclass:
final class TemplateImageView: UIImageView {
override func awakeFromNib() {
super.awakeFromNib()
guard let oldImage = image else { return }
image = nil
image = oldImage.withRenderingMode(.alwaysTemplate)
}
}
Kemudian setel kelas dalam Interface Builder ke TemplateImageView.
Cara sederhana untuk mengatur dari 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)
}
}
}
}
Berfungsi dengan baik di iOS 10 dan Swift 3
Di iOS 9, pengaturan tintColorproperti di Interface Builder masih bermasalah.
Perhatikan bahwa solusi yang berfungsi selain menulis baris yang secara langsung memodifikasi ImageViewproperti adalah dengan menyetel Render As: Gambar Template dalam katalog aset, dan memanggil misalnya:
[[UIImageView appearanceWhenContainedInInstancesOfClasses:@[[MyView class]]] setTintColor:[UIColor whiteColor]];
Jika Anda membuat IBOutlet, Anda dapat mengubahnya dalam metode awakeFromNib seperti ...
self.myImageView.image = [self.myImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
Meskipun jawaban @ Moby lebih tepat - ini mungkin lebih ringkas.
Gila bug ini masih di iOS 12.1! Untuk storyboard / xibs: Menambahkan tag ke UIImageView bisa menjadi perbaikan cepat.
Swift 4.2.0
view.viewWithTag(1)?.tintColorDidChange()
extension UIImageView {
@IBInspectable var renderModeTemplate : Bool {
get{
return image?.renderingMode == .alwaysTemplate
}
set{
image = image?.withRenderingMode(newValue ? .alwaysTemplate:.alwaysOriginal)
}
}
}
Di storyboard pilih UIImageView dan pilih inspector, set property renderModeTemplate= On
Di Storyboard
Seperti yang juga disebutkan Rudolf di atas , saya akan mendefinisikan kelas sederhana, seperti ini:
import UIKit
@IBDesignable class TintImage: UIImageView{
override func layoutSubviews() {
super.layoutSubviews()
image = image?.withRenderingMode(.alwaysTemplate)
}
}
Setelah definisi ini, cukup tambahkan Image View ke storyboard dan pilih kelas kustomnya sebagai TintImage. Ini akan mengaktifkan pilihan "Tint" di storyboard.