Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/110.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios didSet属性值仅显示在print()中_Ios_Swift_Cells_Collectionview - Fatal编程技术网

Ios didSet属性值仅显示在print()中

Ios didSet属性值仅显示在print()中,ios,swift,cells,collectionview,Ios,Swift,Cells,Collectionview,初始目标: 有一个垂直放置的单元格列表的视图,其中显示一些信息。当用户单击单元格以显示包含更多信息的新视图时 到目前为止的路(对我任性的儿子讨好!): 我创建了两个视图控制器:ViewController(UICollectionViewController、UICollectionViewDelegateFlowLayout子类化)和DetailViewController(UIViewController子类化) 我创建了ViewController用于生成集合视图的单元格,以及Detai

初始目标

有一个垂直放置的单元格列表的视图,其中显示一些信息。当用户单击单元格以显示包含更多信息的新视图时

到目前为止的路(对我任性的儿子讨好!):

  • 我创建了两个视图控制器:ViewController(UICollectionViewController、UICollectionViewDelegateFlowLayout子类化)和DetailViewController(UIViewController子类化)
  • 我创建了ViewController用于生成集合视图的单元格,以及DetailViewController使用的详细视图
  • 我创建了一个名为Detail的结构作为自定义数据类型,它使用属性(例如名称、姓氏、地址等)提供数据存储
结构:

struct Detail: Decodable {
    let name: String?
    let surname: String?
    let address: String?
    let description: String?
}
我使用以下数据进行测试(测试完成后,我将通过API调用获取这些数据)。我将其放置在视图控制器中:

let details: [Detail] = [Detail(name: "Chris", surname: "Doe", address: "Neverland 31", description: "This is a description about Chris Doe"), Detail(name: "Tony", surname: "Cross", address: "Galaxy Road 1", description: "This is a description about Tony Cross")]
要使用上述信息和方法创建单元格,请执行以下操作:

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

    let detailView = DetailView()
    detailView.details = details[indexPath.item]

    let detailViewController = DetailViewController()
    detailViewController.modalTransitionStyle = .coverVertical
    self.present(detailViewController, animated: true, completion: nil)
}
而且:

let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! Cell
由于该方法要求我们返回UICollectionViewCell,我首先通过执行以下操作将相关信息发送到Cell:

cell.details = details[indexPath.item]
return cell
单元格中我使用didSet创建了以下属性,以帮助我检索信息:

var details: Detail? {
    didSet {
        guard let details = details else { return }
        guard let name = details.name else { return }
        ....
        ....
     }    
正如您可以理解的,使用来自ViewController的信息,我动态构建了每个单元格

在这一点上,所有人都很好

然后我试图在单击单元格时显示详细视图。为此,我在方法中遵循了相同的实践:

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

    let detailView = DetailView()
    detailView.details = details[indexPath.item]

    let detailViewController = DetailViewController()
    detailViewController.modalTransitionStyle = .coverVertical
    self.present(detailViewController, animated: true, completion: nil)
}
同样,在详细视图中我使用相同的方法获取与所选项目关联的数据。通过这种方式,我可以访问用户选择的单元格的数据,如下所示:

 import UIKit

 class DetailView: UIView {

     var dismissDetailViewAction: (() -> Void)?

     var details: Detail? {
        didSet {

            // get details
            guard let details = details else { return }
            guard let name = details.name else { return }
            guard let surname = details.surname else { return }
            guard let address = details.address else { return }
            guard let description = details.description else { return }

            // print description and it shows in the console but not in the view
            print(description)

            let attributedTextDescription = NSMutableAttributedString(string: description, attributes: [NSAttributedStringKey.font: UIFont.FontBook.AvertaRegular.of(size: 20), NSAttributedStringKey.foregroundColor: UIColor.white])
            briefDescription.attributedText = attributedTextDescription
            briefDescription.textAlignment = .center
            briefDescription.textColor = .white
            briefDescription.numberOfLines = 0
        }
    }

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

        setupView()
    }

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

    fileprivate func setupView() {
        setupDescriptionText()
        setupCloseButton()
    }

    let briefDescription: UITextView = {
        let text = UITextView()          
        text.textColor = .red
        return text
    }()

    let closeButton: UIButton = {
        let button = UIButton(title: "Close", font: UIFont.FontBook.AvertaRegular.of(size: 18), textColor: .white, cornerRadius: 5)
        button.backgroundColor = .black
        button.addTarget(self, action: #selector(closeDetailView), for: .touchUpInside)
        return button
    }()


    fileprivate func setupDescriptionText() {
        self.addSubview(briefDescription)
        briefDescription.translatesAutoresizingMaskIntoConstraints = false
        briefDescription.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 5).isActive = true
        briefDescription.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -5).isActive = true
        briefDescription.topAnchor.constraint(equalTo: self.topAnchor, constant: 10).isActive = true
        briefDescription.heightAnchor.constraint(equalToConstant: 300).isActive = true
    }

    fileprivate func setupCloseButton() {
        self.addSubview(closeButton)
        closeButton.translatesAutoresizingMaskIntoConstraints = false

        closeButton.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        closeButton.bottomAnchor.constraint(equalTo: self.safeAreaLayoutGuide.bottomAnchor, constant: -10).isActive = true
        closeButton.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 40).isActive = true
        closeButton.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -40).isActive = true
        closeButton.heightAnchor.constraint(equalToConstant: 60).isActive = true
    }

    @objc func closeDetailView() {
        dismissDetailViewAction?()
    }

}
所以,我实际上要做的是设计didSet外部视图的静态部分,以及didSet内部的动态部分。这适用于collectionView的单元格

我使用DetailViewController显示DetailView并在用户单击“关闭”按钮时自动关闭

我这样做的原因是我喜欢保持我的ViewController尽可能干净(海量的ViewController,不是我的东西)

问题

整个构建过程没有任何问题,但是当我单击单元格转到DetailView时,没有显示任何信息

奇怪的部分

在DetailView-->didSet中,当我使用print(name)时,它工作正常(您可以在控制台中看到正确的名称)。但当我尝试在视图中使用该值时,它将不会显示

我知道我的DetailView很好,因为如果我在其中使用硬编码的值,它就会工作(您会看到正确的结果)

有什么建议可以解释为什么它不能正常工作吗

PS:我正在以编程方式构建整个过程。没有涉及故事板

提前感谢,并对丢失的邮件表示歉意

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    let detailView = DetailView()
    detailView.details = details[indexPath.item]

    let detailViewController = DetailViewController()
    detailViewController.modalTransitionStyle = .coverVertical
    self.present(detailViewController, animated: true, completion: nil)
}
您在此处创建一个
DetailView
,将您的
详细信息传递给它。。。然后什么也不做

通常,
DetailView
将是
DetailViewController
的一个属性,您将把
details
传递给视图控制器,视图控制器将显示它


这里发生的事情是,您正在创建、配置并丢弃一个
DetailView
,而您可能应该使用
DetailViewController
拥有或应该拥有的视图

如前所述,您的
detailView
未在
detailViewController
中引用。相反,您在
DetailViewController
内创建了另一个
DetailView
实例,但此实例中没有
Detail

控制台消息是从
detailView
内部调用的,但是
detailViewController
内部是另一个没有调用此消息的实例,因为其
Detail
默认设置为nil

简而言之,要解决此问题,您只需执行以下更改:

import UIKit

class DetailViewController: UIViewController {

var detail: Detail!

private lazy var detailView: DetailView = {
    let mainView = DetailView(frame: self.view.frame)
    mainView.details = detail
    return mainView
}

override func viewDidLoad() {
    super.viewDidLoad()

    setupView()
}

fileprivate func setupView() {
    self.view.addSubview(detailView)

    self.homeDetailView.dismissDetailViewAction = dismissDetailView

    // pin view
    self.detailView.translatesAutoresizingMaskIntoConstraints = false
    self.detailView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
    self.detailView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
    self.detailView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
    self.detailView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
}

fileprivate func dismissDetailView() {
    // dismiss current (DetailViewController) controller
    self.dismiss(animated: true, completion: nil)
}

}
在您的
collectionView(…)
func中:

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let detailViewController = DetailViewController()
    detailViewController.detail = details[indexPath.item]
    detailViewController.modalTransitionStyle = .coverVertical
    self.present(detailViewController, animated: true, completion: nil)
}

您正在didSet中创建一组局部变量,它们在didSet退出后将不存在。您在这里试图实现什么,已设置的详细信息实例已包含名称、姓氏,。。。价值观如何在视图控制器中访问它?能否添加更多代码,说明您试图将这些详细信息绑定到视图,以及如何将detailView传递给detailViewController?现在问题太不清楚了。请检查编辑的问题。希望它能提供更多的信息。这样就可以了!但有一个错误:闭包后缺少括号。谢谢Stepan!