【问题标题】:Be able to load xib from both Storyboard and ViewController能够从 Storyboard 和 ViewController 加载 xib
【发布时间】:2016-10-02 12:15:56
【问题描述】:

我正在尝试创建完美的解决方案,以直接从代码和 Storyboard 中创建自定义 UIView 子类。但是,我没有找到任何解决方案。

对于通过情节提要的IBDesignable 解决方案,我遵循了这个示例http://supereasyapps.com/blog/2014/12/15/create-an-ibdesignable-uiview-subclass-with-code-from-an-xib-file-in-xcode-6 并且效果很好。

但是如果我尝试通过UIViewController调用这个扩展方法来调用这个子类:

extension UIView {
    class func loadFromNibNamed(nibNamed: String, bundle : NSBundle? = nil) -> UIView? {
        return UINib(
            nibName: nibNamed,
            bundle: bundle
        ).instantiateWithOwner(nil, options: nil)[0] as? UIView
    }
}

它崩溃并说错过了this class is not key value coding-compliant for the key

有没有人找到解决方案与我分享两种可能性?

我需要它,因为我应该在情节提要中使用这个 UIView 以及 UITableview SectionHeader

【问题讨论】:

  • 您需要了解 swift 类可用于情节提要和 xib 文件。但是每次要使用它时都需要在情节提要上重新设计它。由于您想将此视图用作 UITableView 的标题,因此有一种方法可以仅使用 xibs 来执行此操作。看看这个线程希望它会帮助你。 stackoverflow.com/questions/31693901/…
  • 所以你的意思是我不能创建一个 xib 文件并将其用于情节提要或通过 NSBundle.mainBundle() 在视图控制器中实例化它?
  • 请看下面我的回答。

标签: ios swift storyboard


【解决方案1】:

为了保留这两种情况,我更喜欢在我的子类声明中写下这个:

@IBDesignable class CustomView: UIView {

    var view: UIView!

    @IBOutlet weak var button: UIButton!
    @IBOutlet weak var label: UILabel!


    func xibSetup() {
        view = loadViewFromNib()
        view.frame = bounds
        view.autoresizingMask = [UIViewAutoresizing.flexibleWidth, UIViewAutoresizing.flexibleHeight]
        addSubview(view)
    }

    func loadViewFromNib() -> UIView {

        let bundle = Bundle(for: type(of: self))
        let nib = UINib(nibName: "CustomView", bundle: bundle)
        let view = nib.instantiate(withOwner: self, options: nil)[0] as! UIView

        return view
    }


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

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

通过这种方式,我可以看到并将其添加到我的storyboard 中。 在ViewForHeaderInSection 方法中,我是这样写的:

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

let header = UIView()

let view:CustomView = CustomView(frame: CGRect(x: 0, y: 0, width:  self.view.frame.width, height: 30))

view.label.text = "header title: \(section)"

header.addSubview(view)


return header

}

所以它起作用了;)

【讨论】:

    【解决方案2】:

    这是在从情节提要实例化的视图控制器中使用 xib 的方法(在您的情况下,作为 UITableView 的节标题)。

    1. 创建一个 xib 文件,设计您的界面,以及与您的 swift 文件中的 IBOutlets 的 UI 元素的必要连接
    2. 在视图控制器类的 viewDidLoad 方法中(从情节提要中实例化的方法)

      // Name your xib and swift class as Header
      
      let headerNib = UINib(nibName: "Header", bundle: nil)
      self.tableView.registerNib(headerNib, forHeaderFooterViewReuseIdentifier: "header")
      
    3. 实现UITableViewDelegate方法viewForHeaderInSection

      func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
      
      let header = tableView.dequeueReusableHeaderFooterViewWithIdentifier("header") as! Header
      // Customise your header view here
      
      return header;
      }
      

    这就是你需要做的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-04
      • 2016-08-31
      • 1970-01-01
      • 1970-01-01
      • 2013-04-08
      • 2013-01-24
      • 2015-07-19
      • 2021-04-11
      相关资源
      最近更新 更多