แก้ไข UIImage renderingMode จากไฟล์ storyboard / xib


95

มันเป็นไปได้ที่จะปรับเปลี่ยนUIImage's renderingModeจากกระดานหรือ Xib แก้ไข?

เป้าหมายคือการนำtintColorไปใช้กับUIImageViewวัตถุนั้น ๆ

คำตอบ:


101

นี่คือวิธีที่คุณสามารถทำได้ในไฟล์. xib หรือสตอรี่บอร์ด:

(Obj-C) สร้างหมวดหมู่บน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) สร้างส่วนขยายสำหรับ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)
    }
}

จากนั้นใน Identity Inspector ในไฟล์ xib ให้เพิ่มแอ็ตทริบิวต์รันไทม์:

ป้อนคำอธิบายภาพที่นี่


44
สิ่งที่ฉันชอบเกี่ยวกับคำตอบนี้คือคำตอบสำหรับคำถาม
สาหร่าย

1
ฉันต้องการสร้างคลาสย่อย UIImageView แทนที่จะทำการตั้งค่าคีย์ เพราะมันง่ายกว่าในการตั้งค่าและเราสามารถหลีกเลี่ยงการตั้งค่าตัวเลขเป็นค่าการแจงนับ ตัวอย่างเช่น: `@implementation TemplateRenderingImageView - (id) initWithCoder: (NSCoder *) aDecoder {self = [super initWithCoder: aDecoder]; ถ้า (ตัวเอง) {self.image = [self.image imageWithRenderingMode: UIImageRenderingModeAlwaysTemplate]; } กลับตัว; } @ end`
john fantasy

1
ตอบโจทย์มาก! ภาพหน้าจอมีประโยชน์
BigSauce

1
ใช้ไม่ได้กับ Launch Screen.xib แน่นอนเพราะคุณไม่สามารถใช้แอ็ตทริบิวต์รันไทม์ที่ผู้ใช้กำหนดได้
Steve Moser

3
hardcoding 2 เป็นค่าคือ bad bad bad .. การใช้ xcassets catalog คือคำตอบที่ถูกต้อง
tGilani

199

คุณสามารถตั้งค่าโหมดการแสดงภาพไม่ได้อยู่ใน.xibไฟล์ แต่อยู่ใน.xcassetsไลบรารี

หลังจากเพิ่มรูปภาพลงในไลบรารีเนื้อหาแล้วให้เลือกรูปภาพและเปิดตัวตรวจสอบคุณสมบัติทางด้านขวาของ Xcode ค้นหาแอตทริบิวต์ "Render As" และตั้งค่าเป็น "template"

หลังจากตั้งค่าโหมดการแสดงผลของภาพแล้วคุณสามารถเพิ่มสีอ่อนลงในไฟล์ UIImageViewในไฟล์.xibหรือ.storyboardไฟล์เพื่อปรับสีของภาพได้

สิ่งนี้ตั้งค่าคุณสมบัติบนรูปภาพทุกที่ที่มีการใช้งานไม่ใช่แค่ในไฟล์ตัวสร้างอินเทอร์เฟซเดียว แต่ในเกือบทุกกรณี (ที่ฉันเคยพบ) นี่เป็นพฤติกรรมที่คุณต้องการ

ภาพหน้าจอของ Xcode แสดงตัวตรวจสอบคุณสมบัติสำหรับรูปภาพ

สิ่งที่ควรทราบ:

  • สีของภาพจะไม่เปลี่ยนไปในตัวสร้างอินเทอร์เฟซ (ณ Xcode 6.1.1) แต่จะทำงานเมื่อแอปพลิเคชันถูกเรียกใช้
  • ฉันเคยประสบปัญหาบางอย่างกับคุณลักษณะนี้และในบางสถานการณ์ฉันต้องลบและเพิ่มไฟล์ UIImageView . ฉันไม่ได้มองลึกลงไป
  • นอกจากนี้ยังใช้งานได้ดีกับอื่น ๆUIKitComponentsเช่นรูปภาพในUIButton's และUIBarButtonItem' s
  • หากคุณมีภาพสีขาวจำนวนมากที่มองไม่เห็นในไลบรารีเนื้อหาของคุณการทำให้เป็นภาพสีดำ / โปร่งใสและการเปลี่ยนโหมดการแสดงผลจะทำให้ชีวิตของคุณดีขึ้นถึง 10 เท่า

15
ดูเหมือนจะมีข้อผิดพลาดเกี่ยวกับสีอ่อนUIImageViewดังนั้นจึงไม่แสดงสีของโทนสีเสมอเมื่อเรียกใช้แอป
หมอก

@Fogh ฉันมีข้อบกพร่องที่ไม่สอดคล้องกันเช่นนั้นเช่นกัน การตั้งค่าสีอ่อนจะแก้ไขปัญหานี้โดยทางโปรแกรมหรือไม่
Anthony Mattox

2
ฉันสามารถยืนยันได้ว่ามีปัญหาเมื่อตั้งค่าสีอ่อนใน IB การตั้งค่าให้ทำงานโดยใช้โปรแกรม ฉันยื่นข้อบกพร่อง # 20305518 สำหรับมัน
Nikolay Derkach

1
@AxelGuilmin Yup. จริงๆแล้วใช้เฉพาะช่องอัลฟาเท่านั้นดังนั้นอาจเป็นสีใดก็ได้ตราบเท่าที่ความโปร่งใสเป็นสิ่งที่คุณต้องการ
Anthony Mattox

1
ตอนนี้ใช้งานได้กับ Xcode 7.3 (7D175)! แม้ว่าคำตอบที่ยอมรับจะเป็นวิธีแก้ปัญหาที่เข้าใจง่าย แต่ฉันชอบคำตอบนี้แทน
nstein

43

การใช้โหมดการเรนเดอร์เทมเพลตด้วย UIImageView ในสตอรี่บอร์ดหรือ xib นั้นมีปัญหามากทั้งบน iOS 7 และ iOS 8

บน iOS 7

UIImage ไม่ได้ถูกถอดรหัสอย่างถูกต้องจาก storyboard / xib หากคุณตรวจสอบimageView.image.renderingModeคุณสมบัติในviewDidLoadวิธีนี้คุณจะสังเกตเห็นว่าคุณสมบัตินั้นอยู่เสมอUIImageRenderingModeAutomaticแม้ว่าคุณจะตั้งค่าเป็นRender As Template Imageก็ตามในไฟล์ xcassets ของคุณก็ตาม

ในการแก้ปัญหาคุณต้องตั้งค่าโหมดการแสดงผลด้วยตนเอง:

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

บน iOS 8

UIImage ได้รับการถอดรหัสอย่างเหมาะสมและเป็นไฟล์ renderingModeคุณสมบัติสะท้อนถึงสิ่งที่เลือกไว้ในไฟล์ xcassets แต่ภาพจะไม่ถูกย้อมสี

ในการแก้ไขปัญหาคุณมีสองทางเลือก:

  1. ตั้งค่าtintColorคุณสมบัติในแอททริบิวต์รันไทม์ที่ผู้ใช้กำหนดแทนบานหน้าต่างตัวตรวจสอบคุณสมบัติ

หรือ

  1. รีเซ็ตโทนสีด้วยตนเอง
UIColor *tintColor = self.imageView.tintColor;
self.imageView.tintColor = nil;
self.imageView.tintColor = tintColor;

คุณสามารถเลือกตัวเลือกที่คุณต้องการทั้งสองสีของภาพอย่างเหมาะสม

(หากคุณกำลังคอมไพล์ด้วย Xcode 6.2 ให้ทำไฟล์ self.imageView.tintColor = self.imageView.tintColor;ก็เพียงพอแล้ว แต่จะไม่ได้ผลอีกต่อไปหากคุณกำลังคอมไพล์ด้วย Xcode 6.3)

สรุป

หากคุณต้องการรองรับทั้ง iOS 7 และ iOS 8 คุณจะต้องมีวิธีแก้ปัญหาทั้งสองอย่าง หากคุณต้องรองรับ iOS 8 เท่านั้นจำเป็นต้องมีวิธีแก้ปัญหาเพียงวิธีเดียว


2
ขอบคุณ. วิธีแก้ปัญหาเฉพาะ # 2 เท่านั้นที่ใช้ได้กับฉันใน Xcode 7 และ iOS 8
surfrider

3
ฉันยืนยันว่าวิธีแก้ปัญหาสำหรับ iOS 8 นั้นใช้ได้กับ iOS 9 เช่นกัน
Michael Pirotte

1
ฉันเห็นสิ่งเดียวกันใน Xcode 7 อย่างแน่นอน - วิธีแก้ปัญหาแอตทริบิวต์ผู้ใช้นั้นใช้ได้ดี ขอบคุณ!
Geoffrey Wiseman

การรีเซ็ต tintColor ด้วยตนเองใน AwakenFromNib ทำได้! (รูปภาพถูกตั้งค่าเป็นเทมเพลตในแค็ตตาล็อก. xcassets ด้วยมิฉะนั้นคุณจะต้องสร้างภาพเทมเพลตจากต้นฉบับ) ขอบคุณ !!
เกือกม้า 7

15

การตั้งค่า imageView RenderingMode เพื่อใช้สีอ่อนในกระดานเรื่องราวสามารถลดลงเหลือเพียงซับเดียว:

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

จากนั้นสามารถกำหนดสีของภาพและสีอ่อนใน Storyboard ได้


13

คุณสามารถแก้ไขปัญหา. xib ด้วยส่วนขยาย:

import UIKit

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

ที่มา: https://gist.github.com/buechner/3b97000a6570a2bfbc99c005cb010bac

น่าทึ่งจุดบกพร่องนี้มีมาประมาณ 4-5 ปีแล้ว


3
ควรเลือกเป็นคำตอบ
farzadshbfn

ยังคงเป็นข้อบกพร่องและสิ่งนี้ยังคงแก้ไขได้ใน iOS 12.0
Sam Soffes

ยังคงเป็นข้อบกพร่องใน iOS 12.1
Cesare

พวกที่ไม่จริงไม่จริง
จ้า

8

คุณ cann't ตั้งrenderingModeทั้งจากหรือstoryboard xibสามารถเข้าถึงได้โดยทางโปรแกรม

เช่น:

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

3
ฉันคิดว่าคุณพิมพ์รหัสผิดเล็กน้อย บรรทัดที่สองควรเป็นUIImage *selectedImage = [unSeletedImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
Artem Stepanenko

8

ตั้งค่า tintColor & Class ใน 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
    }

}

นี่เป็นคำตอบเดียวที่ใช้ได้กับ new swift ขอขอบคุณ.
Simon Moshenko

ไม่ได้ผลสำหรับฉันด้วยเหตุผลแปลก ๆ ... มันควรจะอัปเดตสีในกระดานเรื่องราวหรือไม่
Cesare

4

มันง่ายมากที่จะแก้ไข

เพียงสร้างคลาส UIImageViewPDF และใช้ในสตอรี่บอร์ดของคุณ

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

อีกวิธีหนึ่งคือการสร้างUIImageViewคลาสย่อย:

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

แล้วก็ตั้งระดับใน Interface Builder TemplateImageViewไป


ทางออกที่ดีที่สุด !!
Irshad Mohamed

2

วิธีง่ายๆในการตั้งค่าจาก 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)
            }

        }
    }
}

ทำงานได้ดีบน iOS 10 และ Swift 3


1

ใน iOS 9 การตั้งค่าtintColorคุณสมบัติในตัวสร้างอินเทอร์เฟซยังคงเป็นปัญหา

โปรดทราบว่าวิธีแก้ปัญหาที่ใช้งานได้นอกเหนือจากการเขียนเส้นที่ปรับเปลี่ยนImageViewคุณสมบัติโดยตรงคือการตั้งค่า Render As: Template Image ในแค็ตตาล็อกเนื้อหาและเรียกเช่น:

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

1

ฉันได้รับการแก้ไขปัญหานี้โดยการเพิ่มแอตทริบิวต์ runtime tintColorในตัวสร้างอินเทอร์เฟซ

หมายเหตุ: คุณจะยังต้องตั้งค่าให้รูปภาพของคุณแสดงเป็นรูปภาพเทมเพลตในไฟล์ Images.xcassets ของคุณ

ป้อนคำอธิบายภาพที่นี่


0

หากคุณสร้าง IBOutlet คุณสามารถเปลี่ยนได้ในวิธีการ AwakenFromNib ของคุณ ...

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

แม้ว่าคำตอบของ @ Moby จะถูกต้องมากกว่า แต่ก็อาจจะรวบรัดกว่านี้


1
คำถามคือวิธีทำในสตอรีบอร์ด (หรือ xib) ไม่ใช่ในโค้ด
Artem Stepanenko

@artem - ใช่ขอโทษฉันไม่ได้ตั้งใจที่จะสรุปว่าฉันมีคำตอบสำหรับคำถามของคุณ เพียงชี้ให้เห็นวิธีง่ายๆในการจัดการกับสิ่งนี้ผ่าน IBOutlet
amergin

0

บ้าบั๊กนี้ยังอยู่ใน iOS 12.1! สำหรับสตอรี่บอร์ด / xibs: การเพิ่มแท็กใน UIImageView สามารถแก้ไขได้อย่างรวดเร็ว

สวิฟต์ 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)
       }
   }
}

ในกระดานเรื่องราวให้เลือก UIImageView และเลือกตัวตรวจสอบตั้งค่าคุณสมบัติrenderModeTemplate= On ในสตอรี่บอร์ด


0

ดังที่รูดอล์ฟได้กล่าวไว้ข้างต้นฉันจะกำหนดคลาสง่ายๆดังนี้:

import UIKit

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

TintImageหลังจากคำนิยามนี้เพียงแค่เพิ่มดูภาพลงในกระดานและเลือกชั้นเองในฐานะที่เป็น การดำเนินการนี้จะเปิดใช้งานการเลือก "สีอ่อน" ในกระดานเรื่องราว

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.