Ios 集合视图单元格导航
亲爱的同事们,请帮助我。我两个月前开始学习Swift,如果我能够完成,这将是我的第一个应用程序。。。 首先,我不使用故事板。在我的应用程序中,主窗口中有收藏视图。当您点击单元格中的图像(例如cat单元格中的cat图像)时,应打开cat.swift文件。但我还不能实现它。同样,如果您点击狗图像,应该会查看dog.swift文件。这是代码 这是打开应用程序时的主屏幕:Ios 集合视图单元格导航,ios,swift,uicollectionview,uinavigationcontroller,swift4,Ios,Swift,Uicollectionview,Uinavigationcontroller,Swift4,亲爱的同事们,请帮助我。我两个月前开始学习Swift,如果我能够完成,这将是我的第一个应用程序。。。 首先,我不使用故事板。在我的应用程序中,主窗口中有收藏视图。当您点击单元格中的图像(例如cat单元格中的cat图像)时,应打开cat.swift文件。但我还不能实现它。同样,如果您点击狗图像,应该会查看dog.swift文件。这是代码 这是打开应用程序时的主屏幕: import UIKit class FeaturedAnimalsController: UICollectionViewCon
import UIKit
class FeaturedAnimalsController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
var animalCategories: [AnimalCategory]?
private let cellId = "cellId"
override func viewDidLoad() {
super.viewDidLoad()
animalCategories = AnimalCategory.sampleAnimalCategories()
collectionView?.backgroundColor = .white
collectionView?.register(CategoryCell.self, forCellWithReuseIdentifier: cellId)
}
func showAnimalDetailForAnimal(animal: Animal) {
let layout = UICollectionViewFlowLayout()
let animalDetailController = AnimalDetailController(collectionViewLayout: layout)
animalDetailController.animal = animal
navigationController?.pushViewController(animalDetailController, animated: true)
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if let count = animalCategories?.count {
return count
}
return 0
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! CategoryCell
cell.featuredAnimalsController = self
cell.animalCategory = animalCategories?[indexPath.item]
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width, height: 230)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
这是分类单元:
import UIKit
class CategoryCell: UICollectionViewCell, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
var featuredAnimalsController: FeaturedAnimalsController?
var animalCategory: AnimalCategory? {
didSet {
if let name = animalCategory?.name {
nameLabel.text = name
}
}
}
private let cellId = "animalCellId"
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if let count = animalCategory?.animals?.count {
return count
}
return 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! AnimalCell
cell.animal = animalCategory?.animals?[indexPath.item]
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 100, height: frame.height - 32)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 0, left: 14, bottom: 0, right: 14)
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if let animal = animalCategory?.animals![indexPath.item] {
featuredAnimalsController?.showAnimalDetailForAnimal(animal: animal)
}
}
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
let nameLabel: UILabel = {
let label = UILabel()
label.text = "Cardiology"
label.font = UIFont.systemFont(ofSize: 16)
//label.numberOfLines = 1 --> DEFAULT
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
let animalsCollectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.backgroundColor = .clear
collectionView.translatesAutoresizingMaskIntoConstraints = false
return collectionView
}()
func setupViews() {
backgroundColor = .clear
animalsCollectionView.dataSource = self
animalsCollectionView.delegate = self
animalsCollectionView.register(AnimalCell.self, forCellWithReuseIdentifier: cellId)
addSubview(nameLabel)
addSubview(animalsCollectionView)
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-14-[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": nameLabel]))
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": animalsCollectionView]))
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[nameLabel(30)][v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": animalsCollectionView, "nameLabel": nameLabel]))
}
}
class AnimalCell: UICollectionViewCell {
var animal: Animal? {
didSet {
if let name = animal?.name {
nameLabel.text = name
}
categoryLabel.text = animal?.category
if let imageName = animal?.imageName {
imageView.image = UIImage(named: imageName)
}
}
}
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupViews() {
backgroundColor = .clear
addSubview(categoryLabel)
addSubview(imageView)
addSubview(nameLabel)
categoryLabel.frame = CGRect(x: 0, y: frame.width + 38, width: frame.width, height: 20)
imageView.frame = CGRect(x: 0, y: 0, width: frame.width, height: frame.width)
nameLabel.frame = CGRect(x: 0, y: frame.width + 2, width: frame.width, height: 40)
}
let imageView: UIImageView = {
let iv = UIImageView()
//iv.image = UIImage(named: "cat")
iv.contentMode = .scaleAspectFill
iv.translatesAutoresizingMaskIntoConstraints = false
iv.layer.cornerRadius = 16
iv.layer.masksToBounds = true
return iv
}()
let nameLabel: UILabel = {
let label = UILabel()
label.text = ""
label.font = UIFont.systemFont(ofSize: 14)
label.numberOfLines = 2
return label
}()
let categoryLabel: UILabel = {
let label = UILabel()
label.text = ""
label.font = UIFont.systemFont(ofSize: 13)
label.numberOfLines = 2
return label
}()
}
这是动物类别模型:
import UIKit
class AnimalCategory: NSObject {
var name: String?
var animals: [Animal]?
static func sampleAnimalCategories() -> [AnimalCategory] {
let catFamilyCategory = AnimalCategory()
catFamilyCategory.name = "Cat Family"
var catFamilyAnimals = [Animal]()
let catAnimal = Animal()
catAnimal.name = "Cat"
catAnimal.imageName = "cat"
catAnimal.category = "Lovely"
//catAnimal.dvcName = Cat.self()
catFamilyAnimals.append(catAnimal)
catFamilyCategory.animals = catFamilyAnimals
let dogFamilyCategory = AnimalCategory()
dogFamilyCategory.name = "Dog Family"
var dogFamilyAnimals = [Animal]()
let dogAnimal = Animal()
dogAnimal.name = "Dog"
dogAnimal.imageName = "dog"
dogAnimal.category = "Friendly"
//dogAnimal.dvcName = Dog.self
dogFamilyAnimals.append(dogAnimal)
dogFamilyCategory.animals = dogFamilyAnimals
return [catFamilyCategory, dogFamilyCategory]
}
}
struct Animal {
let name: String
let category: String
let imageName: String
let dvc: AnimalDetailController
}
struct AnimalCategory {
var name: String
private var _animals = [Animal]()
var animals: [Animal] {
get {
return self._animals
}
}
init(name: String) {
self.name = name
}
static var sampleAnimalCategories: [AnimalCategory] = {
var dogFamily = AnimalCategory(name: "Dog Family")
dogFamily.addAnimal(Animal(name: "Dog", category: "Friendly", imageName: "dog", dvc: DogDetailViewController()))
var catFamily = AnimalCategory(name: "Cat Family")
catFamily.addAnimal(Animal(name: "Cat", category: "Lovely", imageName: "cat", dvc: CatDetailViewController()))
let categories = [dogFamily,catFamily]
return categories
}()
mutating func addAnimal(_ animal: Animal) {
self._animals.append(animal)
}
}
这是动物模型:
import UIKit
class Animal: NSObject {
//var id: NSNumber?
var name: String?
var category: String?
var imageName: String?
//var dvc: AnimalDetailController?
}
这是动物细节控制器和样本cat.swift:
import UIKit
class AnimalDetailController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
var animal: Animal? {
didSet {
navigationItem.title = animal?.name
}
}
}
class Cat: AnimalDetailController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .brown
}
}
由于@Paulw11进行了一些更改后,下面是为每种动物显示特定细节视图控制器的代码:
func showAnimalDetailFor(_ animal: Animal) {
let layout = UICollectionViewFlowLayout()
var dvc = animal.dvc
dvc = AnimalDetailController(collectionViewLayout: layout)
self.show(dvc, sender: self)
}
以下是动物和动物类别模型:
import UIKit
class AnimalCategory: NSObject {
var name: String?
var animals: [Animal]?
static func sampleAnimalCategories() -> [AnimalCategory] {
let catFamilyCategory = AnimalCategory()
catFamilyCategory.name = "Cat Family"
var catFamilyAnimals = [Animal]()
let catAnimal = Animal()
catAnimal.name = "Cat"
catAnimal.imageName = "cat"
catAnimal.category = "Lovely"
//catAnimal.dvcName = Cat.self()
catFamilyAnimals.append(catAnimal)
catFamilyCategory.animals = catFamilyAnimals
let dogFamilyCategory = AnimalCategory()
dogFamilyCategory.name = "Dog Family"
var dogFamilyAnimals = [Animal]()
let dogAnimal = Animal()
dogAnimal.name = "Dog"
dogAnimal.imageName = "dog"
dogAnimal.category = "Friendly"
//dogAnimal.dvcName = Dog.self
dogFamilyAnimals.append(dogAnimal)
dogFamilyCategory.animals = dogFamilyAnimals
return [catFamilyCategory, dogFamilyCategory]
}
}
struct Animal {
let name: String
let category: String
let imageName: String
let dvc: AnimalDetailController
}
struct AnimalCategory {
var name: String
private var _animals = [Animal]()
var animals: [Animal] {
get {
return self._animals
}
}
init(name: String) {
self.name = name
}
static var sampleAnimalCategories: [AnimalCategory] = {
var dogFamily = AnimalCategory(name: "Dog Family")
dogFamily.addAnimal(Animal(name: "Dog", category: "Friendly", imageName: "dog", dvc: DogDetailViewController()))
var catFamily = AnimalCategory(name: "Cat Family")
catFamily.addAnimal(Animal(name: "Cat", category: "Lovely", imageName: "cat", dvc: CatDetailViewController()))
let categories = [dogFamily,catFamily]
return categories
}()
mutating func addAnimal(_ animal: Animal) {
self._animals.append(animal)
}
}
和动物详细信息控制器类:
class AnimalDetailController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
var animal: Animal? {
didSet {
navigationItem.title = animal?.name
}
}
}
我不会在视图控制器之间传输数据。我计划为牢房中的每只动物制作特定的swift文件,然后当你点击它们的图标时,我希望这些swift文件显示出来。当然,我正在使用导航控制器,并在app delegate中进行设置
请帮帮我。谢谢大家。一般来说,我会提醒大家不要将数据和代码紧密耦合,但您可以通过在数据模型中存储对view controller类的引用来实现自己的目的;在你的注释代码中,它几乎是正确的;您不需要在
self
之后使用()
如果不需要可变性,最好使用结构,这样您的Animal
和AnimalCategory
对象就可以是结构。您也可以避免所有这些选项
struct Animal {
let name: String
let category: String
let imageName: String
let dvc: AnimalDetailController.Type
}
struct AnimalCategory {
var name: String
private var _animals = [Animal]()
var animals: [Animal] {
get {
return self._animals
}
}
init(name: String) {
self.name = name
}
static var sampleAnimalCategories: [AnimalCategory] = {
var dogs = AnimalCategory(name: "Dog Family")
dogs.addAnimal(Animal(name: "Dog", category: "Friendly", imageName: "dog", dvc: DogDetailViewController.self))
var cats = AnimalCategory(name: "Cat Family")
cats.addAnimal(Animal(name: "Cat", category: "Lovely", imageName: "cat", dvc: CatDetailViewController.self))
let categories = [dogs,cats]
return categories
}()
mutating func addAnimal(_ animal: Animal) {
self._animals.append(animal)
}
}
然后,您的showAnimalDetailForAnimal
将类似于:
func showAnimalDetailFor(_ animal: Animal) {
let dvc = animal.dvc.init()
self.show(dvc, sender: self)
}
你也可以做很多关于你使用期权的清理工作。例如,animals
和animalCategories
都可以隐式展开选项
struct Animal {
let name: String
let category: String
let imageName: String
let dvc: AnimalDetailController.Type
}
struct AnimalCategory {
var name: String
private var _animals = [Animal]()
var animals: [Animal] {
get {
return self._animals
}
}
init(name: String) {
self.name = name
}
static var sampleAnimalCategories: [AnimalCategory] = {
var dogs = AnimalCategory(name: "Dog Family")
dogs.addAnimal(Animal(name: "Dog", category: "Friendly", imageName: "dog", dvc: DogDetailViewController.self))
var cats = AnimalCategory(name: "Cat Family")
cats.addAnimal(Animal(name: "Cat", category: "Lovely", imageName: "cat", dvc: CatDetailViewController.self))
let categories = [dogs,cats]
return categories
}()
mutating func addAnimal(_ animal: Animal) {
self._animals.append(animal)
}
}
您将无法使用
AnimalDetailViewController
子类UICollectionViewController
,因为您无法使用布局进行初始化。您需要将UIViewController
子类化,并将集合视图添加到viewdiload
为什么要为每种动物创建特定的类?一般来说,您会尽可能多地从数据中提取代码。。。例如,当我点击cat图像时,我希望看到一个包含5个单元格的集合视图;但若我点击狗的图像,我想看到3个单元格。在这些细胞中,数据将是不相关的。所以我想我不能从一个数据库中导航。这就是为什么ı选择为每种动物制作不同的swift文件。分类单元格是主页中不同的集合视图。长话短说,我要求代码算法在点击名为“Cat”的图像后查看Cat.swift(这是一个单独的集合视图),或者点击CATV的单元格,您可以在数据模型中存储对Cat.self
和Dog.self
的引用,然后在该属性上调用init()
,以获取视图控制器的实例,例如让catVC=Cat.self
然后让catVCInstance=catVC.init()
,但是,正如我所说,数据和代码之间的这种紧密耦合是很糟糕的,谢谢你,但是在完成了所有编写的工作之后,我也遇到了同样的问题。问题是,当我点击cat图像时,会显示AnimalDetailController,而不是CatDetailViewController(特定于cat的swift文件)。我在给AnimalDetailController键入背景色后意识到了这一点。在我的项目中,CatDVC和DogDVC是CollectionViewController,它们是AnimalDetailController的子类。但我还不能超越动物细节控制器。。。谢谢你的回答。如果有人想键入他们自己的解决方案,我还有以前的***版本作为备份编辑你的问题以显示你的showAnimalDetailFor
代码或任何你用来实例化和展示细节视图控制器的函数。你的showAnimalDetailFor
正在实例化AnimalDetailController
-我的代码不是这样做的。使用我的showAnimalDetailFor
我尝试了:func showAnimalDetailFor(animal:animal){let dvc=animal.dvc self.show(dvc,sender:self)}这是因为一开始我甚至无法启动它,但当我使用此代码启动时,它在点击一个图像后崩溃,因为我试图实例化一个集合视图,而我没有它的任何布局。这就是为什么我试图在ShowAnimalDetail中为函数设置布局