Swift - 在课堂上为自己分配一个NIB

时间:2015-01-28 19:57:49

标签: ios swift subclass xib init

我正在为通知下拉列表创建一个UIView子类。 我正在使用XIB构建视图,并希望在初始化时将该xib分配给类(即避免必须从调用ViewController执行此操作)。

由于你无法在swift中分配给'self',我如何从类本身中正确地执行此操作?

class MyDropDown: UIView
{
     func showNotification()
     {
          self = UINib(nibName: nibNamed, bundle: bundle).instantiateWithOwner(nil, options: nil)[0] as? UIView
     }
}

2 个答案:

答案 0 :(得分:7)

对于任何想要如何在swift中使用自己的类初始化xib的人来说,这是使用自定义类初始值设定项的最佳方法:

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
    }
}

答案 1 :(得分:5)

我通常采用以下方法:

  1. 将我的自定义视图类设置为nib中的FileOwner
  2. 设置所有必需的出口和操作
  3. 将出口设置为nib中的视图,并在类
  4. 中将其命名为“contentView”
  5. init*方法中 - 使用所有者实例化nib并将子视图添加到我的自定义视图对象。
  6. 以下是以这种方式实现的集合头视图的示例。

    @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
    

    // 更新 Swift示例

    主要的想法是不将视图从笔尖直接加载到self,而是将它/视图从nib /作为子视图添加到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)
        }
    }
    

    InterfaceBuilder