是否可以从情节提要或 xib 编辑器修改 a UIImage
?renderingMode
目标是应用于tintColor
特定UIImageView
对象。
是否可以从情节提要或 xib 编辑器修改 a UIImage
?renderingMode
目标是应用于tintColor
特定UIImageView
对象。
您可以不在.xib
文件中设置图像渲染模式,而是在.xcassets
库中设置。
将图像添加到资产库后,选择图像并打开 Xcode 右侧的属性检查器。找到属性“渲染为”并将其设置为“模板”。
UIImageView
设置图像的渲染模式后,您可以在文件.xib
或文件中添加色调颜色.storyboard
以调整图像颜色。
这会在图像上的任何位置设置属性,而不仅仅是在一个界面构建器文件中,但在几乎所有情况下(我遇到过),这都是您想要的行为。
需要注意的几点:
UIImageView
. 我没有深入研究过。UIKitComponents
图像,例如UIButton
's 和UIBarButtonItem
's 中的图像。以下是在 .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)
}
}
然后在 xib 文件的 Identity Inspector 中,添加一个运行时属性:
在 iOS 7 和 iOS 8 上,在故事板或 xib 中使用带有 UIImageView 的模板渲染模式是非常错误的。
UIImage 未从情节提要/xib 正确解码。如果您检查方法imageView.image.renderingMode
中的属性viewDidLoad
,您会注意到它总是UIImageRenderingModeAutomatic
,即使您在 xcassets 文件中将其设置为Render As Template Image也是如此。
要解决此问题,您必须手动设置渲染模式:
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 设置为使用情节提要中的 tint 颜色可以简化为单行:
[self.imageView setImage:[self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]];
然后可以在情节提要中设置图像和色调颜色。
您可以通过扩展修复 .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 年了。
您不能设置renderingMode
fromstoryboard
或xib
. 它可以通过编程方式访问。
前任:
UIImage *unSeletedImage = [UIImage imageNamed:@"UnSelected.png"];
selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
在 Storyboard 中设置 tintColor 和 Class。
//
// 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
在 Interface Builder 中设置属性仍然存在问题。
请注意,除了编写直接修改ImageView
属性的行之外,一个可行的解决方案是在资产目录中设置渲染为:模板图像,并调用例如:
[[UIImageView appearanceWhenContainedInInstancesOfClasses:@[[MyView class]]] setTintColor:[UIColor whiteColor]];
如果你创建一个 IBOutlet 你可以在你的 awakeFromNib 方法中改变它,就像这样......
self.myImageView.image = [self.myImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
虽然@Moby 的回答更正确——这可能更简洁。
extension UIImageView {
@IBInspectable var renderModeTemplate : Bool {
get{
return image?.renderingMode == .alwaysTemplate
}
set{
image = image?.withRenderingMode(newValue ? .alwaysTemplate:.alwaysOriginal)
}
}
}
在情节提要中选择 UIImageView 并选择检查器,设置属性renderModeTemplate
=On
在情节提要中
疯狂的这个 bug 还在 iOS 12.1 中!对于故事板/xib:向 UIImageView 添加标签可以快速修复。
斯威夫特 4.2
view.viewWithTag(1)?.tintColorDidChange()
正如鲁道夫在上面也提到的,我会定义一个简单的类,如下所示:
import UIKit
@IBDesignable class TintImage: UIImageView{
override func layoutSubviews() {
super.layoutSubviews()
image = image?.withRenderingMode(.alwaysTemplate)
}
}
在此定义之后,只需将图像视图添加到情节提要并选择其自定义类为TintImage
. 这将激活情节提要中的“色调”选择。