UIImage renderingMode'u bir storyboard / xib dosyasından değiştirme


95

Bir film şeridinden veya xib düzenleyiciden bir UIImage'i değiştirmek mümkün renderingModemüdür?

Amaç, tintColorbelirli bir UIImageViewnesneye uygulamaktır.

Yanıtlar:


101

Bunu .xib veya film şeridi dosyalarında şu şekilde yapabilirsiniz:

(Obj-C) Şurada bir kategori oluşturun 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) Şunun için bir uzantı oluşturun 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)
    }
}

Ardından, xib dosyasındaki Kimlik Denetçisinde bir çalışma zamanı özniteliği ekleyin:

görüntü açıklamasını buraya girin


44
Bu cevabın sevdiğim yanı, sorunun cevabı olması.
algal

1
Anahtar değer ayarını yapmak yerine bir UIImageView alt sınıfı oluşturmayı tercih ederim. Çünkü, kurulumu daha kolay ve numaralandırma değerinde sayı ayarından kaçınabiliriz. Örneğin: `@implementation TemplateRenderingImageView - (id) initWithCoder: (NSCoder *) aDecoder {self = [super initWithCoder: aDecoder]; if (self) {self.image = [self.image imageWithRenderingMode: UIImageRenderingModeAlwaysTemplate]; } kendine dönüş; } @ end`
john fantasy

1
Mükemmel cevap! Ekran görüntüleri yardımcı oldu.
BigSauce

1
Elbette Launch Screen.xib ile çalışmaz çünkü onunla kullanıcı tanımlı çalışma zamanı özniteliklerini kullanamazsınız.
Steve Moser

3
2 değerini bir değer olarak kodlamak kötü kötü kötü .. xcassets kataloğunun kullanılması doğru cevaptır.
tGilani

199

Görüntü işleme modunu .xibdosyada değil, bir .xcassetskitaplıkta ayarlayabilirsiniz .

Bir varlık kitaplığına bir görüntü ekledikten sonra, görüntüyü seçin ve Xcode'un sağ tarafındaki nitelik denetçisini açın. "Farklı Oluştur" özelliğini bulun ve "şablon" olarak ayarlayın.

Bir görüntünün oluşturma modunu ayarladıktan sonra, görüntü rengini ayarlamak için UIImageViewbir .xibveya .storyboarddosyadaki öğesine bir renk tonu ekleyebilirsiniz .

Bu, yalnızca bir arabirim oluşturucu dosyası yerine görüntüdeki özelliği kullanıldığı her yerde ayarlar, ancak hemen hemen tüm durumlarda (karşılaştığım) bu, istediğiniz davranıştır.

Bir görüntü için nitelik denetçisini gösteren Xcode ekran görüntüsü

Dikkat edilmesi gereken birkaç nokta:

  • Görüntü rengi arayüz oluşturucuda (Xcode 6.1.1 itibariyle) değişmiş gibi görünmeyecek, ancak uygulama çalıştırıldığında çalışacaktır.
  • Bu özellikte bazı hatalar yaşadım ve bazı durumlarda UIImageView. O kadar derinlemesine bakmadım.
  • Bu UIKitComponents, UIButton's ve UIBarButtonItem' ler içindeki resimler gibi diğerlerinde de harika çalışır .
  • Varlık kitaplığınızda görünmeyen bir sürü beyaz resminiz varsa, bunları siyah / şeffaf resimler yapmak ve işleme modunu değiştirmek hayatınızı 10 kata kadar daha iyi hale getirecektir.

15
Renk tonu renginin açık olduğu bir hata var gibi görünüyor UIImageView, bu nedenle uygulama çalıştırılırken ton rengi her zaman gösterilmiyor.
Fogh

@Fogh Ben de buna benzer tutarsız hatalar yaşadım. Ton rengini ayarlamak programlı olarak bunu düzeltir mi?
Anthony Mattox

2
IB'de ton rengini ayarlarken bir sorun olduğunu doğrulayabilirim. Programlı olarak ayarlamak işe yarar. Bunun için 20305518 numaralı bir hata kaydettim.
Nikolay Derkach

1
@AxelGuilmin Yup. Aslında sadece alfa kanalı kullanılır, bu nedenle şeffaflık istediğiniz gibi herhangi bir renk olabilir.
Anthony Mattox

1
Şimdi Xcode 7.3 (7D175) ile çalışıyor! Kabul edilen cevap çok sezgisel bir çözüm olsa da, bunun yerine bu cevabı tercih ediyorum.
nstein

43

Şablon oluşturma modunu bir film şeridinde veya xib'de UIImageView ile kullanmak hem iOS 7 hem de iOS 8'de çok hatalı.

İOS 7'de

UIImage film şeridi / xib'den düzgün bir şekilde çözülmedi. Eğer incelemek Eğer imageView.image.renderingModetesise viewDidLoadyöntemiyle, bunu her zaman olduğunu göreceksiniz UIImageRenderingModeAutomaticbunu ayarlı olsa bile, As Template Resmi Render sizin xcassets dosyasında.

Geçici çözüm için, oluşturma modunu manuel olarak ayarlamanız gerekir:

self.imageView.image = [self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];

İOS 8'de

UIImage düzgün bir şekilde çözülür ve renderingModeözelliği xcassets dosyasında seçileni yansıtır ancak görüntü renklendirilmez.

Çözüm için iki seçeneğiniz vardır:

  1. tintColorÖzelliği , Nitelikler denetçisi bölmesi yerine Kullanıcı Tanımlı Çalışma Zamanı Niteliklerinde ayarlayın .

veya

  1. TintColor'u manuel olarak sıfırlayın:
UIColor *tintColor = self.imageView.tintColor;
self.imageView.tintColor = nil;
self.imageView.tintColor = tintColor;

Her ikisi de görüntüyü uygun şekilde renklendirmek için tercih ettiğiniz seçeneği seçebilirsiniz.

(Xcode 6.2 ile derliyorsanız, sadece yapmak self.imageView.tintColor = self.imageView.tintColor;yeterlidir ancak Xcode 6.3 ile derliyorsanız artık bu çalışmaz)

Sonuç

Hem iOS 7 hem de iOS 8'i desteklemeniz gerekiyorsa, her iki geçici çözüme de ihtiyacınız olacak. Yalnızca iOS 8'i desteklemeniz gerekiyorsa, yalnızca bir geçici çözüm gerekir.


2
Teşekkürler. Xcode 7 ve iOS 8'de benim için yalnızca 2 numaralı geçici çözüm çalışıyor.
sörfçü

3
İOS 8 için geçici çözümün iOS 9 için de geçerli olduğunu onaylıyorum.
Michael Pirotte

1
Kesinlikle Xcode 7'de aynı şeyi görüyorum - kullanıcı özniteliği geçici çözümü iyiydi. Teşekkürler!
Geoffrey Wiseman

awakeFromNib'de tintColor'u manuel olarak sıfırlamak bunu yaptı! (görüntü .xcassets kataloğunda da şablon olarak ayarlandı, aksi takdirde orijinalden bir şablon görüntüsü oluşturmanız gerekir). Teşekkürler!!
horseshoe7

15

İmageView RenderingMode'u film şeridinde ton rengini kullanacak şekilde ayarlamak tek satıra indirgenebilir:

[self.imageView setImage:[self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]];

Ardından, görüntü ve renk tonunun tümü Storyboard'da ayarlanabilir.


13

.Xib sorunlarını bir uzantıyla düzeltebilirsiniz:

import UIKit

// fixing Bug in XCode
// http://openradar.appspot.com/18448072
extension UIImageView {
    override open func awakeFromNib() {
        super.awakeFromNib()
        self.tintColorDidChange()
    }
}

Kaynak: https://gist.github.com/buechner/3b97000a6570a2bfbc99c005cb010bac

Şaşırtıcı, bu böcek yaklaşık 4-5 yıldır ortalıkta.


3
Cevap olarak bu seçilmelidir
farzadshbfn

Hala bir hata ve bu hala iOS 12.0'dan itibaren düzeltiyor.
Sam Soffes

Hala iOS 12.1'de bir hata
Cesare

Gerçek olmayan adamlar, gerçek değil.
Mat

8

Ayarlayabilir cann't renderingModegelen ya storyboardya xib. Programlı olarak erişebilir.

ör .:

UIImage *unSeletedImage = [UIImage imageNamed:@"UnSelected.png"];
selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

3
Sanırım, kodunuzda küçük yazım hataları yaptınız. İkinci satırUIImage *selectedImage = [unSeletedImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
Artem Stepanenko

8

Storyboard'da tintColor & Class'ı ayarlayın.

//
//  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
    }

}

New Swift'te işe yarayan tek cevap bu. Teşekkür ederim.
Simon Moshenko

Garip bir nedenden dolayı benim için çalışmıyor ... Film şeridindeki rengi güncellemesi mi gerekiyor?
Cesare

4

Düzeltmesi çok kolay

Sadece UIImageViewPDF sınıfı oluşturun ve bunu film şeridinizde kullanın

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

3

Başka bir çözüm de bir UIImageViewalt sınıf oluşturmaktır :

final class TemplateImageView: UIImageView {
    override func awakeFromNib() {
        super.awakeFromNib()
        guard let oldImage = image else { return }
        image = nil
        image = oldImage.withRenderingMode(.alwaysTemplate)
    }
}

Ardından, Interface Builder'daki sınıfı olarak ayarlayın TemplateImageView.


en iyi çözüm !!
Irshad Mohamed

2

Storyboard'dan ayarlanmanın basit yolu:

@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)
            }

        }
    }
}

İOS 10 ve Swift 3'te iyi çalışıyor


1

İOS 9 ayarında, tintColorInterface Builder'daki özellik hala hatalı.

Satırları doğrudan ImageViewözellikleri değiştirmenin yanı sıra çalışan bir çözümün varlık kataloğunda Farklı Oluştur: Şablon Görüntüsünü ayarlamak ve örneğin:

[[UIImageView appearanceWhenContainedInInstancesOfClasses:@[[MyView class]]] setTintColor:[UIColor whiteColor]];

1

tintColorArabirim oluşturucuya çalışma zamanı özniteliği ekleyerek bu sorunu çözdüm.

NOT: Görüntünüzü Images.xcassets dosyanızda şablon görüntüsü olarak işlenecek şekilde ayarlamanız gerekir.

görüntü açıklamasını buraya girin


0

Bir IBOutlet oluşturursanız, bunu awakeFromNib yönteminizde şu şekilde değiştirebilirsiniz ...

self.myImageView.image = [self.myImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];

@ Moby'nin cevabı daha doğru olsa da - bu daha kısa ve öz olabilir.


1
Soru, bunun kodda değil, storyboard'da (veya xib'de) nasıl yapılacağıydı.
Artem Stepanenko

@artem - evet, üzgünüm, sorunuza bir cevabım olduğu sonucuna varmak istemedim. IBOutlet aracılığıyla bununla başa çıkmanın basit bir yolunu işaret ediyor
amergin

0

Çılgınca bu hata hala iOS 12.1'de! Film şeritleri / xibs için: UIImageView'a bir etiket eklemek hızlı bir düzeltme olabilir.

Swift 4.2

view.viewWithTag(1)?.tintColorDidChange()

0
extension UIImageView {

   @IBInspectable var renderModeTemplate : Bool {
       get{
           return image?.renderingMode == .alwaysTemplate
       }

       set{
          image = image?.withRenderingMode(newValue ? .alwaysTemplate:.alwaysOriginal)
       }
   }
}

Film şeridinde UIImageView öğesini seçin ve denetçiyi seçin, özelliği ayarlayın renderModeTemplate= On Öykü Panosunda


0

Rudolf'un yukarıda da bahsettiği gibi , şöyle basit bir sınıf tanımlardım:

import UIKit

@IBDesignable class TintImage: UIImageView{
    override func layoutSubviews() {
        super.layoutSubviews()
 
        image = image?.withRenderingMode(.alwaysTemplate)
    }
}

Bu tanımdan sonra, film şeridine bir Resim Görünümü ekleyin ve özel sınıfını TintImage. Bu, film şeridindeki "Ton" seçimini etkinleştirecektir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.