【问题标题】:How can I update a UICollectionView from another class?如何从另一个类更新 UICollectionView?
【发布时间】:2021-01-09 11:08:45
【问题描述】:

我现在尝试了几天,但还没有取得任何成果。我想要做的是当用户从 ViewController 类中选择一个 User 项目时,我想将它保存在 Realm 中并在 SavedInterestsViewController 类的 CollectionView 中显示它。我使用了这篇文章How to access and refresh a UITableView from another class in Swift 中建议的委托模式,但不幸的是我仍然收到 nil,我猜是因为 GC 已经删除了 collectionView 出口,对吧? (如果我误解了,请纠正我)。但是,我怎样才能通过使用委托模式来实现它呢?这是我的代码,这是用户选择新用户项的类:

protocol ViewControllerDelegate {
func didUpdate(sender: ViewController)
}

class ViewController: UIViewController {

@IBOutlet weak var searchBar: UISearchBar!
@IBOutlet weak var collectionView: UICollectionView!
var delegate: ViewControllerDelegate?
let numberOfTweets = 5
let realm = try! Realm()

var image = UIImage()
var imageArray: [String] = []
var userArray: [User] = []

override func viewDidLoad() {
    super.viewDidLoad()
    
    collectionView.delegate = self
    collectionView.dataSource = self
    collectionView.register(UINib(nibName: "CollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "CollectionCell")
    searchBar.delegate = self
}

}

extension ViewController: UISearchBarDelegate {

func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
    print("One second...")
    let functionClass = NetworkingFunctions()
    var loopCount = 0
    functionClass.getWikipediaAssumptions(for: searchBar.text!) { [self] (articleArray) in
        self.userArray.removeAll()
        for x in articleArray {
            functionClass.performWikipediaSearch(with: x, language: WikipediaLanguage("en")) { (user) in
                self.userArray.append(user)
                collectionView.reloadData()
                loopCount += 1
            }
        }
    }
}
}

extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return userArray.count
}

func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 1
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionCell", for: indexPath) as! CollectionViewCell
    let image = UIImage.init(data: userArray[indexPath.item].image as Data)
    cell.userImage.image = image
    cell.nameLabel.text = userArray[indexPath.item].name
    cell.userImage.layer.borderColor = image?.averageColor?.cgColor
    if userArray[indexPath.item].checked == false {
        cell.checkmark.isHidden = true
    } else {
        cell.checkmark.isHidden = false
    }
    return cell
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    if userArray[indexPath.item].checked == false {
        userArray[indexPath.item].checked = true
        collectionView.reloadData()
        let newUser = User()
        newUser.image = userArray[indexPath.item].image
        newUser.name = userArray[indexPath.item].name
        newUser.checked = true
        try! realm.write {
            realm.add(newUser)
        }
        self.delegate = SavedInterestsViewController()
        self.delegate?.didUpdate(sender: self)
    }
    else {
        userArray[indexPath.item].checked = false
        collectionView.reloadData()
    }
}
}

extension ViewController: UICollectionViewDelegateFlowLayout {

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let width = UIScreen.main.bounds.width/3 - 10
    let height = width
    return CGSize(width: width, height: height)
}

}

class User: Object {

@objc dynamic var image: NSData = NSData()
@objc dynamic var name: String = ""
@objc dynamic var checked: Bool = false

}

...这是我想要显示所选项目的类,在用户单击 ViewController 类的导航控制器的“后退”按钮后:

class SavedInterestsViewController: UIViewController, ViewControllerDelegate {
func didUpdate(sender: ViewController) {
    DispatchQueue.main.async {
        self.collectionView.reloadData()
    }
}

@IBOutlet weak var addButton: UIBarButtonItem!
@IBOutlet weak var collectionView: UICollectionView!
let realm = try! Realm()

var userArray: [User] = []

override func viewDidLoad() {
    super.viewDidLoad()

    collectionView.delegate = self
    collectionView.dataSource = self
    collectionView.register(UINib(nibName: "CollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "CollectionCell")
    fetchDataFromRealm()
    
}

@IBAction func addButtonPressed(_ sender: UIBarButtonItem) {
    performSegue(withIdentifier: "SavedToNew", sender: self)
}

func fetchDataFromRealm() {
    userArray.append(contentsOf: realm.objects(User.self))
    collectionView.reloadData()
}

}

extension SavedInterestsViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return userArray.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionCell", for: indexPath) as! CollectionViewCell
    let image = UIImage.init(data: userArray[indexPath.item].image as Data)
    cell.userImage.image = image
    cell.nameLabel.text = userArray[indexPath.item].name
    cell.userImage.layer.borderColor = image?.averageColor?.cgColor
    if userArray[indexPath.item].checked == false {
        cell.checkmark.isHidden = true
    } else {
        cell.checkmark.isHidden = false
    }
    return cell
}
}

extension SavedInterestsViewController: UICollectionViewDelegateFlowLayout {

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let width = UIScreen.main.bounds.width/3 - 10
    let height = width
    return CGSize(width: width, height: height)
}

}

【问题讨论】:

    标签: swift collections


    【解决方案1】:

    在你的代码中有行

    self.delegate = SavedInterestsViewController()
    self.delegate?.didUpdate(sender: self)
    

    但它几乎什么都不做 - 你将代理设置为新创建的类,didUpdate 它 - 但我看不到它有任何用途 - 你没有以任何方式呈现它。

    如果我理解正确 - 你有 SavedInterestsViewController,从它 - 你打开 ViewController,做一些事情,然后回到 SavedInterestsViewController。 (我可能对您的流程有误 - 如果是,请纠正我)

    在这个流程中 - 您在 ViewController 中有委托属性,但它必须是 SavedInterestsViewController 类型。当您从中打开 ViewController 时,您必须将其设置为 SavedInterestsViewController。稍后在 ViewController 中,您必须调用委托的 didUpdate 方法。

    【讨论】:

    • 是的,您描述的流程是正确的。好的,所以我必须设置self.delegate = SavedInterestsViewController.self,但是你说我打开它时必须将它设置为SavedInterestsViewController是什么意思?
    • 现在我尝试了:` override func prepare(for segue: UIStoryboardSegue, sender: Any?) { let vc = segue.destination as! ViewController vc.delegate? = SavedInterestsViewController.self 为! SavedViewController 类中的 ViewControllerDelegate }`,但这不起作用。我没有返回 nil,但从未调用过委托方法。
    • 成功了。我必须在准备 segue 函数中的委托属性之后去掉问号,就是这样。谢谢你的回答,这真的让我很紧张!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-05
    • 1970-01-01
    相关资源
    最近更新 更多