-
-
Save bwhiteley/049e4bede49e71a6d2e2 to your computer and use it in GitHub Desktop.
// Create CustomView.xib, set File's Owner to CustomView. | |
// Link the top level view in the XIB to the contentView outlet. | |
class CustomView : UIView { | |
@IBOutlet private var contentView:UIView? | |
// other outlets | |
override init(frame: CGRect) { // for using CustomView in code | |
super.init(frame: frame) | |
self.commonInit() | |
} | |
required init?(coder aDecoder: NSCoder) { // for using CustomView in IB | |
super.init(coder: aDecoder) | |
self.commonInit() | |
} | |
private func commonInit() { | |
Bundle.main.loadNibNamed("CustomView", owner: self, options: nil) | |
guard let content = contentView else { return } | |
content.frame = self.bounds | |
content.autoresizingMask = [.flexibleHeight, .flexibleWidth] | |
self.addSubview(content) | |
} | |
} |
Use this to break the infinite loop.
required init?(coder aDecoder: NSCoder) { // for using CustomView in IB
super.init(coder: aDecoder)
if self.subviews.count == 0{
self.commonInit()
}
}
how do you link top level view in the xib to the content view outlet
class CustomHeader: UIView {
var view:UIView!
override init(frame:CGRect) {
super.init(frame: frame)
setup()
}
required init(coder aCoder: NSCoder) {
super.init(coder: aCoder)!
setup()
}
func setup() {
view = self.loadViewFromNib()
view.frame = bounds
view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
addSubview(view)
}
func loadViewFromNib() -> UIView {
return UINib(nibName: "CustomHeader", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! UIView
}
Simply add class type (Ex.CustomHeader) in Xib file of where you are going to use this custom class. it worked fine for me
Is it possible to have this in an extension (swift 3)? I don't seem to be able to come up with a working one. Ideas?
Just use NibDesignable
Don't try to get the first view. If you do it, the iboutlets won't be set anyway, which is not what you what. Rather do this:
import UIKit
class CustomView: UIView {
@IBOutlet weak var contentView: UIView?
@IBOutlet weak var anotherSubviewOfContentViewHere: UIView?
override init(frame: CGRect) {
super.init(frame: frame)
nibSetup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
nibSetup()
}
func nibSetup() {
Bundle.main.loadNibNamed(String(describing: CustomView.self), owner: self, options: nil)
guard let contentView = contentView else { return }
self.addSubview(contentView)
}
}
It goes into an infinite loop. No solution seems to be working for creating a simple custom UIView!!!!!
It goes into an infinite loop too
Infinite loop is caused by not setting FileOwner or remove custom class name in top level view. Top level view should be just UIView. All outlets has to be connected from FileOwner.
Here is the setup for all you guys experiencing infinite loop:
- Open your xib file
- Press File's Owner -> Utilities pane (right Xcode pane) -> 3rd "tab" ->
Custom Class
-> SetClass
to the name of your*.swift/*.m
file - Press topmost view -> remove
Custom Class
in the same menu as in step 2. - If your
*.swift / *.m
file already had the outlets configured, you'll notice, that they are not connected (you can see that in the 6th tab of the right Xcode pane). To fix that proceed to steps 5 and 6. - Delete all the iboutlets you've had configured for your subviews.
- Connect
File's Owner's
outlets to your subviews
thanks for the code
Hi all
I need to send extra two parameters in CustomView class from the viewcontroller class , How this is possible.
I think we are on the same page, I want to create a custom view with IBOutlets. And I want to create it in such a way that it can directly use in storyboard. But it seems to impossible, when init with coder initialise a view, the IBOutlets are nil. If I use a different method using files owner , awake from nib will never execute, here. The sad part is that, the dilemma is to just load a view to screen. Anyone have a comment?
https://gist.github.com/bwhiteley/049e4bede49e71a6d2e2#gistcomment-2037515
work fine...completly.
Thanks! It's crazy how difficult it is to find information on how to do this