4

I trying to using my custom xib files. But those UI are not showing in main view controller in xcode. But it show when run the app. I already added @IBDesignable in class. Here is what i did.

  1. I created TestView.xib and added some design

  2. I created TestView.swift

  3. I updated fileOwner of TestView.xib with TestView in Custom Class

  4. I added init code to testView.swift

Code inside TestView.swift

import UIKit

@IBDesignable class DetailView: UIView {

override init(frame: CGRect){
    super.init(frame: frame)
    self.setup()
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)!
    self.setup()

}

func setup() {
    let view = Bundle.main.loadNibNamed("TestView", owner: self, options: nil)?.first as! UIView
    view.frame = self.bounds
    self.addSubview(view)
}

}
  1. And Added on UIView in MainViewController and link to TestView with custom class name.

  2. After that i run the app, I can see the UI from testView. Image of emulator and result

  3. But my custom UI don't show in MainViewController in xcode Image of xcode view controller

How can i enable to see my custom UI in MainViewController ? Thanks

Thet Paing Soe
  • 91
  • 2
  • 10
  • Are you expecting `setup()` to run when viewing things in IB? –  Oct 20 '17 at 11:29
  • 3
    Try implementing ```func prepareForInterfaceBuilder()``` https://developer.apple.com/documentation/objectivec/nsobject/1402908-prepareforinterfacebuilder – Arda Keskiner Oct 20 '17 at 12:43
  • Do you have any idea how to call setup() for IB ? @dfd – Thet Paing Soe Oct 20 '17 at 15:48
  • Directly? You can't. IB is for *design-time*, not *run-time*. (That's why I asked. @Arda_Keskiner gave you the way to work - see about using `prepareForInterfaceBuilder()`. If you think it through, there *should* be no way for you to, um, "execute" code with a design-time tool. Depending on your needs, this function may work for you. –  Oct 20 '17 at 17:48
  • @dfd Thanks for your help. I already found my problem that need to change setup function. I posted below. – Thet Paing Soe Oct 21 '17 at 06:33
  • @ArdaKeskiner Thanks for your help. :D – Thet Paing Soe Oct 21 '17 at 06:34
  • In your example code, why is your class called DetailView and not TestView and was it still called DetailView in your answer below? – Sojourner9 Feb 23 '18 at 17:01

3 Answers3

7

In InterfaceBuilder select your ViewController and choose "Editor-->Refresh all Views". Then your custom view should come up.

If something is wrong you can debug your IBDesignable class by setting breakpoints in your code and then choose "Editor-->Debug selected views".

prepareForInterfaceBuilder() only needs to be implemented if you need special design appearance in InterfaceBuilder.

Sometimes it is necessary to clean the project and build folder to get it to work:
Project->Clean
Project->(hold down options key)->Clean Build Folder

zisoft
  • 22,770
  • 10
  • 62
  • 73
4

I just changed the setup function. It working now. Final Result Image - It showing UI in IB

func setup() {
    view = loadViewFromNib()
    view.frame = bounds
    view.autoresizingMask = UIViewAutoresizing(rawValue: UIViewAutoresizing.RawValue(UInt8(UIViewAutoresizing.flexibleWidth.rawValue) | UInt8(UIViewAutoresizing.flexibleHeight.rawValue)))

    self.addSubview(view)
}

func loadViewFromNib() -> UIView {
    let bundle = Bundle(for: type(of: self))
    let nib = UINib(nibName: "TestView", bundle: bundle)
    let view = nib.instantiate(withOwner: self, options: nil)[0] as! UIView
    return view
}
Thet Paing Soe
  • 91
  • 2
  • 10
  • 1
    In case anyone else might have the same problem even after implementing it this way, check that your File Owner is set to your custom view class, but the view's class is NOT set to it (i.e. it remains UIView). – Vladimir Mitrovic Nov 01 '17 at 10:28
  • The above solutions didn't work for static UITableViewCells (XCode 9.2) – Darkwonder Feb 15 '18 at 22:03
  • Did you have to define view using this code as you are no longer using let? How was it defined, as an outlet? – Sojourner9 Feb 23 '18 at 17:14
0

Override two func below for live:

override open func prepareForInterfaceBuilder() {
   layer.cornerRadius = cornerRadius
   layer.borderWidth = borderWidth
}

override open func awakeFromNib() {
   layer.cornerRadius = cornerRadius
   layer.borderWidth = borderWidth
}
Giang
  • 3,553
  • 30
  • 28