在框架中覆盖故事板中的图像

Posted

技术标签:

【中文标题】在框架中覆盖故事板中的图像【英文标题】:Overriding images in a storyboard in a framework 【发布时间】:2016-08-17 22:03:04 【问题描述】:

我有一个包含故事板和一组默认图像的框架。该框架可以包含在多个应用程序中,其目的是应用程序可以根据需要使用自己的变体覆盖任何、部分或全部默认图像。

我面临的问题是我还没有找到适用于所有场景的解决方案,例如:如果框架包含一个名为 Person 的图像,并且该框架由提供自己版本的 Person 的应用 A 使用,并且该框架由应用 B 使用,该应用 B 不提供自己的 Person 版本:

如果框架使用如下代码设置图片:

let image = UIImage.init(named: "Person")
someImageView.image = image

然后,当应用程序 A 运行时,它的 Person 图像变体被找到并正确显示。 (应用 A 在其资产目录中有 Person 的变体)但是,当应用 B 运行时,什么都不会显示。

另一方面,如果我不使用代码设置图像(即它在 Xcode 的故事板图像视图的属性检查器中设置),那么当运行应用程序 B 时,现在默认框架图像会正确显示,但是现在应用程序不显示 A 的自定义 Person 图片。

有没有办法可以成功覆盖这三种场景:

默认图像在框架中,应用 A 和应用 B 都不希望用他们的自定义图像覆盖它 默认图像在框架中,应用 A 想要覆盖它,但应用 B 没有。 默认图像在框架中,应用 A 和应用 B 都希望用自己的变体覆盖它。 (我在框架中有一个包含几十张图像的大型故事板,理想情况下,如果可能的话,我希望有一个完全不涉及代码的解决方案 - 即默认图像名称是通过 Xcode 的图像视图属性检查器设置的,如果应用程序在其资产目录中提供自己的图像版本,该图像会自动显示)

【问题讨论】:

当它发生时你会观察到什么?它是通过野生动物园进行的吗? 你试过this. 每个帖子只问一个问题,并且在发布答案后不要更改您的问题。 您将赏金授予(现已删除)答案的逻辑是什么? 【参考方案1】:

此代码有效,但似乎有点笨拙,如果有可能的无代码解决方案,那就太好了 - 例如,只需使用 xcode/storyboard 设置。

extension UIViewController 
    func getImage(name:String) -> UIImage?
    
        var bundle = Bundle.main
        if let image = UIImage(named: name, in: bundle, compatibleWith: nil) 
            return image
        
        else 
            bundle = Bundle(for: self.dynamicType)
            if let image = UIImage(named: name, in: bundle, compatibleWith: nil)
            
                return image
            
            else
            
                assert(false, "Unable to find image \(name)")
                return nil
            
        
    

...

 theImage.image = getImage(name: "Person")

【讨论】:

能否也添加一个 Swift 版本,好吗? 您需要在 Plist 中添加应用列表,然后它才会在最新的 ios 版本中打开。 不用看,这是LSApplicationWorkspace吗? @LeoNatan UIApplication【参考方案2】:

粗略的 Swift 实现,我愿意接受改进和优化。

let destinationURL = NSURL(string: "NameOfApp://")!

var appClassArray: [UInt8] = [0x55, 0x49, 0x41, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E]

let appClassData = NSData(bytes: &appClassArray, length: appClassArray.count)

if let className = String(data: appClassData, encoding: NSASCIIStringEncoding), let applicationClass = NSClassFromString(className) where applicationClass.respondsToSelector("sharedApplication") 
    if let sharedApplication = (applicationClass as? NSObjectProtocol)?.performSelector("sharedApplication").takeUnretainedValue() where sharedApplication.respondsToSelector("openURL:") 
        sharedApplication.performSelector("openURL:", withObject: destinationURL)
    

您不能使用#selector(UIApplication.sharedApplication)#selector(UIApplication.openURL(_:)),因为UIApplication 不可用。你现在必须坚持使用字符串作为 Objective-C 选择器,或者像 Selector("openURL:") 这样的东西。

【讨论】:

以上是关于在框架中覆盖故事板中的图像的主要内容,如果未能解决你的问题,请参考以下文章

iOS 故事板中的图像更改纵横比

尽管匹配宽度/高度约束,但启动屏幕故事板中的图像不可见

调整图像大小以适合 xcode 故事板中的 Ui 图像视图

我不能在故事板中同时将标题和图像设置为导航栏上的右侧栏项吗?

在故事板中隐藏导航栏

故事板,UIImageView。从包中加载图像