简体   繁体   English

以编程方式从xib加载自定义UIView

[英]Load custom UIView from xib programmatically

I have created a custom UIView in MySample.xib . 我在MySample.xib创建了一个自定义UIView。 I have added the class MyView to the File Owner of xib. 我已将类MyView添加到xib的File Owner

MyView.swift MyView.swift

class MyView: UIView {

    @IBOutlet var view: UIView!

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

        setup()
    }

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

        setup()
    }

    func setup() {
        NSBundle.mainBundle().loadNibNamed("MySample", owner: self, options: nil)            
        self.addSubview(self.view)
    }
}

I am now loading this MyView from MyController file like this: 我现在从MyController文件加载这个MyView ,如下所示:

MyController.swift MyController.swift

class MyController: UIViewController {
    init() {
        super.init(nibName: nil, bundle: nil)

        view.addSubview(MyView())

    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

Now to display this view, I am using to following code from another controller's UIButton : 现在要显示这个视图,我用来跟踪来自另一个控制器的UIButton代码:

presentViewController(MyController(), animated: true, completion: nil)

This does display the view on screen. 这会在屏幕上显示视图。 But the problem is, it doesn't accept any user interaction. 但问题是,它不接受任何用户交互。 In my custom view, I have a UITableView which does display the data but it doesn't scroll or get tapped due to lack of user interaction. 在我的自定义视图中,我有一个UITableView,它显示数据,但由于缺乏用户交互,它不会滚动或点击。

Any idea what I am doing wrong? 知道我做错了什么吗?

There are some unnecessary things in your example. 你的例子中有一些不必要的东西。

I am still not sure what are you trying to do, but if you want to add a custom view from xib to your view controller then: 我仍然不确定你想做什么,但如果你想从xib添加自定义视图到你的视图控制器,那么:

  1. Create a view in a xib file , you don't need to override init , and you can't init view from xib using the default init UIView() , so please remove init method from your MyView class. 在xib文件中创建一个视图,你不需要覆盖init,也不能使用默认的init UIView()从xib初始化视图,所以请从你的MyView类中删除init方法。

  2. In your xib make sure that your view that you see in the IB is of the class type you want to use (i guess MyView class). 在你的xib中确保你在IB中看到的视图是你想要使用的类类型(我猜MyView类)。

  3. In your view controller init the view like this: 在您的视图控制器中初始化视图如下:

     class MyController: UIViewController { override func viewDidLoad() { super.viewDidLoad() //Get all views in the xib let allViewsInXibArray = NSBundle.mainBundle().loadNibNamed("MySample", owner: self, options: nil) //If you only have one view in the xib and you set it's class to MyView class let myView = allViewsInXibArray.first as! MyView //Set wanted position and size (frame) myView.frame = self.view.bounds //Add the view self.view.addSubview(myView) //TODO: set wanted constraints. } } 

Instead of linking xib File's Owner class to MyView , I have to change the class of root view in xib to MyView . 我不得不将xib File's Owner类链接到MyView ,而是必须将xib中的根视图类更改为MyView Then based on @Oleg Sherman code, it works perfectly with small changes of adding MyView() as owner to get all it's events, otherwise it will throw an error this class is not key value coding-compliant for the key ****. 然后基于@Oleg Sherman代码,它完全适用于添加MyView()作为所有者的小变化来获取它的所有事件,否则它将抛出一个错误, this class is not key value coding-compliant for the key ****. :

let allViewsInXibArray = NSBundle.mainBundle().loadNibNamed("MySample", owner: MyView(), options: nil)

Using File's Owner class to MyView is only required when you have to use the xib in Storyboard. 只有在Storyboard中使用xib时,才需要File's Owner类用于MyView

Not sure if there is a workaround to use File's Owner class to MyView when programmatically loading xib from custom controller like in my original question. 不知道是否有一个解决方法,以编程方式从自定义控制器加载xib时,使用File's Owner类到MyView ,就像我原来的问题一样。

You don't have to re-instantiate this twice already if you using the design pattern . 如果使用设计模式,则不必重新实例化两次。

It's so simple. 这很简单。 Just write: 写吧:

class MyController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()

    //Get all views in the xib
    let view = MyView() 
    self.view.addSubview(myView)

    //TODO: set wanted constraints.
}}

And It will work. 它会奏效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM