从 CollectionView Cell 以编程方式执行 Segue
Posted
技术标签:
【中文标题】从 CollectionView Cell 以编程方式执行 Segue【英文标题】:Performing Segue Programmatically from CollectionView Cell 【发布时间】:2017-07-21 01:15:04 【问题描述】:我目前在集合视图单元格中创建了集合视图。 集合视图中的集合视图。我在第二个视图控制器中的didSelectItemAt
上执行转场或呈现视图控制器时遇到问题。现在,我尝试的所有操作都会导致崩溃,或者出现“视图不在视图层次结构中”错误。
来一张图说明:
这是我的代码:
集合视图 1:
class ExploreVC: UIViewController, UICollectionViewDataSource,UICollectionViewDelegate, UICollectionViewDelegateFlowLayout
var businessView: UIViewController!
let foodCategory = exploreCategory()
let shopCategory = exploreCategory()
let cultureCategory = exploreCategory()
let nightlifeCategory = exploreCategory()
@IBOutlet weak var collectionView: UICollectionView!
override func viewWillAppear(_ animated: Bool)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.backgroundColor = UIColor.clear
collectionView.register(categoryCell.self, forCellWithReuseIdentifier: "category")
exploreCategories = exploreCategory.setCategories()
businessView = storyboard?.instantiateViewController(withIdentifier: "businessPage")
func setCategories() -> [exploreCategory]
foodCategory.name = "Good Food"
shopCategory.name = "Shopping Near You"
cultureCategory.name = "Cultural Highlights"
nightlifeCategory.name = "Start Your Night"
return [foodCategory,shopCategory,cultureCategory,nightlifeCategory]
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "category", for: indexPath) as! categoryCell
cell.exploreCategory = exploreCategories?[indexPath.item]
return cell
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
if let count = exploreCategories?.count
return count
return 0
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
let size = CGSize(width: view.frame.width, height: 280)
return size
func gotToBusinessPage()
print("gotToBusinessPage is being executed")
let top: UIViewController? =
UIApplication.shared.keyWindow?.rootViewController
let businessPage = BusinessVC()
top?.performSegue(withIdentifier: "toBusiness", sender: self)
//top?.present(businessPage, animated: true) _ in
//present(businessPage, animated: true)
集合视图 1 单元格:
import UIKit
import Foundation
import AlgoliaSearch
import SwiftyJSON
import AFNetworking
class categoryCell: UICollectionViewCell, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout
private let cellId = "exploreCell"
//* MARK Algolia
var exploreSearch = [exploreBusiness]()
var businessIndex: AlgoliaSearch.Index!
let query = Query()
var searchId = 0
var displayedSearchId = -1
var loadedPage: UInt = 0
var nbPages: UInt = 0
//*MARK Set Cell Values
var exploreCategory: exploreCategory?
didSet
if let name = exploreCategory?.name
categoryLabel.text = name.uppercased()
//*MARK Init
override init(frame: CGRect)
super.init(frame: frame)
setUpViews()
searchFood(category: (exploreCategories?[0])!)
searchShop(category: (exploreCategories?[1])!)
searchCulture(category: (exploreCategories?[2])!)
searchNightlife(category: (exploreCategories?[3])!)
required init?(coder aDecoder: NSCoder)
super.init(coder: aDecoder)
//*MARK UI Mark Up
let categoryLabel: UILabel =
let black = UIColor(red:0.29, green:0.29, blue:0.29, alpha:1.0)
let label = UILabel()
label.font = UIFont(name: "AvenirNext-DemiBold", size: 14)
label.textColor = black
label.text = "TRENDING NEAR YOU"
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 1
return label
()
let businessCollectionView: UICollectionView =
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.backgroundColor = UIColor.clear
return collectionView
()
//* MARK UI Set Up
func setUpViews()
addSubview(businessCollectionView)
addSubview(categoryLabel)
businessCollectionView.dataSource = self
businessCollectionView.delegate = self
businessCollectionView.showsHorizontalScrollIndicator = false
businessCollectionView.register(exploreCell.self, forCellWithReuseIdentifier: cellId)
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-16-[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": categoryLabel]))
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": businessCollectionView]))
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[categoryLabel(24)][v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": businessCollectionView, "categoryLabel": categoryLabel]))
//*MARK CollectionView Set Up
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
if let count = exploreCategory?.businesses?.count
return count
return 0
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! exploreCell
cell.business = exploreCategory?.businesses?[indexPath.item]
return cell
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
let size = CGSize(width: 124, height: frame.height - 30)
return size
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets
return UIEdgeInsetsMake(0, 16, 0, 16)
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! exploreCell
cell.business = exploreCategory?.businesses?[indexPath.item]
let cellData = cell.business
businessName = (cellData?.businessName!)!
businessID = (cellData?.objectID!)!
businessType = (cellData?.businessType!)!
zipcode = (cellData?.zipcode!)!
state = (cellData?.state!)!
address = (cellData?.address!)!
city = (cellData?.city!)!
hours = "\(cellData?.openTime! ?? "error") - \(cellData?.closeTime! ?? "error")"
if cellData?.image1URL?.isEmpty == false
image1 = (cellData?.image1URL!)!
images.append(image1)
if cellData?.image2URL?.isEmpty == false
image2 = (cellData?.image2URL!)!
images.append(image2)
if cellData?.image3URL?.isEmpty == false
image3 = (cellData?.image3URL!)!
images.append(image3)
if cellData?.image4URL?.isEmpty == false
image4 = (cellData?.image4URL!)!
images.append(image4)
if cellData?.image5URL?.isEmpty == false
image5 = (cellData?.image5URL!)!
images.append(image5)
if cellData?.image6URL?.isEmpty == false
image6 = (cellData?.image6URL!)!
images.append(image6)
if cellData?.image7URL?.isEmpty == false
image7 = (cellData?.image7URL!)!
images.append(image7)
let tab = ExploreVC()
tab.gotToBusinessPage()
第二个集合视图单元格:
import UIKit
import AlamofireImage
import Alamofire
class exploreCell: UICollectionViewCell
weak var exploreVC : ExploreVC?
var mainVC = ExploreVC()
var business: exploreBusiness?
didSet
nameLabel.text = business?.businessName
reviewLabel.text = "\(business?.reviewCount! ?? 0) Reviews"
let url = URL(string: (business?.image1URL)!)
Alamofire.request(url!).responseImage response in
if let image = response.result.value
self.imageView.image = image
override init(frame: CGRect)
super.init(frame: frame)
setUpViews()
required init?(coder aDecoder: NSCoder)
super.init(coder: aDecoder)
let imageView: UIImageView =
let iv = UIImageView()
iv.contentMode = .scaleAspectFill
iv.layer.cornerRadius = 4
iv.layer.masksToBounds = true
return iv
()
let nameLabel: UILabel =
let black = UIColor(red:0.29, green:0.29, blue:0.29, alpha:1.0)
let label = UILabel()
label.text = "Paradise Diner"
label.font = UIFont(name: "AvenirNext-DemiBold", size: 14)
label.textColor = black
label.numberOfLines = 2
return label
()
let reviewIcon: UIImageView =
let iv = UIImageView()
iv.image = #imageLiteral(resourceName: "review-black")
iv.contentMode = .scaleAspectFill
iv.layer.masksToBounds = true
return iv
()
let reviewLabel: UILabel =
let black = UIColor(red:0.29, green:0.29, blue:0.29, alpha:1.0)
let label = UILabel()
label.text = "45 Reviews"
label.font = UIFont(name: "AvenirNext-DemiBold", size: 14)
label.textColor = black
label.numberOfLines = 1
return label
()
func setUpViews()
addSubview(imageView)
addSubview(nameLabel)
addSubview(reviewIcon)
addSubview(reviewLabel)
let ImageRect = CGRect(x: 0, y: 0, width: frame.width, height: 182)
let nameLabelRect = CGRect(x: 0, y: 190 , width: frame.width, height: 20)
let reviewRect = CGRect(x: 0, y: 220 , width: 16, height: 11)
let reviewLabelRect = CGRect(x: 22, y: 217 , width: frame.width - 16, height: 16)
imageView.frame = ImageRect
nameLabel.frame = nameLabelRect
reviewIcon.frame = reviewRect
reviewLabel.frame = reviewLabelRect
如果不清楚,我很乐意解释更多。
【问题讨论】:
CollectionView 委托方法应该在控制器ExploreVC
中,而不是在单元格中。
单元格中有一个委托方法,因为它是集合视图中的集合视图
【参考方案1】:
你的代码的问题是这一行:
let tab = ExploreVC()
这不是要求您当前的 ExploreVC 执行此操作,而是要求新创建的实例执行此操作(这就是它失败的原因)。
你必须做的来解决这个问题(不要过多地修改你的代码)是:
1) 在“categoryCell”中添加一个弱变量来引用实际的 ExploreVC:
weak var exploreVC : ExploreVC?
2) 在 ExploreVC 的“cellForItemAt”中添加对它的引用:
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "category", for: indexPath) as! categoryCell
cell.exploreCategory = exploreCategories?[indexPath.item]
cell.exploreVC = self
return cell
3) 在 didSelectItem 函数中删除“let tab = ExploreVC()”并添加它:
exploreVC?.gotToBusinessPage()
【讨论】:
我正在尝试从第二个集合视图的单元格中执行或呈现视图控制器。 (黑色细胞) 然后将引用传递给那个。关键是您必须让您的 ExploreVC 执行 segue,而不是像您似乎正在做的新实例。 但是如果它在 categoryCell 类中,我如何将它设置为 self?或者我可以在里面设置为 self 吗? 我想通了!我将weak var设为全局变量,并在ExploreVC的viewDidLoad中设置为self以上是关于从 CollectionView Cell 以编程方式执行 Segue的主要内容,如果未能解决你的问题,请参考以下文章
点击 CollectionView Cell 按钮以播放来自特定阵列的声音并从特定阵列复制电影
点击CollectionView Cell的下半部分时推动ViewController