2014-07-10 26 views
18

我希望在IB可編程的UIImageView中加載示例圖像,以便在編輯界面時在Interface Builder中顯示。下面的代碼無法正常工作,在IB視圖佔位符保持爲空(視圖區域僅包含UIImageView的文字):如何使用IBDesignable在prepareForInterfaceBuilder中加載圖像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存在於項目中(如果我在IB中手動設置UIImageView的圖像屬性,圖像顯示出來)。
  • 我試圖讓本捆綁在代碼

的這是在Xcode 6公測3

更新測試了兩種不同的方法:在這兩種情況下的束路徑我得到的是"/Applications/Temporary/Xcode6-Beta3.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Overlays" 。在那條路上,圖像顯然不存在。

+0

張貼雷達到蘋果rdar:// 17762946 – mxb

+1

說,你不應該在prepareForInterfaceBuilder中調用超級? – Fattie

回答

3

在夫特3.0 @kasplat的代碼已更改爲:

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

// OR ALTERNATIVELY BY PROVDING THE CONCRETE NAME OF DESIGNABLE CLASS 
let theBundle = Bundle(for: RH_DesignableView.self) 

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

嘗試獲得類的捆綁是這樣的:

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

響應...

工程已經確定,按照預期基於 這個問題表現在以下方面:

我們不能真正做到這一點比指定包更容易。你可能會說,「哦,讓我們swizzle - [NSBundle mainBundle]」,但很多 呼叫站點引用一個捆綁不通過那裏(或通過CF API去 )。有人可能會說,「好的,那麼我們在 至少swizzle - [UIImage imageNamed:]」。這裏的問題是 不是主包的單個替代品。您可能一次加載多個 實時瀏覽包(框架或應用程序),因此我們 不能只選擇一個作爲主包。

開發人員需要了解捆綁包以及如何從 捆綁包中獲取圖像。開發人員應該使用 UIImage(名爲:inBundle:compatibleWithTraitCollection :)進行所有圖像查找。

+0

thx回答,但正確的做法應該是我自己的答案中描述的方法。 – mxb

+3

我提供了捆綁包示例,因爲我向Apple發佈了一個錯誤報告(17656550),說明無法在Live View中查找資源。我在Apple答覆中添加了Apple的回覆。 – kasplat

+0

偉大的調查,顯然你必須非常瞭解視圖以「實時視圖」呈現時的視圖所處的「範圍」。 –

5

我能夠解決從當前的NSProcessInfo對象獲取Interface Builder項目路徑的問題。然後您可以從IB_PROJECT_SOURCE_DIRECTORIES鍵中收集正確的路徑。

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,因爲它似乎UIImageView的appereance不活的看法發生改變。

+1

在我看來,正確的迴應是這個帖子中的#kasplat或者那個@rickster:http://stackoverflow.com/questions/24603232/xcode-6-ib-designable-not-loading-resources-from- bundle-in-interface-builder – SwiftArchitect

+0

我接受這個答案是因爲它基於WWDC會話,所以它在我看來就像來自Apple的官方信息。你怎麼看? – mxb

+0

看來,蘋果現在提供了一個更簡單的方法:'prepareForInterfaceBuilder'只能帶你到目前爲止,並需要非常具體的操作。'NSBundle:forClass'另一方面是靈活的,封裝良好。也許蘋果現在提供更好,更輕量級的解決方案來應對錯誤(17656550)? – SwiftArchitect

0

對於Swift 2和Xcode 7,界面已更改。應該使用

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

我用它在my project,它工作正常兩種IB和設備。

+0

謝謝。但是我不明白@kasplat的答案。 – mxb

+0

UIImage的init是不同的。 –

0

這將加載您的IB_Designable,或者如果您沒有 - 默認圖像。

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

} 
7

允許彈出在迅速3答案

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

爲SWIFT 4(3)使用此:

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

這種方法普遍獲得捆綁

相關問題