Загрузка 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/