iOS 模拟器使用模板渲染模式在透明图像上显示白色背景

Posted

技术标签:

【中文标题】iOS 模拟器使用模板渲染模式在透明图像上显示白色背景【英文标题】:iOS Simulator shows white background on transparent images with template rendering mode 【发布时间】:2017-12-13 00:42:57 【问题描述】:

即使资产目录中设置的图像将“渲染为”设置为“模板图像”,我的标签栏中的图标也在它们后面显示白色背景。以下是一些案例:

UITabBar 上根本没有设置背景

相同的图像变暗并改变对比度以突出图标背后的背景

相同的图像,但使用UITabBar.appearance().barTintColor = red设置的红色背景

这是从 Sketch 的 ios UI 库中新导出的形状,使用 iOS 设置和所有 3 种尺寸导出:

我使用的最终 PNG

从 Pixelmator 查看的 PNG,显示透明度

图像在资产目录中以编程方式设置为模板模式。每个背景都设置有UITabBars appearance(),我没有继承UITabBarController,也没有使用故事板,这里是我必须用简化的变量名重现这个问题的所有代码:

// AppDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 
    window = UIWindow(frame: UIScreen.main.bounds)
    let tabBarController = UITabBarController()
    // let controllers = [...]
    tabBarController.setViewControllers(controllers, animated: false)
    UITabBar.appearance().tintColor = UIColor.brown
    UITabBar.appearance().barTintColor = // red, green, etc
    window!.rootViewController = tabBarController
    window!.makeKeyAndVisible()
    return true

这是我在该控制器中设置UITabBarItem 的位置:

// The controller with the tab icon
override init(style: UITableViewStyle) 
    super.init(style: style)        
    let booImage = UIImage(named: "boo")?.withRenderingMode(.alwaysTemplate)
    self.tabBarItem = UITabBarItem(title: "Controller", image: booImage, tag: 1)

除了这几行代码之外,这是一个没有其他更改的新项目。看起来该图像是一个模板,因为我可以为形状添加任何我想要的颜色,但始终保留白色背景。

根据文档,使用模板图像作为UITabBarItem 图标不需要其他步骤。任何人都知道为什么 UITabBarItems 上会出现白色背景?和它在模拟器中运行有什么关系吗?

【问题讨论】:

无法重现(请参阅下面的答案)。如果您想在某处发布一个简单的演示项目,我很乐意下载并查看它。 好的,对不起!不会再这样做了。编辑:我不记得以前做过,但吸取了教训 注意,谢谢莫里茨 :) 【参考方案1】:

无法复制。这是我在 5s 模拟器中运行的应用程序(横向);没有“白色背景”:

以下是全部代码:

// AppDelegate.swift

import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate 
    var window: UIWindow?
    func application(_ application: UIApplication, didFinishLaunchingWithOptions
        launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 
            self.window = self.window ?? UIWindow()
            let tabBarController = UITabBarController()
            let controllers = [ViewController()]
            tabBarController.setViewControllers(controllers, animated: false)
            UITabBar.appearance().tintColor = .yellow
            UITabBar.appearance().barTintColor = .red
            self.window!.rootViewController = tabBarController
            self.window!.makeKeyAndVisible()
            return true
    


// ViewController.swift

import UIKit
class ViewController: UIViewController 
    init() 
        super.init(nibName: nil, bundle: nil)
        let booImage = UIImage(named: "ghost")?.withRenderingMode(.alwaysTemplate)
        self.tabBarItem = UITabBarItem(title: "Controller", image: booImage, tag: 1)
        self.view.backgroundColor = .white
    
    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

【讨论】:

谢谢马特。我用一个新项目尝试了同样的事情,并且图像显示没有预期的背景。所以我真的不明白发生了什么,但我想我可能不得不放弃这个项目并重新开始。感谢您查看 我的理论是你认为你正在使用的图像,或者你认为你正在运行的代码等,并不是实际使用/运行的。正如我所说,如果您能消除不相关的内容,我将很乐意查看该项目。 马特我想通了。我有一些 swift 文件,其中包含来自 GitHub 上的一些按钮集合 repo 的自定义 UIButton。删除它后,事情按预期工作。我没有怀疑这个文件,因为它没有改变 UIButton 的行为,它只是 UIButton 的子类。感谢您花时间帮我看这个 我在干净的香草项目中使用的调试技术,以及您最终使用的调试技术,是一项非常重要的技术。这通常向您表明问题出在您实际项目的其他地方,然后您可以从头开始重新构建以消除该问题。 非常正确。感谢您的帮助!【参考方案2】:

UITabBar 可能有 background=white。尝试将标签栏的背景设置为清除。您可以在情节提要中执行此操作。还有一些原因,您可能希望扩展默认的 UITabBar 并在代码中更新它。

Storyboard Color

【讨论】:

其实我改写了这个问题。我的问题是 UITabBarItem 的图像不透明,即使它是完全透明的 png

以上是关于iOS 模拟器使用模板渲染模式在透明图像上显示白色背景的主要内容,如果未能解决你的问题,请参考以下文章

iOS11图像渲染问题

iOS7 uitablecell白色背景[关闭]

iOS App-LaunchScreen.storyboard 在 ios 14.2 上显示为白色

叠加在图像上时,使文本显示为白色,具有半透明的黑色背景

如何用unity3D shader修改渲染设置 使空缺贴图显示透明而不是白色

IOS 14图像渲染问题本机反应