从 CollectionViewCell 呈现视图时,调用中缺少参数 'coder' 的参数

Missing argument for parameter 'coder' in call when presenting a view from CollectionViewCell

我有一个 ViewController,里面有一个 CollectionView,还有一个 CollectionViewCell,里面有一个 TableView。当用户单击 TableViewCell 时,我想显示一个 ViewController 显示用户任务的详细视图,但我在这一行 let vc = MyTasksDetailController(). 这是我的代码:

ProfileController

final class ProfileController: UIViewController {
   
private var collectionView: UICollectionView?
    let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .vertical
        layout.minimumLineSpacing = 1
        layout.minimumInteritemSpacing = 1
        layout.sectionInset = UIEdgeInsets(top: 0, left: 1, bottom: 0, right: 1)
        let size = (view.width - 4)/3
        layout.itemSize = CGSize(width: size, height: size)
        collectionView = UICollectionView(frame: .zero,
                                          collectionViewLayout: layout)
        // Headers
        collectionView?.register(ProfileInfoHeader.self,
                                 forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader,
                                 withReuseIdentifier: ProfileInfoHeader.identifier)
        
        collectionView?.register(MyTasksCollectionCell.self,
                                 forCellWithReuseIdentifier: MyTasksCollectionCell.identifier)
        
        collectionView?.delegate = self
        collectionView?.dataSource = self
        guard let collectionView = collectionView else {
            return
     }
        view.addSubview(collectionView)
    }
extension ProfileController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1 
    }
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 1 
    }
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MyTasksCollectionCell.identifier,
                                                      for: indexPath)as! MyTasksCollectionCell
        
            return cell
        
    }

MyTaskCollectionCell

class MyTasksCollectionCell: UICollectionViewCell, UITableViewDelegate, UITableViewDataSource {

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
                 tableView.deselectRow(at: indexPath, animated: true)
 let task = {() -> Add in
        switch (displayedTask) {
          case .current:
             // First segment tapped
            return self.tasks[indexPath.row]
          case past:
             // Second segment tapped
            return self.pastTasks[indexPath.row]
        }
    }()
     let vc = MyTasksDetailController() //ERROR HERE: Missing argument for parameter 'coder' in call : Insert 'coder: <#NSCoder#>'
self.present(vc, animated: true, completion: nil)

}

MyTaskTableCell

class MyPostsTableCell: UITableViewCell {
    
    var setdescriptionTitleLabel: String? {
        didSet {
            descriptionTitleLabel.text = setdescriptionTitleLabel ?? ""
        }
    }
    var setdateLabel: String? {
        didSet {
            dateLabel.text = setdateLabel ?? ""
        }
    }
    var sethourLabel: String? {
        didSet {
            hourLabel.text = sethourLabel ?? ""
        }
    }
    var setDateIcon: UIImage? {
        didSet {
            dateIcon.image = UIImage()
        }
    }
    var setHourIcon: UIImage? {
        didSet {
            hourIcon.image = UIImage()
        }
    }

MyTasksDetailController

class MyTasksDetailController: UIViewController  {

internal var task: Add? {
       didSet {
            if let task = task {
                setDescriptionLabel = task.description
                setDescriptionTitleLabel = task.descriptionTitle
             }
        }
    }    
    var setDescriptionLabel: String? {
        didSet {
            descriptionLabel.text = setDescriptionLabel ?? ""
        }
    }
    var setdescriptionTitleLabel: String? {
        didSet {
            descriptionTitleLabel.text = setdescriptionTitleLabel ?? ""
        }
    }
     let descriptionLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.font = UIFont.systemFont(ofSize: 28, weight: .bold)
        label.textAlignment = .center
        return label
    }()
    
     let descriptionTitleLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.font = UIFont.systemFont(ofSize: 18, weight: .bold)
        label.textAlignment = .center
        label.numberOfLines = 3
        return label
    }()
   let container: UIView = {
        let v = UIView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.clipsToBounds = true
        v.backgroundColor = .white
        v.layer.cornerRadius = 24

        v.backgroundColor =
            // 1
            UIColor { traitCollection in
              // 2
              switch traitCollection.userInterfaceStyle {
              case .dark:
                // 3
                 v.layer.borderColor = UIColor.label.cgColor
                return UIColor.systemBackground

              default:
                // 4
                 v.layer.borderColor = UIColor.black.cgColor
                return UIColor.systemBackground
              }
            }
        return v
    }()
 lazy var stackContainer: UIStackView = {
       let stackContainer = UIStackView(arrangedSubviews: [stackDesLabel, stackDesTitLabel])
        stackContainer.translatesAutoresizingMaskIntoConstraints = false
        stackContainer.axis = .vertical
        stackContainer.distribution  = UIStackView.Distribution.fillEqually
       return stackContainer
   }()
    lazy var stackDesLabel: UIStackView = {
        let stackDesLabel = UIStackView(arrangedSubviews: [descriptionLabel])
        stackDesLabel.translatesAutoresizingMaskIntoConstraints = false
        stackDesLabel.axis = .vertical
        stackDesLabel.distribution  = UIStackView.Distribution.fillProportionally
        return stackDesLabel
    }()
    lazy var stackDesTitLabel: UIStackView = {
       let stackDesTitLabel = UIStackView(arrangedSubviews: [descriptionTitleLabel])
        stackDesTitLabel.translatesAutoresizingMaskIntoConstraints = false
        stackDesTitLabel.axis = .horizontal
        stackDesTitLabel.distribution  = UIStackView.Distribution.fillEqually
       return stackDesTitLabel
   }()
    override func viewDidLoad() {
        view.addSubview(stackDesLabel)
        view.addSubview(stackDesTitLabel)

        stackContainer.leadingAnchor.constraint(equalTo: container.leadingAnchor).isActive = true
        stackContainer.trailingAnchor.constraint(equalTo: container.trailingAnchor).isActive = true
        stackContainer.centerYAnchor.constraint(equalTo: container.centerYAnchor).isActive = true
        stackContainer.centerXAnchor.constraint(equalTo: container.centerXAnchor).isActive = true
        stackContainer.heightAnchor.constraint(equalTo: container.heightAnchor).isActive = true
        stackContainer.widthAnchor.constraint(equalTo: container.widthAnchor).isActive = true
        
        stackDesTitLabel.topAnchor.constraint(equalTo: stackContainer.topAnchor, constant: 50).isActive = true
         stackDesTitLabel.widthAnchor.constraint(equalTo: stackContainer.widthAnchor).isActive = true
        stackDesTitLabel.centerXAnchor.constraint(equalTo: stackContainer.centerXAnchor).isActive = true
        stackDesLabel.topAnchor.constraint(equalTo: stackDesTitLabel.bottomAnchor, constant: 50).isActive = true
        stackDesLabel.leadingAnchor.constraint(equalTo: stackContainer.leadingAnchor, constant: 5).isActive = true
        stackDesLabel.widthAnchor.constraint(equalTo: stackContainer.widthAnchor).isActive = true
 }

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

添加(数据结构)

struct Add {
    static var details: Add = Add()
    var descriptionTitle: String = ""
    var description: String = ""
    var id: String?
    var date: String = ""
    var hour: String = ""

    func getDict() -> [String: Any] {
              let dict = [
                          "descriptionTitle": self.descriptionTitle,
                          "description": self.description,
                          "date": self.date,
                          "hour": self.hour,
                ] as [String : Any]
               return dict
         }

}

正如我所怀疑的那样,问题出在 MyTasksDetailController 与您实施

required init?(coder aDecoder: NSCoder)

如果您只是想要一个快速的解决方案,您可以根据对您的应用程序最有意义的事情做以下两件事之一:

  1. 删除 required init?(coder aDecoder: NSCoder)
  2. 像这样添加你自己的初始化器:
    init() {
        // Keep nil if you are not initializing from XIB
        super.init(nibName: nil, bundle: nil)
    }
    

说明

我相信您试图实现的目标违反了初始化继承规则,这就是您收到该错误的原因。

我正在查看全部rules from here

当您这样做时:class MyTasksDetailController: UIViewController - 如果您遵循以下规则,您将自动从 UIViewController 继承初始化程序:

自动初始化程序继承

Rule 1

If your subclass doesn’t define any designated initializers, it automatically inherits all of its superclass designated initializers.

Rule 2

If your subclass provides an implementation of all of its superclass designated initializers—either by inheriting them as per rule 1, or by providing a custom implementation as part of its definition—then it automatically inherits all of the superclass convenience initializers.

These rules apply even if your subclass adds further convenience initializers.

现在当您添加:

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

它违反了规则 1,您正在添加自己的指定初始化程序,因此您丢失了之前继承的所有其他初始化程序,因此您会收到此错误:

所以现在您有 2 个选项,如前所述。

1.删除 required init?(coder aDecoder: NSCoder)

如果您在情节提要中创建视图控制器,则需要此版本的 init,因为在这种情况下会自动调用它。如果您不打算这样做,您可以将其删除。如果你打算在故事板中使用它,你需要完成它:

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

2。添加您自己的指定初始化器

通过添加 required init?(coder aDecoder: NSCoder),您丢失了之前继承的默认初始化程序,因此现在您需要创建自己的初始化程序:

init() {
    // Initialize your local vars
    
    // Call designated initializer from the super class
    // Keep nil if you are not initializing from XIB
    super.init(nibName: nil, bundle: nil)
}

以下任一方法都可以解决您的问题:

更新最后的想法

  1. 以上应该可以解决您的初始化错误
  2. 但是,你会在下一行出错self.present(vc, animated: true, completion: nil)

简而言之,present (documentation reference)只能被视图控制器调用

在您的代码中 MyTasksCollectionCell 是一个 UICollectionViewCell,因此您需要通知视图控制器您的集合视图位于其中,一个单元格被点击并且视图控制器需要处理呈现新视图。

您可以通过两种方式做到这一点:

  1. Delegates - 让您的视图控制器负责处理单元格点击并呈现另一个视图控制器
  2. Observers - 通知您的视图控制器处理单元格点击并呈现另一个视图控制器

这两个都会

这些只是给您一个想法的快速链接,但我建议您多用谷歌搜索一下,看看哪个最适合您的情况