Swift - Assign a NIB to self in class

心已入冬 提交于 2019-11-30 23:15:01

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:

  1. Set my custom-view class as FileOwner in the nib
  2. Set all required outlets and actions
  3. Set outlet to the view in nib and name it 'contentView' in the class
  4. In the init* 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)
    }
}

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!