Swift线程1:致命错误:init(coder :)尚未实现(调用超级解决方案不起作用) [英] Swift Thread 1: Fatal error: init(coder:) has not been implemented (Calling super solution doesn't work)

查看:394
本文介绍了Swift线程1:致命错误:init(coder :)尚未实现(调用超级解决方案不起作用)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嘿,我到处搜寻,仍然找不到解决我问题的方法。我在这里有一个自定义类:

Hey guys I have searched all around and still cannot find a solution to my problem. I have a custom class here :

import UIKit

/** 
  DatasourceController is simply a UICollectionViewController that 
allows you to quickly create list views.

 In order to render our items in your list, simply provide it with a 
Datasource object.
 */
open class DatasourceController: UICollectionViewController, 
UICollectionViewDelegateFlowLayout {

open let activityIndicatorView: UIActivityIndicatorView = {
    let aiv = UIActivityIndicatorView(activityIndicatorStyle: .whiteLarge)
    aiv.hidesWhenStopped = true
    aiv.color = .black
    return aiv
}()

open var datasource: Datasource? {
    didSet {
        if let cellClasses = datasource?.cellClasses() {
            for cellClass in cellClasses {
                collectionView?.register(cellClass, forCellWithReuseIdentifier: NSStringFromClass(cellClass))
            }
        }

        if let headerClasses = datasource?.headerClasses() {
            for headerClass in headerClasses {
                collectionView?.register(headerClass, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: NSStringFromClass(headerClass))
            }
        }

        if let footerClasses = datasource?.footerClasses() {
            for footerClass in footerClasses {
                collectionView?.register(footerClass, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: NSStringFromClass(footerClass))
            }
        }

        collectionView?.reloadData()
    }
}

public init() {
    super.init(collectionViewLayout: UICollectionViewFlowLayout())
}

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

let defaultCellId = "lbta_defaultCellId"
let defaultFooterId = "lbta_defaultFooterId"
let defaultHeaderId = "lbta_defaultHeaderId"

override open func viewDidLoad() {
    super.viewDidLoad()
    collectionView?.backgroundColor = .white
    collectionView?.alwaysBounceVertical = true

    view.addSubview(activityIndicatorView)
    activityIndicatorView.anchorCenterXToSuperview()
    activityIndicatorView.anchorCenterYToSuperview()

    collectionView?.register(DefaultCell.self, forCellWithReuseIdentifier: defaultCellId)
    collectionView?.register(DefaultHeader.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: defaultHeaderId)
    collectionView?.register(DefaultFooter.self, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: defaultFooterId)
}

override open func numberOfSections(in collectionView: UICollectionView) -> Int {
    return datasource?.numberOfSections() ?? 0
}

override open func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return datasource?.numberOfItems(section) ?? 0
}

//need to override this otherwise size doesn't get called
open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: view.frame.width, height: 50)
}

override open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    let cell: DatasourceCell

    if let cls = datasource?.cellClass(indexPath) {
        cell = collectionView.dequeueReusableCell(withReuseIdentifier: NSStringFromClass(cls), for: indexPath) as! DatasourceCell
    } else if let cellClasses = datasource?.cellClasses(), cellClasses.count > indexPath.section {
        let cls = cellClasses[indexPath.section]
        cell = collectionView.dequeueReusableCell(withReuseIdentifier: NSStringFromClass(cls), for: indexPath) as! DatasourceCell
    } else if let cls = datasource?.cellClasses().first {
        cell = collectionView.dequeueReusableCell(withReuseIdentifier: NSStringFromClass(cls), for: indexPath) as! DatasourceCell
    } else {
        cell = collectionView.dequeueReusableCell(withReuseIdentifier: defaultCellId, for: indexPath) as! DatasourceCell
    }

    cell.controller = self
    cell.datasourceItem = datasource?.item(indexPath)
    return cell
}

override open func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {

    let reusableView: DatasourceCell

    if kind == UICollectionElementKindSectionHeader {
        if let classes = datasource?.headerClasses(), classes.count > indexPath.section {
            reusableView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: NSStringFromClass(classes[indexPath.section]), for: indexPath) as! DatasourceCell
        } else if let cls = datasource?.headerClasses()?.first {
            reusableView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: NSStringFromClass(cls), for: indexPath) as! DatasourceCell
        } else {
            reusableView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: defaultHeaderId, for: indexPath) as! DatasourceCell
        }            
        reusableView.datasourceItem = datasource?.headerItem(indexPath.section)

    } else {
        if let classes = datasource?.footerClasses(), classes.count > indexPath.section {
            reusableView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: NSStringFromClass(classes[indexPath.section]), for: indexPath) as! DatasourceCell
        } else if let cls = datasource?.footerClasses()?.first {
            reusableView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: NSStringFromClass(cls), for: indexPath) as! DatasourceCell
        } else {
            reusableView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: defaultFooterId, for: indexPath) as! DatasourceCell
        }
        reusableView.datasourceItem = datasource?.footerItem(indexPath.section)
    }

    reusableView.controller = self

    return reusableView
}

open func getRefreshControl() -> UIRefreshControl {
    let rc = UIRefreshControl()
    rc.addTarget(self, action: #selector(handleRefresh), for: .valueChanged)
    return rc
}

@objc open func handleRefresh() {

}

open var layout: UICollectionViewFlowLayout? {
    get {
        return collectionViewLayout as? UICollectionViewFlowLayout
    }
}

}

哪个是我的故事板上的UICollectionView控制器的父类。我在这里为它创建一个控制器类:

Which is parent class to a UICollectionView controller in my storyboard. I make a controller class for it here :

import LBTAComponents

class homeView: DatasourceController {

override func viewDidLoad() {
    super.viewDidLoad()
}

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

} 

问题我得到线程1:致命错误:运行此代码时尚未实现init(coder :),我已经尝试了该解决方案:

Issue i get Thread 1: Fatal error: init(coder:) has not been implemented when running this code I have already tried the solution :

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

这不起作用。还有其他建议吗?如果您想亲自了解一下,我可以从cocoapod库中获得此​​框架:

this does not work. Any other suggestions? I got this framework from cocoapod library if you would like to see for your self :

pod'LBTAComponents'

pod 'LBTAComponents'

我怀疑这个问题与收藏夹视图和情节提要有关,但我无法弄清楚。

I suspect the issue is something to do with a collection view and the storyboard but i cant figure it out.

推荐答案

每当ViewController从Storyboard / XIB初始化时,它都是通过 init(coder:)来完成的

Whenever ViewController initialising form Storyboard/XIB, it doing it by init(coder: )

您的基类 DatasourceController 覆盖初始化程序

Your base class DatasourceController override initialisers

public init() {
    super.init(collectionViewLayout: UICollectionViewFlowLayout())
}

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

因此,当您在HomeController中调用super.init(coder:...)时,它将实际上调用 fatalError( init(coder :)尚未实现) 似乎谁写了这个课程,都不是一个很棒的故事板/ xib爱好者。

So when you calling super.init(coder:...) in your HomeController, it will actually call fatalError("init(coder:) has not been implemented") Seems whoever wrote this class, is not a great storyboard/xib lover.

您可以删除 DatasourceController 中的两个初始化程序,但要确保在情节提要中设置Flow布局。或者您可以将它们更改为super。

You can delete remove both initialisers in DatasourceController, but make sure that you setting up Flow layout in storyboard. Or you can change them to call super.

如果您不能更改基类,则无法从Storyboard加载VC。

If you can't change base class, you can't load your VC from Storyboard.

这篇关于Swift线程1:致命错误:init(coder :)尚未实现(调用超级解决方案不起作用)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆