Swift - 在类中将NIB分配给self

4

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

由于在swift中不能对'self'进行赋值,因此如何从类本身正确执行此操作?

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

8

如果有人想要在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
    }
}

5

我的一般做法如下:

  1. 在nib中将我的自定义视图类设置为FileOwner
  2. 设置所有必需的outlets和actions
  3. 在nib中将视图的outlet设置为并在类中将其命名为'contentView'
  4. init*方法中-使用owner实例化nib并将子视图添加到我的自定义视图对象中。

以下是按照这种方式实现集合头视图的示例。

@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 示例

主要思想是不直接从nib加载视图到self,而是将其作为子视图添加到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


你的方法是针对Objective-C的。在Swift中,初始化方法不返回对象,而且“self”不可分配。 - JimmyJammed
我的方法是与语言无关的。你可以只在if(){...}中参与并在Swift中使用它。问题是-你不将视图从nib分配给self,而是将其作为子视图添加到self中。 - Max Komarychev
请查看 Swift 示例。 - Max Komarychev
非常感谢!这将使我的生活变得更加轻松! - Aquila Sagitta
从2022年开始,我不得不使用这种方法来展示屏幕的超快速演示。在完成以上步骤后,请不要忘记重新启动您的Xcode。 - Glenn Posadas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接