ios 从 storyboard/xib 文件修改 UIImage 渲染模式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19517334/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Modify UIImage renderingMode from a storyboard/xib file
提问by Artem Stepanenko
Is it possible to modify a UIImage
's renderingMode
from a storyboard or xib editor?
是否有可能修改UIImage
的renderingMode
从故事板或XIB编辑器?
The goal is to apply tintColor
to the particular UIImageView
object.
目标是应用于tintColor
特定UIImageView
对象。
回答by Anthony Mattox
You can set the image rendering mode not in the .xib
file, but in an .xcassets
library.
您可以不在.xib
文件中设置图像渲染模式,而可以在.xcassets
库中设置。
After adding an image to an asset library, select the image and open the attributes inspector on the right side of Xcode. Find the attribute 'Render As' and set it to 'template'.
将图像添加到资产库后,选择图像并打开 Xcode 右侧的属性检查器。找到属性“渲染为”并将其设置为“模板”。
After setting an image's rendering mode, you can add a tint color to the UIImageView
in a .xib
or .storyboard
file to adjust the image color.
设置图像的渲染模式后,您可以UIImageView
在 a.xib
或.storyboard
文件中添加色调颜色以调整图像颜色。
This sets the property on the image wherever it's used rather than just in one interface builder file, but in almost all cases (that I've encountered) this is the behavior you want.
这会在图像的任何位置设置属性,而不仅仅是在一个界面构建器文件中,但在几乎所有情况下(我遇到过),这都是您想要的行为。
A few things to note:
需要注意的几点:
- The image color will not appear to have changed in interface builder (as of Xcode 6.1.1) but will work when the application is run.
- I've experienced some bugginess with this feature and in some situations I've had to remove and re-add the
UIImageView
. I have not looked into that deeply. - This also works great on other
UIKitComponents
such as images inUIButton
's andUIBarButtonItem
's. - If you have a bunch of white images that are invisible in your asset library, making them black/transparent images and changing the rendering mode will make your life up to 10x better.
- 图像颜色在界面构建器中似乎没有改变(从 Xcode 6.1.1 开始),但在应用程序运行时会起作用。
- 我在此功能上遇到了一些问题,在某些情况下,我不得不删除并重新添加
UIImageView
. 我没有深入研究过。 - 这也适用
UIKitComponents
于UIButton
's 和UIBarButtonItem
's 中的其他图像。 - 如果您有一堆在您的资产库中不可见的白色图像,将它们设为黑色/透明图像并更改渲染模式将使您的生活质量提高 10 倍。
回答by Snowman
Here's how you can do it in .xib or storyboard files:
以下是在 .xib 或故事板文件中执行此操作的方法:
(Obj-C) Create a category on UIImageView
:
(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) Create an extension for UIImageView
:
(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)
}
}
Then in the Identity Inspector in the xib file, add a runtime attribute:
然后在xib文件中的Identity Inspector中,添加一个runtime属性:
回答by 0xced
Using the template rendering mode with a UIImageView in a storyboard or xib is very buggy, both on iOS 7 and iOS 8.
在故事板或 xib 中使用带有 UIImageView 的模板渲染模式是非常错误的,无论是在 iOS 7 还是 iOS 8 上。
On iOS 7
在 iOS 7 上
The UIImage is not properly decoded from the storyboard/xib. If you inspect the imageView.image.renderingMode
property in the viewDidLoad
method, you will notice that it is always UIImageRenderingModeAutomatic
, even if you set it to Render As Template Imagein your xcassets file.
UIImage 未从故事板/xib 正确解码。如果您检查方法中的imageView.image.renderingMode
属性viewDidLoad
,您会注意到它始终为UIImageRenderingModeAutomatic
,即使您在 xcassets 文件中将其设置为Render As Template Image。
To workaround, you have to manually set the rendering mode:
要解决此问题,您必须手动设置渲染模式:
self.imageView.image = [self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
On iOS 8
在 iOS 8 上
The UIImage is properly decoded and its renderingMode
property reflects what was chosen in the xcassets file but the image is not tinted.
UIImage 被正确解码,其renderingMode
属性反映了在 xcassets 文件中选择的内容,但图像没有着色。
To workaround, you have two options:
要解决此问题,您有两个选择:
- Set the
tintColor
property in the User Defined Runtime Attributesinstead of the Attributes inspector pane.
- 设置
tintColor
在属性定义运行时用户属性而不是属性检查器窗格。
or
或者
- Manually reset the tintColor:
- 手动重置 tintColor:
UIColor *tintColor = self.imageView.tintColor;
self.imageView.tintColor = nil;
self.imageView.tintColor = tintColor;
You can pick your preferred option, both properly tint the image.
您可以选择您喜欢的选项,都可以正确地为图像着色。
(If you are compiling with Xcode 6.2, just doing self.imageView.tintColor = self.imageView.tintColor;
is enough but this doesn't work anymore if you are compiling with Xcode 6.3)
(如果您使用 Xcode 6.2 进行编译,只需这样做self.imageView.tintColor = self.imageView.tintColor;
就足够了,但是如果您使用 Xcode 6.3 进行编译,这将不再起作用)
Conclusion
结论
If you need to support both iOS 7 and iOS 8, you'll need both workarounds. If you only have to support iOS 8, only one workaround is needed.
如果您需要同时支持 iOS 7 和 iOS 8,则需要两种解决方法。如果您只需要支持 iOS 8,则只需要一种解决方法。
回答by middleseatman
Setting imageView RenderingMode to use the tint color in the storyboard can be reduced to a one-liner:
将 imageView RenderingMode 设置为在故事板中使用色调颜色可以简化为单行:
[self.imageView setImage:[self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]];
Then the image and tint color can all be set in the Storyboard.
然后图像和色调颜色都可以在 Storyboard 中设置。
回答by nikans
You may fix .xib issues with an extension:
您可以使用扩展名修复 .xib 问题:
import UIKit
// fixing Bug in XCode
// http://openradar.appspot.com/18448072
extension UIImageView {
override open func awakeFromNib() {
super.awakeFromNib()
self.tintColorDidChange()
}
}
Source: https://gist.github.com/buechner/3b97000a6570a2bfbc99c005cb010bac
来源:https: //gist.github.com/buechner/3b97000a6570a2bfbc99c005cb010bac
Amazing, this bug has been around for like 4-5 years now.
太神奇了,这个错误已经存在大约 4-5 年了。
回答by Dmitry Coolerov
Set tintColor & Class in Storyboard.
在 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
}
}
回答by Mani
You cann't set renderingMode
either from storyboard
or xib
. It could access by programmatically.
您不能设置renderingMode
fromstoryboard
或xib
。它可以通过编程方式访问。
ex:
前任:
UIImage *unSeletedImage = [UIImage imageNamed:@"UnSelected.png"];
selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
回答by Igor Popov
It's very easy to fix
很容易修复
Just create class UIImageViewPDF and use it in your storyboard
只需创建类 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
回答by Rudolf Adamkovi?
Another solution is to create a UIImageView
subclass:
另一种解决方案是创建一个UIImageView
子类:
final class TemplateImageView: UIImageView {
override func awakeFromNib() {
super.awakeFromNib()
guard let oldImage = image else { return }
image = nil
image = oldImage.withRenderingMode(.alwaysTemplate)
}
}
Then just set the class in the Interface Builder to TemplateImageView
.
然后只需将 Interface Builder 中的类设置为TemplateImageView
.
回答by Rodrigo
Simple way to be set from Storyboard:
从 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)
}
}
}
}
Works fine on iOS 10 and Swift 3
在 iOS 10 和 Swift 3 上运行良好