如何在prepareForInterfaceBuilder加载的图像与IBDesignable的UIImageView

问题描述 投票:23回答:7

我想在一个IB外观性UIImageView加载的样本图像,在界面生成要显示在编辑界面。下面的代码无法正常工作,在IB视图占位符保持为空(视图区域仅包含文本的UIImageView):

@IBDesignable
class TestImageView : UIImageView
{
    override func prepareForInterfaceBuilder() {
        //let bundle = NSBundle.mainBundle()
        let bundle = NSBundle(forClass: nil)
        let imagePath = bundle.pathForResource("Test", ofType: "jpg")
        self.image = UIImage(contentsOfFile: imagePath)
    }
}

注意:

  • 在IB视图的自定义类类是正确的(TestImageView)
  • test.jpg放在存在于项目(如果我手动设置UIImageView的图像属性中IB的图像显示出来)。
  • 我试图获得本束中的代码的两种不同的方法

将其用的Xcode 6的β3测试。

更新:在这两种情况下的束路径我得到的是"/Applications/Temporary/Xcode6-Beta3.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Overlays"。在这条道路的形象显然是不存在的。

ios uiimageview swift
7个回答
19
投票

更新了雨燕4.2

当你初始化的UIImage(用的UIImage(命名为:“SomeName”)的应用程序将寻找资产在你的主束,其工作方式通常正常,但当你在设计时,在InterfaceBuilder中持有的外观性意见的代码(。为在一个单独的束而设计编译)。

因此,解决办法是:动态地定义你的包,因此您的文件可以在设计中找到,编译和运行时间:

    // DYNAMIC BUNDLE DEFINITION FOR DESIGNABLE CLASS
    let dynamicBundle = Bundle(for: type(of: self))

    // OR ALTERNATIVELY BY PROVDING THE CONCRETE NAME OF YOUR DESIGNABLE VIEW CLASS
    let dynamicBundle = Bundle(for: YourDesignableView.self)

    // AND THEN SUCCESSFULLY YOU CAN LOAD THE RESSOURCE
    let image = UIImage(named: "Logo", in: dynamicBundle, compatibleWith: nil)

53
投票

尝试让这样的类的包:

let bundle = NSBundle(forClass: self.dynamicType)

或指定的类名像这样

let bundle = NSBundle(forClass: TestImageView.self)

假设你的形象是在捆绑,例如Images.xcassets,您可以然后使用加载它:

self.image = UIImage("Test", inBundle: bundle, compatibleWithTraitCollection: self.traitCollection)

记住要检查你的形象是否试图使用它之前为零。我一直无法使用bundle.pathForResource与正常图像资产正常工作来获得图像路径。目前还没有出现要在那里你仅指定名称和捆绑一个UIImage调用,因此你必须使用特性集合。

这个问题是有关:

xcode 6 IB_DESIGNABLE- not loading resources from bundle in Interface builder

苹果回应...

工程已确定基于以下按预期这个问题表现:

我们真的不能让这个不是指定的包变得更容易。你可能会说,“哦,让我们来调酒 - [一个NSBundle mainBundle]”,但很多电话网站的引用捆不经过那里去(或经过CF API)。有人可能会说,然后“确定,以及然后怎么样,我们至少调酒 - [UIImage的imageNamed:]”。这里的问题是,有主束没有单一的替代品。您可能需要在加载一次多重实时取景束(无论是框架或应用程序),所以我们不能只挑一个作为主束。

开发人员需要了解捆绑,以及如何从包获得的图像。开发者应该使用的UIImage(命名为:inBundle:compatibleWithTraitCollection :)所有图像查找。


7
投票

让流行在迅速3回答

let bundle = Bundle(for: self.classForCoder)
... UIImage(named: "AnImageInYourAssetsFolderPerhaps", in: bundle, compatibleWith: self.traitCollection)!

5
投票

我能得到修复从目前NSProcessInfoobject界面生成项目路径的问题。然后,您可以收集来自IB_PROJECT_SOURCE_DIRECTORIESkey的正确路径。

override func prepareForInterfaceBuilder() {
    let processInfo = NSProcessInfo.processInfo()
    let environment = processInfo.environment
    let projectSourceDirectories : AnyObject = environment["IB_PROJECT_SOURCE_DIRECTORIES"]!
    let directories = projectSourceDirectories.componentsSeparatedByString(":")

    if directories.count != 0 {
        let firstPath = directories[0] as String
        let imagePath = firstPath.stringByAppendingPathComponent("PrepareForIBTest/Test.jpg")

        let image = UIImage(contentsOfFile: imagePath)
        self.image = image
    }
}

这种技术在WWDC 2014 411届“有什么新在Interface Builder”在此Apple Developer Forums post bjhomer的建议说明。

此外,我必须说,这是需要切换到UIView子类,因为它似乎UIImageViewdoes的appereance不活观念的转变。


5
投票

为SWIFT 4(3)使用此:

let image = UIImage(named: "foo", in: Bundle(for: type(of: self)), compatibleWith: traitCollection)

这种做法得到普遍捆绑


0
投票

这将加载您IB_Designable,或者如果你有没有 - 默认图像。

- (void)prepareForInterfaceBuilder
{
    NSBundle *bundle = [NSBundle bundleForClass:[self class]];
    imagePic = imagePic ? [imagePic imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] : [UIImage imageNamed:@"goodIcon" inBundle:bundle compatibleWithTraitCollection:self.traitCollection];

}

0
投票

为SWIFT 2和7的Xcode,接口已被更改。应该使用

let bundle = NSBundle(forClass: self.dynamicType)
let image = UIImage(named: "imageName", inBundle: bundle, compatibleWithTraitCollection: self.traitCollection)
let imageView = UIImageView(image: image)

我用它在my project,它工作正常两种IB和设备。

© www.soinside.com 2019 - 2024. All rights reserved.