【问题标题】:Load custom UIView from xib programmatically以编程方式从 xib 加载自定义 UIView
【发布时间】:2016-07-31 21:42:54
【问题描述】:

我在MySample.xib 中创建了一个自定义 UIView。我已将 MyView 类添加到 xib 的 File Owner 中。

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)
    }
}

我现在从MyController 文件中加载这个MyView,如下所示:

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")
    }
}

现在要显示此视图,我正在使用来自另一个控制器的 UIButton 的以下代码:

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

这确实会在屏幕上显示视图。但问题是,它不接受任何用户交互。在我的自定义视图中,我有一个 UITableView 可以显示数据,但由于缺少用户交互,它不会滚动或被点击。

知道我做错了什么吗?

【问题讨论】:

  • 您是否使用了视图层次检查器来确保自定义视图之上没有任何内容?
  • @EmilioPelaez 是的,我已经检查过了,上面什么都没有。
  • 如果在MyView 上覆盖touchesBegan... 会发生什么?它会被调用吗? userInteractionEnabled 是真的吗?
  • @EmilioPelaez 没有任何反应。它永远不会进入那个touchesBegan 函数。视图上的userInteraction 也已启用。
  • @EmilioPelaez 我尝试在MyController 上使用touchesBegan,它确实有效。但它在MyView 中不起作用。在我上面的代码中,我已将其添加为 MyController 中的子视图。

标签: ios swift uiview


【解决方案1】:

您不必重新实例化它两次 如果您使用design pattern,则已经。

就是这么简单。随便写:

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.
}}

它会起作用的。

【讨论】:

  • 虽然理论上这可以回答这个问题,it would be preferable 在这里包含答案的基本部分,并提供链接以供参考。
【解决方案2】:

你的例子中有一些不必要的东西。

我仍然不确定您要做什么,但是如果您想将自定义视图从 xib 添加到您的视图控制器,那么:

  1. 在 xib 文件中创建视图,不需要重写 init ,并且不能使用默认的 init UIView() 从 xib 初始化视图,因此请从 MyView 类中删除 init 方法。

  2. 在您的 xib 中,确保您在 IB 中看到的视图属于您要使用的类类型(我猜是 MyView 类)。

  3. 在您的视图控制器中初始化如下视图:

    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.
        }
    }
    

【讨论】:

  • 现在我收到这个错误:*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<MyApp.MyController 0x7c127fb0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key label.'
  • 你的 xib 中可能连接不好,如果可能的话,我建议你从一个新的 xib 开始,首先创建新的 xib,将视图的类设置为相关的视图类,设置一些背景颜色,然后看看它是否有效。
  • 不是使用self作为所有者,而是必须使用MyView()将所有事件转移到视图链接到的MyView类。
  • 它与使用“self”作为文件所有者一起工作,到目前为止完美回答了此类问题。
【解决方案3】:

我必须将 xib 中的根视图类更改为 MyView,而不是将 xib File's Owner 类链接到 MyView。然后基于 @Oleg Sherman 代码,通过添加MyView() 作为所有者来获取它的所有事件,它可以完美地工作,否则它会抛出错误this class is not key value coding-compliant for the key ****.

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

仅当您必须在 Storyboard 中使用 xib 时,才需要使用 File's Owner 类到 MyView

不确定当像我原来的问题那样以编程方式从自定义控制器加载 xib 时,是否有一种解决方法可以使用 File's Owner 类到 MyView

【讨论】:

  • 就我而言...这对我有用...我只是将我的所有者更改为我的 xib 类。 : 让 mCuentasView = Bundle.main.loadNibNamed("CajaAhorroView", owner: self.mContainerCuenta, options: nil)![0] as! UIView self.mContainerView.addSubview(mCuentasView) mCuentasView.frame = self.mContainerView.bounds
猜你喜欢
  • 1970-01-01
  • 2017-10-01
  • 2015-05-26
  • 2015-02-03
  • 2020-05-16
  • 1970-01-01
  • 1970-01-01
  • 2017-11-18
  • 1970-01-01
相关资源
最近更新 更多