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