I am creating a UIView subclass for a notification dropdown banner. I am using a XIB to build out the view and want to assign that xib to the class when it initializes (i.e.
For anyone looking on how to initialize a xib from it's own class in swift, here is the best approach using a custom class initializer:
class MyCustomView: UIView
{
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var titleLabel: UILabel!
class func initWithTitle(title: String, image: UIImage? = nil) -> MyCustomView
{
var myCustomView = UINib(nibName: "MyCustomView", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as? MyCustomView
myCustomView.titleLabel.text = title
if image != nil
{
myCustomView.imageView.image = image
}
//...do other customization here...
return myCustomView
}
}
My usual approach is the following:
FileOwner
in the nibinit*
method - instantiate nib with owner and add subview to my custom-view object.Here is the example of the collection header view implemented this way.
@interface Header : UITableViewHeaderFooterView
@property (nonatomic) IBOutlet UIView *contentView;
@property (weak, nonatomic) IBOutlet UILabel *labelTitle;
// other required outlets & actions
// ...
@end
#import "Header.h"
@implementation Header
- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier
{
if (self = [super initWithReuseIdentifier:reuseIdentifier]) {
[[NSBundle mainBundle] loadNibNamed:@"Header"
owner:self
options:nil];
[self.contentView addSubview:self.content];
UIView *subview = self.content;
self.content.translatesAutoresizingMaskIntoConstraints = NO;
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(subview);
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[subview]|" options:0 metrics: 0 views:viewsDictionary]];
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[subview]|" options:0 metrics: 0 views:viewsDictionary]];
}
return self;
}
@end
// UPDATE Swift example
The main idea is not to load view from the nib directly to self
but add it /view from nib/ as a subview to the self
import UIKit
class CustomView: UIView {
@IBOutlet var contentView: UIView!
@IBOutlet weak var labelTitle: UILabel!
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.__loadContent()
}
override init(frame: CGRect) {
super.init(frame: frame)
self.__loadContent()
}
private func __loadContent() {
// create nib
let nib = UINib(nibName: "CustomView", bundle: NSBundle.mainBundle())
// load outlets to self
nib.instantiateWithOwner(self, options: nil)
// add content view as a subview
self.addSubview(self.contentView)
// disable autoresizing
self.contentView.setTranslatesAutoresizingMaskIntoConstraints(false)
// manually create constraints to fix content view inside self with 0 padding
let viewsDict: NSDictionary = ["content": self.contentView]
let vertical = NSLayoutConstraint.constraintsWithVisualFormat("V:|[content]|",
options: NSLayoutFormatOptions.allZeros,
metrics: nil,
views: viewsDict)
let horizontal = NSLayoutConstraint.constraintsWithVisualFormat("H:|[content]|",
options: NSLayoutFormatOptions.allZeros,
metrics: nil, views: viewsDict)
self.addConstraints(vertical)
self.addConstraints(horizontal)
}
}