簡體   English   中英

快速使用 Nib 自定義 UIView,而不在視圖控制器中使用 loadFromNib

[英]Custom UIView with Nib in swift without using loadFromNib in the view controller

我一直使用 loadNibNamed 方法將自定義視圖加載到視圖控制器中,但現在我試圖避免在自定義視圖之外調用該方法以使其更可重用,這樣如果另一個人使用我的自定義視圖,他只需要在沒有 loadFromNib 的情況下實例化視圖,例如:

var myView: MyView = MyView()

將此視圖添加到視圖控制器的視圖中就足夠了,自定義視圖將在其自身內部加載筆尖。 我正在嘗試在 Swift 中執行此操作,在 ObjC 中我找到了類似於以下答案之一的代碼: UIView 和 initWithFrame 以及一個 NIB 文件。 如何加載 NIB 文件? 但是在 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的普通舊實例,而且它有副作用(視圖將從筆尖加載)

我不確定super.init(frame)調用, loadNibNamed可能也會為你調用,所以你可能想檢查一下

你得到一個無限循環,因為loadNibNamed(_,owner:,options:)調用一個init ,然后嘗試再次加載筆尖,然后再等等......試試這個:

斯威夫特 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
}

這段代碼的作用是從筆尖加載視圖,然后將其添加到視圖內的子視圖中。

在另一個 xibs 上添加您的視圖時,這也將起作用,添加@IBDesignable它將變為可用

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM