มันเป็นไปได้ที่จะปรับเปลี่ยนUIImage
's renderingMode
จากกระดานหรือ Xib แก้ไข?
เป้าหมายคือการนำtintColor
ไปใช้กับUIImageView
วัตถุนั้น ๆ
มันเป็นไปได้ที่จะปรับเปลี่ยนUIImage
's renderingMode
จากกระดานหรือ Xib แก้ไข?
เป้าหมายคือการนำtintColor
ไปใช้กับUIImageView
วัตถุนั้น ๆ
คำตอบ:
นี่คือวิธีที่คุณสามารถทำได้ในไฟล์. 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 ให้เพิ่มแอ็ตทริบิวต์รันไทม์:
คุณสามารถตั้งค่าโหมดการแสดงภาพไม่ได้อยู่ใน.xib
ไฟล์ แต่อยู่ใน.xcassets
ไลบรารี
หลังจากเพิ่มรูปภาพลงในไลบรารีเนื้อหาแล้วให้เลือกรูปภาพและเปิดตัวตรวจสอบคุณสมบัติทางด้านขวาของ Xcode ค้นหาแอตทริบิวต์ "Render As" และตั้งค่าเป็น "template"
หลังจากตั้งค่าโหมดการแสดงผลของภาพแล้วคุณสามารถเพิ่มสีอ่อนลงในไฟล์ UIImageView
ในไฟล์.xib
หรือ.storyboard
ไฟล์เพื่อปรับสีของภาพได้
สิ่งนี้ตั้งค่าคุณสมบัติบนรูปภาพทุกที่ที่มีการใช้งานไม่ใช่แค่ในไฟล์ตัวสร้างอินเทอร์เฟซเดียว แต่ในเกือบทุกกรณี (ที่ฉันเคยพบ) นี่เป็นพฤติกรรมที่คุณต้องการ
สิ่งที่ควรทราบ:
UIImageView
. ฉันไม่ได้มองลึกลงไปUIKitComponents
เช่นรูปภาพในUIButton
's และUIBarButtonItem
' sUIImageView
ดังนั้นจึงไม่แสดงสีของโทนสีเสมอเมื่อเรียกใช้แอป
การใช้โหมดการเรนเดอร์เทมเพลตด้วย UIImageView ในสตอรี่บอร์ดหรือ xib นั้นมีปัญหามากทั้งบน iOS 7 และ iOS 8
UIImage ไม่ได้ถูกถอดรหัสอย่างถูกต้องจาก storyboard / xib หากคุณตรวจสอบimageView.image.renderingMode
คุณสมบัติในviewDidLoad
วิธีนี้คุณจะสังเกตเห็นว่าคุณสมบัตินั้นอยู่เสมอUIImageRenderingModeAutomatic
แม้ว่าคุณจะตั้งค่าเป็นRender As Template Imageก็ตามในไฟล์ xcassets ของคุณก็ตาม
ในการแก้ปัญหาคุณต้องตั้งค่าโหมดการแสดงผลด้วยตนเอง:
self.imageView.image = [self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIImage ได้รับการถอดรหัสอย่างเหมาะสมและเป็นไฟล์ renderingMode
คุณสมบัติสะท้อนถึงสิ่งที่เลือกไว้ในไฟล์ xcassets แต่ภาพจะไม่ถูกย้อมสี
ในการแก้ไขปัญหาคุณมีสองทางเลือก:
tintColor
คุณสมบัติในแอททริบิวต์รันไทม์ที่ผู้ใช้กำหนดแทนบานหน้าต่างตัวตรวจสอบคุณสมบัติหรือ
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 เท่านั้นจำเป็นต้องมีวิธีแก้ปัญหาเพียงวิธีเดียว
การตั้งค่า imageView RenderingMode เพื่อใช้สีอ่อนในกระดานเรื่องราวสามารถลดลงเหลือเพียงซับเดียว:
[self.imageView setImage:[self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]];
จากนั้นสามารถกำหนดสีของภาพและสีอ่อนใน Storyboard ได้
คุณสามารถแก้ไขปัญหา. 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 ปีแล้ว
คุณ cann't ตั้งrenderingMode
ทั้งจากหรือstoryboard
xib
สามารถเข้าถึงได้โดยทางโปรแกรม
เช่น:
UIImage *unSeletedImage = [UIImage imageNamed:@"UnSelected.png"];
selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
UIImage *selectedImage = [unSeletedImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
ตั้งค่า 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
}
}
มันง่ายมากที่จะแก้ไข
เพียงสร้างคลาส 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
อีกวิธีหนึ่งคือการสร้าง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
ไป
วิธีง่ายๆในการตั้งค่าจาก 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
ใน iOS 9 การตั้งค่าtintColor
คุณสมบัติในตัวสร้างอินเทอร์เฟซยังคงเป็นปัญหา
โปรดทราบว่าวิธีแก้ปัญหาที่ใช้งานได้นอกเหนือจากการเขียนเส้นที่ปรับเปลี่ยนImageView
คุณสมบัติโดยตรงคือการตั้งค่า Render As: Template Image ในแค็ตตาล็อกเนื้อหาและเรียกเช่น:
[[UIImageView appearanceWhenContainedInInstancesOfClasses:@[[MyView class]]] setTintColor:[UIColor whiteColor]];
หากคุณสร้าง IBOutlet คุณสามารถเปลี่ยนได้ในวิธีการ AwakenFromNib ของคุณ ...
self.myImageView.image = [self.myImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
แม้ว่าคำตอบของ @ Moby จะถูกต้องมากกว่า แต่ก็อาจจะรวบรัดกว่านี้
บ้าบั๊กนี้ยังอยู่ใน iOS 12.1! สำหรับสตอรี่บอร์ด / xibs: การเพิ่มแท็กใน UIImageView สามารถแก้ไขได้อย่างรวดเร็ว
สวิฟต์ 4.2
view.viewWithTag(1)?.tintColorDidChange()
extension UIImageView {
@IBInspectable var renderModeTemplate : Bool {
get{
return image?.renderingMode == .alwaysTemplate
}
set{
image = image?.withRenderingMode(newValue ? .alwaysTemplate:.alwaysOriginal)
}
}
}
ในกระดานเรื่องราวให้เลือก UIImageView และเลือกตัวตรวจสอบตั้งค่าคุณสมบัติrenderModeTemplate
= On
ในสตอรี่บอร์ด
ดังที่รูดอล์ฟได้กล่าวไว้ข้างต้นฉันจะกำหนดคลาสง่ายๆดังนี้:
import UIKit
@IBDesignable class TintImage: UIImageView{
override func layoutSubviews() {
super.layoutSubviews()
image = image?.withRenderingMode(.alwaysTemplate)
}
}
TintImage
หลังจากคำนิยามนี้เพียงแค่เพิ่มดูภาพลงในกระดานและเลือกชั้นเองในฐานะที่เป็น การดำเนินการนี้จะเปิดใช้งานการเลือก "สีอ่อน" ในกระดานเรื่องราว