【问题标题】:Load UIView from xib without storyboard从没有情节提要的xib加载UIView
【发布时间】:2015-12-31 03:30:42
【问题描述】:

我正在尝试以编程方式加载笔尖,而无需在情节提要中使用 IBOutlets。

我已经设置了文件所有者的自定义类并为图像和标签创建了出口。我创建了一个 UINib 实例,并在我的自定义类中调用了 instantiateWithOwner 来手动加载 nib。现在我正在尝试将 nib 加载到 uitableviewcontroller 上。

我的问题是如何在视图控制器上加载该 xib,而无需使用情节提要将 uiview 添加到视图控制器,也无需将插座连接到 uiview。

关于如何使用故事板和 IBOutlets 加载 nib 有几个问题和教程,这很简单。

谁能告诉我如何以编程方式快速执行此操作?

注意:我的项目中有两个视图控制器。 VC1 有一个带有图像和标签的 collectionView。我正在使用 xib 和自定义类在 VC2 中显示选定的 collectionView。

【问题讨论】:

    标签: swift uiview xib


    【解决方案1】:

    您不必设置所有者。您可以简单地实例化 nib 并引用由它创建的顶级对象。话虽如此,如果您确实将自己作为所有者传递并连接了插座,那也可以。值得注意的是,如果多次实例化 nib,则每次都会将 outlets 的值设置为新实例。如果您想引用以前的那些,您必须在其他属性中捕获它们。

        // Create a UINib object for a nib named MyNib in the main bundle
        let nib = UINib(nibName: "MyNib", bundle: nil)
    
        // Instante the objects in the UINib
        let topLevelObjects = nib.instantiateWithOwner(self /*or nil*/, options: nil)
    
        // Use the top level objects directly...
        let firstTopLevelObject = topLevelObjects[0]
    
        // Or use any IBOutlets
        doSomeStuff(self.someOutletProperty)
    

    【讨论】:

    • 我确实将自己作为所有者传递,并在 xib 中将网点连接到自定义类。我的问题是如何在视图控制器上加载该 xib 而不将 uiview 添加到情节提要中的视图控制器并且不将插座连接到 uiview。我想以编程方式进行。
    • 我的示例代码将执行此操作。注释“直接使用顶级对象”正下方的行将导致对 xib 文件中的第一个顶级对象的引用。你可以通过nil作为所有者。
    【解决方案2】:

    您可以从 XIB 中获取顶视图并将其放在任何地方

    override func viewDidLoad() {
        super.viewDidLoad()
        let calendar = UINib(nibName: "<<NibFileName>>", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as! UIView
        view.addSubview(calendar)
    }
    

    【讨论】:

    • 我正在尝试使用从 collectionView 传递的值加载 XIB。因此,图像和标签是可变的。
    • 我的自定义类中已经有了这个方法。我正在尝试使用从视图控制器 1 中的 collectionView 传递到视图控制器 2 的值加载 XIB。因此,图像和标签是可变的。如何在 viewcontroller2 中加载 uiview 而无需在情节提要中使用 IBOutlets。
    【解决方案3】:

    你可以用这个方法:

    方法:

    public static func getViewFromNib(nibName:String)-> UINib{
        let uiNib = UINib(nibName: nibName, bundle: nil)
        return uiNib 
    }
    

    用法:

        let customView = getViewFromNib.instantiateWithOwner(ownerOrNil, options: nil) as! UIView
        view.addSubview(customView)
    

    【讨论】:

    • 我的自定义类中已经有了这个方法。我正在尝试使用从视图控制器 1 中的 collectionView 传递到视图控制器 2 的值加载 XIB。因此,图像和标签是可变的。如何在 viewcontroller2 中加载 uiview 而无需在情节提要中使用 IBOutlets。
    【解决方案4】:

    感谢您对这个问题的回答。他们都很好。我已经接受了对我来说最容易实现的那个。这是一种不同的方法,也适用于某些情况:

        var myView: myCoolView = myCoolView()  // subclass of uiview with xib
    

    然后,添加 ViewDidLoad:

        myView.frame = CGRectMake(0, 64, self.view.frame.size.width, 175)
        myView.titleLabel.text = stringOne
        myView.backgroundImage.image = imageOne
        myView.contentMode = UIViewContentMode.ScaleAspectFill
        myView.autoresizingMask = UIViewAutoresizing.FlexibleBottomMargin | UIViewAutoresizing.FlexibleHeight | UIViewAutoresizing.FlexibleRightMargin | UIViewAutoresizing.FlexibleLeftMargin | UIViewAutoresizing.FlexibleTopMargin | UIViewAutoresizing.FlexibleWidth
        self.view.addSubview(myView)
    

    【讨论】:

      【解决方案5】:

      我从here 找到了另一个解决方案并适合我(Swift 2):

      let myView = NSBundle.mainBundle().loadNibNamed("myView", owner: self, options: nil).first as! myView
      self.view.addSubview(myView)
      myView.translatesAutoresizingMaskIntoConstraints = false
      self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[view]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["view":myView]))
      self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[view]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["view":myView]))
      myView.myButton.setTitle("myTitle", forState: .Normal)
      

      以编程方式创建的约束。在 xib 中创建的 outlet 在主 viewController 类中很容易获得。

      不管怎样,这段代码肯定有待改进。我是一个粗略的程序员。

      【讨论】:

        【解决方案6】:

        最佳答案对我不起作用。我刚刚完成:

        let newView = Bundle.main.loadNibNamed("MyNib", owner: self, options: nil)?.first as! UIView
            self.view.addSubview(newView)
            newView.translatesAutoresizingMaskIntoConstraints = false
            self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[view]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["view":newView]))
            self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[view]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["view":newView]))
        

        像魅力一样工作

        如果您需要访问某个元素,您可以这样做:

        newView.myButton.setTitle("myTitle", forState: .Normal)
        

        编码不错!

        【讨论】:

          猜你喜欢
          • 2017-05-06
          • 2014-03-20
          • 2013-05-18
          • 2015-07-31
          • 2012-11-23
          • 1970-01-01
          • 1970-01-01
          • 2017-06-18
          • 2015-11-14
          相关资源
          最近更新 更多