Загрузка XIB файла в UIView Swift

Я пытаюсь загрузить файл XIB в UIView, но у меня проблемы. У меня есть необходимые функции переопределения, но они, похоже, сбой. Высказывание этой ошибки, предупреждение:

не удалось загрузить информацию о классе Objective-C. Это будет значительно снизить качество имеющейся информации о типе.

Мне было интересно, может ли кто-нибудь показать мне, как правильно загрузить файл XIB в UIView

import UIKit

class Widget: UIView {

    let view = UIView()

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

        //call function

        loadNib()

    }

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

        loadNib()

        //fatalError("init(coder:) has not been implemented")
    }

    func loadNib() {
        let bundle = NSBundle(forClass: self.dynamicType)
        let nib = UINib(nibName: "nib", bundle: bundle)
        let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView
        view.frame = bounds
        view.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
        self.addSubview(view);  
    }
}

Ответ 1

Я использую это в одном из наших проектов, maby его полезно для вас

import UIKit

class RegisterPageView: UIView {

        class func instanceFromNib() -> RegisterPageView {
            return UINib(nibName: "RegisterPageView", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as! RegisterPageView
        }
}

Ответ 2

Использование Swift 3.0

let viewFromNib: UIView? = Bundle.main.loadNibNamed("NibName", 
    owner: nil, 
    options: nil)?.first

Ответ 3

Вот мой подход (написанный в Swift 3.1):

protocol XibDesignable : class {}

extension XibDesignable where Self : UIView {

    static func instantiateFromXib() -> Self {

        let dynamicMetatype = Self.self
        let bundle = Bundle(for: dynamicMetatype)
        let nib = UINib(nibName: "\(dynamicMetatype)", bundle: bundle)

        guard let view = nib.instantiate(withOwner: nil, options: nil).first as? Self else {

            fatalError("Could not load view from nib file.")
        }
        return view
    }
}

extension UIView : XibDesignable {}

Теперь я просто могу создать любой подкласс UIView из Xib (при условии, что он есть), как и MyCustomView.instantiateFromXib(). Не забудьте указать свой Xib файл в точности как ваш подкласс UIView и правильно указать тип основного представления в этом Xib файле.


Как только SR-0068 будет реализован, можно отказаться от протокола и перенести функцию непосредственно в расширение UIView.


Просто примечание: исходное сообщение использует обычно используемый шаблон с вложенным представлением. ИМХО это плохой шаблон, который не использует ресурсы и создает только ненужную иерархию представлений.

Ответ 4

Улучшено DevAndArtist Расширение UIView

public extension UIView
{
    static func loadFromXib<T>(withOwner: Any? = nil, options: [AnyHashable : Any]? = nil) -> T where T: UIView
    {
        let bundle = Bundle(for: self)
        let nib = UINib(nibName: "\(self)", bundle: bundle)

        guard let view = nib.instantiate(withOwner: withOwner, options: options).first as? T else {
            fatalError("Could not load view from nib file.")
        }
        return view
    }
}

Использование

let view = CustomView.loadFromXib()
let view = CustomView.loadFromXib(withOwner: self)
let view = CustomView.loadFromXib(withOwner: self, options: [UINibExternalObjects: objects])

Обсуждение внешних объектов

Ответ 5

для swift 3

class YourClass:  UIView {
    class func instanceFromNib() -> YourClass {
        return UINib(nibName: "YourClassNibName", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! YourClass
    }
}

Ответ 6

Обычно я использую следующий способ загрузки xib файла, принадлежащего пользовательскому UIView:

NSBundle.mainBundle().loadNibNamed(nibName, owner: self, options: nil)[0];

Ответ 7

В моем проекте я реализовал следующее (очень похожее на решение Питера)

import UIKit

// MARK: - Protocol Declaration

public protocol InterfaceBuilderInstantiable
{
    /// The UINib that contains the view
    ///
    /// Defaults to the swift class name if not implemented
    static var associatedNib : UINib { get }
}

// MARK: - Default Implementation

extension InterfaceBuilderInstantiable
{
    /// Creates a new instance from the associated Xib
    ///
    /// - Returns: A new instance of this object loaded from xib
    static func instantiateFromInterfaceBuilder() -> Self
    {
        return associatedNib.instantiate(withOwner:nil, options: nil)[0] as! Self
    }

    static var associatedNib : UINib
    {
        let name = String(describing: self)
        return UINib(nibName: name, bundle: Bundle.main)
    }
}

Чтобы использовать, вы просто реализуете протокол:

class MyView: UIView, InterfaceBuilderInstantiable
{
    // The rest

И если ваш nib совпадает с именем вашего класса (MyView.xib), вы устанавливаете: по умолчанию реализация протокола ищет нить с тем же именем, что и класс в основном комплекте.

Конечно, если ваш nib находится в другом комплекте или имеет другое имя, вы можете переопределить associatedNib и вернуть свой собственный nib.

Ответ 8

Swift 4.x

let myView = Bundle.main.loadNibNamed("yourXibView", owner: nil, options: nil)![0] as! UIView

Ответ 9

let xibView = NSBundle.mainBundle().loadNibNamed("NameXibView", owner: nil, options: nil)[0] as! UIView

Ответ 10

  func configureNib() -> UIView {
    let bundle = Bundle(for: type(of: self))
    let nib = UINib(nibName: "CustomUIView", bundle: bundle)
    let view = nib.instantiate(withOwner: self, options: nil)[0] as! UIView
    return view
}

И используйте этот учебник для пользовательского представления с помощью xib... https://developerfly.com/custom-view-use-xib-swift/