Ios 在swift中使用Nib的自定义UIView,而不在视图控制器中使用loadFromNib

Ios 在swift中使用Nib的自定义UIView,而不在视图控制器中使用loadFromNib,ios,swift,uiview,nib,Ios,Swift,Uiview,Nib,我一直使用loadNibNamed方法将自定义视图加载到视图控制器中,但现在我试图避免在自定义视图之外调用该方法,以使其更具可重用性,这样,如果其他人使用我的自定义视图,他只需要实例化视图而不使用loadFromNib,例如: var myView: MyView = MyView() 将此视图添加到视图控制器的视图中就足够了,自定义视图将在其内部加载nib。 我正试图用Swift实现这一点,在ObjC中,我发现了如下代码: 但在swift中,我不能使用答案中使用的init: - (id)in

我一直使用loadNibNamed方法将自定义视图加载到视图控制器中,但现在我试图避免在自定义视图之外调用该方法,以使其更具可重用性,这样,如果其他人使用我的自定义视图,他只需要实例化视图而不使用loadFromNib,例如:

var myView: MyView = MyView()
将此视图添加到视图控制器的视图中就足够了,自定义视图将在其内部加载nib。 我正试图用Swift实现这一点,在ObjC中,我发现了如下代码: 但在swift中,我不能使用答案中使用的init:

- (id)initWithFrame:(CGRect)frame 
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code.
        //
        [[NSBundle mainBundle] loadNibNamed:@"MyView" owner:self options:nil];
        [self addSubview:self.view];
    }
    return self;
}
我有这个方法,它以一个无限循环结束:

override init(frame: CGRect) {
    super.init(frame: frame)
    self.loadFromNibNamed("MyView")
}
我还尝试在MyView中添加另一个视图作为IBOutlet,如另一个答案所示,并使用所有初始化:

@IBOutlet var view: UIView!

override init() {
    super.init()
    NSBundle.mainBundle().loadNibNamed("MediaPlayerView", owner: self, options: nil)
    self.addSubview(self.view)
}

override init(frame: CGRect) {
    super.init(frame: frame)
    NSBundle.mainBundle().loadNibNamed("MediaPlayerView", owner: self, options: nil)
    self.addSubview(self.view)
}

required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    NSBundle.mainBundle().loadNibNamed("MediaPlayerView", owner: self, options: nil)
    self.addSubview(self.view)
}
但仍然得到了无限循环的误差


我找不到一个好的解决办法,这让我发疯!!有人能帮我吗?谢谢

我认为更简洁的方法是不要使用默认的初始值设定项,而是使用自己的初始值设定项,例如这样

override init(frame: CGRect, shouldLoadFromNib: Bool) {
    super.init(frame)
    guard shouldLoadFromNib else {
         return
    }
    NSBundle.mainBundle().loadNibNamed("MediaPlayerView", owner: self, options: nil)
    self.addSubview(self.view)

}
这样,当您从其他地方实例化它时,您将立即看到,这不仅仅是一些
UIView
的普通老实例化,而且它还有副作用(视图将从nib加载)


我不确定
super.init(frame)
调用,可能
loadNibNamed
也会为您调用它,所以您可能想检查一下,您得到的是一个无限循环,因为
loadNibNamed(u,owner:,options:)
调用
init
,然后尝试再次加载nib,又一次,等等。。。试试这个:

Swift 4

var contentView: UIView?

// MARK: Initializers

override init(frame: CGRect) {
    super.init(frame: frame)
    configureView()
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    configureView()
}

override func prepareForInterfaceBuilder() {
    super.prepareForInterfaceBuilder()
    configureView()
}

override func awakeFromNib() {
    super.awakeFromNib()
    configureView()
}

// MARK: Config Functions

func configureView() {
    guard let view = defaultView() else { return }
    view.frame = bounds
    view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    addSubview(view)
    contentView = view

    updateView()
}

func defaultView() -> UIView? {
    // Create view from a nib with the same name
    let nibName = String(describing: type(of: self))
    let bundle = Bundle(for: type(of: self))
    let nib = UINib(nibName: nibName, bundle: bundle)

    return nib.instantiate(withOwner: self, options: nil).first as? UIView
}
这段代码的作用是从nib加载视图,然后将其添加到视图中的子视图中


当在另一个XIB上添加视图时,这也会起作用,添加
@IBDesignable
,它将变得可用

您的NIB是否分别包含类
MyView
MediaPlayerView
的视图。?这可能是无限循环的原因,我猜
init(coder:)
是原因。