A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

想象你正在干活,你的上级要求你在工程中加入一些图片。你找到团队中的设计师(如果你们有一个的话),鼓起勇气,问他要这些图片。不过,通常他都会忙得根本没时间帮你。因为他要做的活儿比你还多。说实话,你到底见过一个设计师有多少活儿要做吗?!简直多到令人发指啊!所以你最不想做的就是成为那个再给他加活儿的人了。特别是那些活儿对设计师来说简单得让人厌烦。更不用说,设计师也要按顺序干活,你拿到那些图片也是几天之后了。所以我们还是来看看如何用Xcode 的Asset Catalog来处理这些麻烦事吧。

麻烦事No.1:“能改一下这个图片的颜色吗?”

目前为止iOS已经提供了一些相当复杂的方法来处理工程中的图片,但很不幸的是,却没有用来处理这种情况的方法。我已经数不清楚有多少次我们因为什么便捷性支持或者是客户不喜欢而改变工程的颜色了。现在在工程中全局改变UIColor已经不是什么难题了,但是我们还要改变工程中图片的颜色。这样我们就不得不回去找已经忙得要死的设计师了,就因为我们太懒而不去学学怎么用Photoshop。当然我们也可以写代码来完成,不过看起来相当复杂,而且还容易造成泄漏。在iOS7 之前,写代码改变图片的颜色和下面差不多(还有很多其他的方法):

class func image(name: String, withColor color: UIColor) -> UIImage? {     if var image = UIImage(named: name) {         // begin a new image context, to draw our colored image onto. Passing in zero for scale tells the system to take from the current device's screen scale.         UIGraphicsBeginImageContext(image.size, false, 0)                 // get a reference to that context we created         let context = UIGraphicsGetCurrentContext()                 // set the context's fill color         color.setFill()                 // translate/flip the graphics context (for transforming from CoreGraphics coordinates to default UI coordinates. The Y axis is flipped on regular coordinate systems)         CGContextTranslateCTM(context, 0.0, image.size.height)         CGContextScaleCTM(context, 1.0, -1.0)                 // set the blend mode to color burn so we can overlay our color to our image.         CGContextSetBlendMode(context, kCGBlendModeColorBurn)         let rect = CGRect(origin: CGPointZero, size: image.size)         CGContextDrawImage(context, rect, image.CGImage)                 // set a mask that matches the rect of the image, then draw the color burned context path.         CGContextClipToMask(context, rect, image.CGImage)         CGContextAddRect(context, rect)         CGContextDrawPath(context, kCGPathFill)                 // generate a new UIImage from the graphics context we've been drawing onto         image = UIGraphicsGetImageFromCurrentImageContext()         UIGraphicsEndImageContext()             return image     }     return nil }

在两个大版本升级之后,我还能看到这样的代码。在iOS7中,我们有了imageWithRenderingMode,这是UIImage的一个方法,参数是有三个选项的枚举值UIImageRenderingMode。

typedef NS_ENUM(NSInteger, UIImageRenderingMode) {     UIImageRenderingModeAutomatic,          // Use the default rendering mode for the context where the image is used     UIImageRenderingModeAlwaysOriginal,     // Always draw the original image, without treating it as a template     UIImageRenderingModeAlwaysTemplate,     // Always draw the image as a template image, ignoring its color information } NS_ENUM_AVAILABLE_IOS(7_0);
  • UIImageRenderingModeAlwaysOriginal  就和字面的意思一样,这个模式告诉系统按照图片文件原来的样子渲染图片。
  • UIImageRenderingModeAlwaysTemplate 这是最有意思的模式。首先会扫描你的图片,然后从图片中所有不透明的像素创建一个模板。这同时也会忽略图片的所有颜色信息。你可以使用UIView子类的tintColor属性来给图片填充你选择的颜色。
  • UIImageRenderingModeAutomatic 这个模式由系统根据图片的使用环境来决定如何渲染图片。如果你的图片是用在比如UITabBar、UINavigationBar、UIToolbar 和UISegmentedControl这些地方,图片使用AlwaysTemplate渲染模式。图片用在其他的地方则会使用AlwaysOriginal渲染模式。

在了解了上面的内容之后,之前我们改变图片颜色的代码就可以简化成下面这样的了:

if var imageToChange = imageView.image?.imageWithRenderingMode(.AlwaysTemplate) {     imageView.image = imageToChange     imageView.tintColor = .redColor() //Setting the tint color is what changes the color of the image itself! }

是不是很神奇?用代码改变图片的颜色,现在变得简单多了。

等等,还没完呢!其实不需要代码也可以改变图片的颜色。

从Xcode 6开始,imageWithRenderingMode已经集成到Asset Catalog里了。如果你在Asset Catalog里选择了一个图片,在右边的Attributes Inspector里,就可以像下图那样把Render As选项改成Template Image。

就是这么简单。甚至你还可以通过在Storyboard中,在Attributes Pane中改变UIImageView的tintColor属性,来改变imageView中的图片的颜色。


1 个回复

倒序浏览
菜鸟表示有点难
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马