通过编程迅速传递数据的问题



我在将数据从一个Uicollection ViewController传递到另一个UicollectionViewController groponally中遇到困难。

目前我的设置如下:

  1. 正在传递数据(RestaurantController

    的UicollectionViewController

    1a。uicollectionViewCell(RestaurantCell

    • 此UicollectionViewCell具有另一个自定义UicollectionViewCell(RestaurantCollectionViewCell
  2. 接收数据(MenuController

    的UicollectionViewController

    2a。uicollectionViewCell(MenuCell

在我的RestaurantCell内部,我正在加载JSON的数据,并将其附加到一个名为餐厅的新数组:var restaurants = [RestaurantModel]()。但是,当我尝试使用var restaurant: RestaurantModel?中加载MenuController中的餐厅名称或任何餐厅对象时,我会得到零值。我觉得我的设置不正确,或者我在某个地方犯了一个愚蠢的错误。也许两者俩。我在下面的每个班级都粘贴了代码。

其中的值返回menucontroller的内部:

print("Restaurant Name:", restaurant?.name)

print("Restaurant Id:", restaurant?.id)

是自定义委托引起问题的?

您非常感谢您的帮助和建议!

我的RestaurantController内部:

 import UIKit
 import FBSDKLoginKit
 class RestaurantController: UICollectionViewController, UICollectionViewDelegateFlowLayout, SWRevealViewControllerDelegate, UISearchBarDelegate, RestaurantDelegate {
var restaurantCell: RestaurantCell?
private let restaurantCellId = "restaurantCellId"
override func viewDidLoad() {
    super.viewDidLoad()
    collectionView?.backgroundColor = UIColor.qpizzaWhite()
    collectionView?.register(RestaurantCell.self, forCellWithReuseIdentifier: restaurantCellId)

    if self.revealViewController() != nil {
        navigationItem.leftBarButtonItem = UIBarButtonItem(image: #imageLiteral(resourceName: "icon_menu_24dp").withRenderingMode(.alwaysOriginal), style: .plain, target: self.revealViewController(), action: #selector(SWRevealViewController.revealToggle(_:)))
        self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
    }
}
// FIXME: issue with this...navigationcontroller is presenting, not pushing ontop of stack view
func didTapRestaurantCell(cell: RestaurantCell) {
    print("Did Tap Restaurant Cell - Restaurant Controller")
    let layout = UICollectionViewFlowLayout()
    let controller = MenuController(collectionViewLayout: layout)
    navigationController?.pushViewController(controller, animated: true)
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: restaurantCellId, for: indexPath) as! RestaurantCell
    cell.delegate = self
    return cell
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 1
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: view.frame.width, height: view.frame.height)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    return 1
}
}

我的RestaurantCell内部:

protocol RestaurantDelegate {
    func didTapRestaurantCell(cell: RestaurantCell)
}

class RestaurantCell: BaseCell, UISearchBarDelegate, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
var delegate: RestaurantDelegate?
var restaurants = [RestaurantModel]()
var filteredRestaurants = [RestaurantModel]()
private let restaurantCollectionViewCell = "restaurantCollectionViewCell"
private let activityIndicator = UIActivityIndicatorView()
lazy var searchBar: UISearchBar = {
    let sb = UISearchBar()
    sb.placeholder = "Search Restaurant"
    sb.barTintColor = .white
    UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).backgroundColor = UIColor.qpizzaWhite()
    sb.delegate = self
    return sb
}()
lazy var collectionView: UICollectionView = {
    let layout = UICollectionViewFlowLayout()
    let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
    cv.backgroundColor = .white
    return cv
}()
override func setupViews() {
    super.setupViews()
    collectionView.register(RestaurantCollectionViewCell.self, forCellWithReuseIdentifier: restaurantCollectionViewCell)
    collectionView.delegate = self
    collectionView.dataSource = self
    backgroundColor = UIColor.qpizzaRed()
    addSubview(searchBar)
    addSubview(collectionView)
    _ = searchBar.anchor(topAnchor, left: leftAnchor, bottom: nil, right: rightAnchor, topConstant: 4, leftConstant: 4, bottomConstant: 0, rightConstant: 4, widthConstant: 0, heightConstant: 50)
    _ = collectionView.anchor(searchBar.bottomAnchor, left: leftAnchor, bottom: bottomAnchor, right: rightAnchor, topConstant: 0, leftConstant: 0, bottomConstant: 0, rightConstant: 0, widthConstant: 0, heightConstant: 0)
     loadRestaurants()
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    print(searchText)
    filteredRestaurants = self.restaurants.filter({ (restaruant: RestaurantModel) -> Bool in
        return restaruant.name?.lowercased().range(of: searchText.lowercased()) != nil
    })
    self.collectionView.reloadData()
}
// MARK - Helper Methods
func loadRestaurants() {
    showActivityIndicator()
    APIManager.shared.getRestaurants { (json) in
        if json != .null {
            //                print("Restaurant JSON:", json)
            self.restaurants = []
            if let restaurantList = json["restaurants"].array {
                for item in restaurantList {
                    let restaurant = RestaurantModel(json: item)
                    self.restaurants.append(restaurant)
                }
                self.collectionView.reloadData()
                self.hideActivityIndicator()
            }
        } else {
            print("Error loading JSON into Restaurant ViewController")
        }
    }
}
func loadImage(imageView: UIImageView, urlString: String) {
    let imageUrl: URL = URL(string: urlString)!
    URLSession.shared.dataTask(with: imageUrl) { (data, response, error) in
        if let error = error {
            print("Error loading image for Restaurant Controller:", error.localizedDescription)
        }
        guard let data = data, error == nil else { return }
        DispatchQueue.main.async(execute: {
            imageView.image = UIImage(data: data)
        })
        }.resume()
}
func showActivityIndicator() {
    activityIndicator.frame = CGRect(x: 0.0, y: 0.0, width: 40.0, height: 40.0)
    activityIndicator.center = center
    activityIndicator.hidesWhenStopped = true
    activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.whiteLarge
    activityIndicator.color = UIColor.qpizzaGold()
    addSubview(activityIndicator)
    activityIndicator.startAnimating()
}
func hideActivityIndicator() {
    activityIndicator.stopAnimating()
}
//MARK: CollectionView Delegate & DataSource Methods
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: restaurantCollectionViewCell, for: indexPath) as! RestaurantCollectionViewCell
    let restaurant: RestaurantModel
    if searchBar.text != "" {
        restaurant = filteredRestaurants[indexPath.item]
    } else {
        restaurant = restaurants[indexPath.item]
    }
    cell.restaurantNameLabel.text = restaurant.name
    cell.restaurantAddressLabel.text = restaurant.address
    if let logoName = restaurant.logo {
        let url = "(logoName)"
        loadImage(imageView: cell.restaurantLogoImageView, urlString: url)
    }
    return cell
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    if searchBar.text != "" {
        return self.filteredRestaurants.count
    }
    return self.restaurants.count
}
//FIXME: Restaurant Name Navigation Title is still not be passed from RestaurantCell to MenuController
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    print("Did Select Item - Restaurant Cell")
    let layout = UICollectionViewFlowLayout()
    let controller = MenuController(collectionViewLayout: layout)
    controller.restaurant = self.restaurants[indexPath.item]
    print("Controller", controller.restaurant) // Optional(QpizzaDelivery.RestaurantModel)
    print("Restaurant:", self.restaurants) // [QpizzaDelivery.RestaurantModel, QpizzaDelivery.RestaurantModel, QpizzaDelivery.RestaurantModel]
    print("IndexPath:", self.restaurants[indexPath.item]) // QpizzaDelivery.RestaurantModel
    delegate?.didTapRestaurantCell(cell: self)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: frame.width, height: 200)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    return 0.5
}
}

我的MenuController内部:

import UIKit
class MenuController: UICollectionViewController, UICollectionViewDelegateFlowLayout, SWRevealViewControllerDelegate {
private let menuCellId = "menuCellId"
var restaurant: RestaurantModel?
var menuItems = [MenuItemsModel]()
override func viewDidLoad() {
    super.viewDidLoad()
    collectionView?.backgroundColor = UIColor.qpizzaWhite()
    collectionView?.register(MenuCell.self, forCellWithReuseIdentifier: menuCellId)
    collectionView?.alwaysBounceVertical = true
    if self.revealViewController() != nil {
        navigationItem.leftBarButtonItem = UIBarButtonItem(image: #imageLiteral(resourceName: "menu2-black-32").withRenderingMode(.alwaysOriginal), style: .plain, target: self.revealViewController(), action: #selector(SWRevealViewController.revealToggle(_:)))
        self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
    }
    print("Restaurant Name:", restaurant?.name) // returns nil
    if let restaurantName = restaurant?.name {
        self.navigationItem.title = restaurantName
    }
    loadMenuItems()
}
func loadMenuItems() {
    print("Restaurant Id:", restaurant?.id) // returns nil
    if let restaurantId = restaurant?.id {
        print("RestaurantId:", restaurantId)
    }
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: menuCellId, for: indexPath) as! MenuCell
    return cell
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 3
}
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let layout = UICollectionViewFlowLayout()
    let controller = MenuDetailsController(collectionViewLayout: layout)
    navigationController?.pushViewController(controller, animated: true)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: view.frame.width, height: 120)
}
}

我的MenuCell内部:

import UIKit
class MenuCell: BaseCell {
let restaurantLabel: UILabel = {
    let label = UILabel()
    label.text = "Restaurant King"
    label.font = UIFont.boldSystemFont(ofSize: 16)
    label.textColor = .black
    label.numberOfLines = 0
    return label
}()
let mealImageView: UIImageView = {
    let iv = UIImageView()
    iv.image = #imageLiteral(resourceName: "button_chicken").withRenderingMode(.alwaysOriginal)
    iv.contentMode = .scaleAspectFill
    iv.clipsToBounds = true
    return iv
}()
let mealDetailsLabel: UILabel = {
    let label = UILabel()
    label.text = "Grass fed grass, American cheese, and friez"
    label.font = UIFont.boldSystemFont(ofSize: 12)
    label.textColor = UIColor.qpizzaBlack()
    label.numberOfLines = 0
    return label
}()
let mealPriceLabel: UILabel = {
    let label = UILabel()
    label.text = "$12.00"
    label.font = UIFont.boldSystemFont(ofSize: 12)
    label.textColor = UIColor.qpizzaBlack()
    return label
}()
let sepereatorView: UIView = {
    let view = UIView()
    view.backgroundColor = UIColor.lightGray
    return view
}()

override func setupViews() {
    super.setupViews()
    backgroundColor = UIColor.qpizzaWhite()
    addSubview(restaurantLabel)
    addSubview(mealImageView)
    addSubview(mealDetailsLabel)
    addSubview(mealPriceLabel)
    addSubview(sepereatorView)
    _ = mealImageView.anchor(topAnchor, left: nil, bottom: nil, right: rightAnchor, topConstant: 14, leftConstant: 0, bottomConstant: 0, rightConstant: 12, widthConstant: 60, heightConstant: 60)
    _ = restaurantLabel.anchor(topAnchor, left: leftAnchor, bottom: nil, right: mealImageView.leftAnchor, topConstant: 14, leftConstant: 12, bottomConstant: 0, rightConstant: 10, widthConstant: 0, heightConstant: 20)
    _ = mealDetailsLabel.anchor(restaurantLabel.bottomAnchor, left: leftAnchor, bottom: nil, right: mealImageView.leftAnchor, topConstant: 12, leftConstant: 12, bottomConstant: 0, rightConstant: 10, widthConstant: 0, heightConstant: 30)
    _ = mealPriceLabel.anchor(mealDetailsLabel.bottomAnchor, left: leftAnchor, bottom: nil, right: rightAnchor, topConstant: 10, leftConstant: 12, bottomConstant: 10, rightConstant: 10, widthConstant: 0, heightConstant: 20)
    _ = sepereatorView.anchor(nil, left: leftAnchor, bottom: bottomAnchor, right: rightAnchor, topConstant: 0, leftConstant: 20, bottomConstant: 4, rightConstant: 20, widthConstant: 0, heightConstant: 1)

}
}

只是一个快速的外观,声明正确类型的变量就是开始。但是实际上,您必须进行分配(=)才能将数据或类参考从一班级移动到下一个。

func didTapRestaurantCell(cell: RestaurantCell) {
  print("Did Tap Restaurant Cell - Restaurant Controller")
  let layout = UICollectionViewFlowLayout()
  let controller = MenuController(collectionViewLayout: layout)
  navigationController?.pushViewController(controller, animated: true)
  // you need to set the restaurant attribute of your new 
  // controller
  let indexPath = indexPath(for: cell)
  controller.restaurant = self.restaurants[indexPath.item]
}

感谢所有评论并协助我弄清楚这一点的人。我能够通过更改协议并将控制器作为参数传递来解决我的问题。

RestaurantCell中:

protocol RestaurantDelegate {
    func didTapRestaurantCell(cell: RestaurantCell, withMenuController: MenuController)
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    print("Did Select Item - Restaurant Cell")
    let layout = UICollectionViewFlowLayout()
    let controller = MenuController(collectionViewLayout: layout)
    controller.restaurant = self.restaurants[indexPath.item]
    delegate?.didTapRestaurantCell(cell: self, withMenuController: controller)
}

RestaurantController中:

func didTapRestaurantCell(cell: RestaurantCell, withMenuController controller: MenuController) {
    print("Did Tap Restaurant Cell - Restaurant Controller")
    navigationController?.pushViewController(controller, animated: true)
}

最新更新