Apakah mungkin untuk memodifikasi UIImage
's renderingMode
dari storyboard atau xib Editor?
Tujuannya adalah untuk diterapkan tintColor
pada UIImageView
objek tertentu .
Apakah mungkin untuk memodifikasi UIImage
's renderingMode
dari storyboard atau xib Editor?
Tujuannya adalah untuk diterapkan tintColor
pada UIImageView
objek 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 .xib
file, tetapi di .xcassets
perpustakaan.
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 UIImageView
dalam file .xib
atau .storyboard
untuk 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.UIKitComponents
gambar lain seperti gambar dalam UIButton
dan 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.renderingMode
properti dalam viewDidLoad
metode 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 renderingMode
propertinya mencerminkan apa yang dipilih dalam file xcassets tetapi gambar tidak diwarnai.
Untuk mengatasinya, Anda memiliki dua opsi:
tintColor
properti 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 renderingMode
dari storyboard
atau 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 UIImageView
subclass:
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 tintColor
properti di Interface Builder masih bermasalah.
Perhatikan bahwa solusi yang berfungsi selain menulis baris yang secara langsung memodifikasi ImageView
properti 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.