UICollectionView not loading on screen - ios

I am trying to create a UICollectionView and its not loading on the screen. In my app delegate I even made it the entry screen and it does not appear just a black screen.
class ChatRoom: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UICollectionViewDataSource, UICollectionViewDelegate {
// Struct of Objects
struct Object {
var image: UIImage!
var title: String!
}
// Properties
var object: Object?
var objects: [Object] = []
var picker: UIImagePickerController!
var ref: FIRDatabaseReference?
#IBOutlet weak var collectionView2: UICollectionView!
// Instance of a class
var secondClass : ChatCell?
// Do any additional setup after loading the view, typically from a nib.
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewDidLoad() {
super.viewDidLoad()
// Firebase Data
ref = FIRDatabase.database().reference()
// CollectionView
collectionView2?.delegate = self
collectionView2?.dataSource = self
collectionView2?.reloadData()
// User Logged In
checkIfUserLoggedIn()
picker = UIImagePickerController()
picker?.allowsEditing = false
picker?.delegate = self
picker?.sourceType = .photoLibrary
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! ChatCell
let object = objects[indexPath.row]
cell.chatLabel.text = object.title ?? ""
cell.chatImage.image = object.image ?? UIImage()
cell.layer.borderWidth = 2
cell.layer.borderColor = UIColor.white.cgColor
cell.layer.masksToBounds = true
cell.layer.cornerRadius = 6
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return objects.count
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let itemWidth = collectionView2.bounds.width
let itemHeight = collectionView2.bounds.height
return CGSize(width: itemWidth, height: itemHeight)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
switch info[UIImagePickerControllerOriginalImage] as? UIImage {
case let .some(image):
object?.image = image
default:
break
}
picker.dismiss(animated: true) {
self.showCellTitleAlert()
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
object = nil
dismiss(animated: true) {
self.collectionView2!.reloadData()
}
}
// Alerts
func showCellTitleAlert() {
let alert = UIAlertController(title: "Cell Title", message: nil, preferredStyle: .alert)
alert.addTextField { $0.placeholder = "Enter only 10 characters" }
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in
self.object = nil
})
alert.addAction(UIAlertAction(title: "Save", style: .default) { _ in
self.object?.title = (alert.textFields?.first.flatMap { $0.text })!
self.object.flatMap { self.objects.append($0) }
self.collectionView2?.reloadData()
})
present(alert, animated: true, completion: nil)
}
// Create new Cell
#IBAction func didSelectCreateButton() {
object = Object()
present(picker, animated: true, completion: nil)
}

Here the collectionView appears blank because you are not filling the objects array which is the dataSource for the collectionView2.

Related

How do I categorize a selected image from iOS library using the Xcode picker? (is there a way to add custom parameters to the picker function?)

I'm working on a closet-organizing iOS app. The user can click on a menu, which will give them a set of options as to what type of item they want to upload a photo of. For example if they click on the "tops" menu option, the program should be able to upload a photo and put it in a "tops" folder. (I've labeled where it should be changed below) Everything is running fine so far, but I'm having trouble passing through the upload type to the picker function, so everything just gets put into one folder. Is there a way to customize the picker function so that I can include an extra parameter (the category type)?
Here's the code so far:
//
// ViewController.swift
//
import UIKit
import PhotosUI
import Photos
import CoreData
import Foundation
import SwiftUI
// user images below
var imageIDs = [String]()
var countImage = 0
class ViewController: UIViewController, PHPickerViewControllerDelegate {
// when trash is pressed in ClosetDetailViewController, return to ViewController
#IBAction func unwindToCloset(segue: UIStoryboardSegue) {
}
#IBOutlet var collectionView: UICollectionView!
// CLOSET FOLDER NAME: "closet_folder"
override func viewDidLoad() {
super.viewDidLoad()
// popup menu items
let tops = UIAction(title: "tops") { (action) in
print("tops!")
self.addPhotos(categoryType: "tops")
}
let outerwear = UIAction(title: "outerwear") { (action) in
print("outerwear!")
self.addPhotos(categoryType: "outerwear")
}
let bottoms = UIAction(title: "bottoms") { (action) in
print("bottoms!")
self.addPhotos(categoryType: "bottoms")
}
let singles = UIAction(title: "one pieces") { (action) in
print("singles!")
self.addPhotos(categoryType: "singles")
}
let accessories = UIAction(title: "accessories") { (action) in
print("accessories!")
self.addPhotos(categoryType: "accessories")
}
let shoes = UIAction(title: "shoes") { (action) in
print("shoes!")
self.addPhotos(categoryType: "shoes")
}
let menu = UIMenu(title: "my closet", options: .displayInline,
children: [tops , outerwear , bottoms, singles, shoes, accessories])
// set up collection in closet
// navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addPhotos))
navigationItem.rightBarButtonItems = [UIBarButtonItem(systemItem: .add, menu: menu)]
collectionView.register(ClosetCollectionViewCell.nib(), forCellWithReuseIdentifier: "ClosetCollectionViewCell")
collectionView.delegate = self
collectionView.dataSource = self
let layout = UICollectionViewFlowLayout()
layout.itemSize = CGSize(width: 75, height: 100)
collectionView.collectionViewLayout = layout
// layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 15
collectionView.reloadData()
}
// access photo library
#objc private func addPhotos(categoryType: String) {
var config = PHPickerConfiguration()
config.selectionLimit = 10
config.filter = .images
let vc = PHPickerViewController(configuration: config)
vc.delegate = self
present(vc, animated: true)
}
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true, completion: nil)
let group = DispatchGroup()
results.forEach { result in
group.enter()
result.itemProvider.loadObject(ofClass: UIImage.self) { reading, error in
defer {
group.leave()
}
guard let image = reading as? UIImage, error == nil else {
return
}
countImage += 1
print(countImage)
imageIDs.append(String(countImage))
print(imageIDs)
// FOLDER NAME SHOULD BE CHANGED HERE BASED ON CATEGORY TYPE
LocalFileManager.instance.saveImage(image: image, imageName: String(countImage), folderName: "closet_folder")
}
}
group.notify(queue: .main) {
self.collectionView.reloadData()
}
}
}
extension ViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
collectionView.deselectItem(at: indexPath, animated: true)
print("you tapped me!")
// set closetImageName in ClosetDetailViewController
detailImageName = imageIDs[indexPath.row]
print(imageIDs[indexPath.row])
performSegue(withIdentifier: "closetDetail", sender: nil)
}
}
extension ViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// how many cells are shown? based on number of items the user uploaded
return countImage
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// return cell for given item
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ClosetCollectionViewCell", for: indexPath) as! ClosetCollectionViewCell
// show every cell in image array
cell.imageView.image = LocalFileManager.instance.getImage(imageName: imageIDs[indexPath.row], folderName: "closet_folder")
return cell
}
}
extension ViewController: UICollectionViewDelegateFlowLayout {
// margin of padding between cells
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 75, height: 100)
}
}
Thanks all!

Collection view Cells redirecting different ViewController

I Have UICollectionView with Sections. Each Sections have variable cells which is defined by array count. I have declared array of strings for each section in viewDidLoad function.
I want each cell to open a New UIViewController on click of respective cell. How do i get the above result.
I am using Swift3 for coding.
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
#IBOutlet weak var collectView: UICollectionView!
var sectionHeader = [String] ()
var sectionArr = [Any] ()
var enquire = [String] ()
var serviceRequest = [String] ()
var missedCall = [String] ()
var settings = [String] ()
var arr = [String] ()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
sectionHeader = ["Enquire","Service Request","Missed Call Recharge","Settings"]
enquire = ["Balance Enquiry","Mini Statement","Account Statement","Cheque Status Enquiry","Fixed Deposit Enquiry"]
serviceRequest = ["Stop Cheque Payment","Cheque Book Request","iPIN Regeneration"]
missedCall = ["Activate","Deactivate","Set Recharge Amount","Recharge"]
settings = ["Change Primary Account","Register"]
sectionArr = [enquire,serviceRequest,missedCall,settings]
collectView.dataSource = self
collectView.delegate = self
collectView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func loadCollectionView(_ sender: Any) {
collectView.reloadData()
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return sectionArr.count
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if (section == 0) {
return enquire.count
}
else if (section == 1) {
return serviceRequest.count
}
else if (section == 2) {
return missedCall.count
}
else {
return self.settings.count
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let mycell:CustomCell = collectView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath) as! CustomCell
arr = sectionArr[indexPath.section] as! [String]
let imagename = arr[indexPath.row]
let modified = imagename.replacingOccurrences(of: " ", with: "_")
let modified_imagename = modified + ".png"
mycell.functionalityImage.image = UIImage(named : modified_imagename)
mycell.functionalityName.text = arr[indexPath.row]
return mycell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
arr = sectionArr[indexPath.section] as! [String]
showAlert(mesgTitle: "SELECTED CELL", mesgText: arr[indexPath.row])
}
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
var reusea:UICollectionReusableView? = nil
if (kind == UICollectionElementKindSectionHeader) {
let header:HeaderTextHome = collectView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "Header_Text", for: indexPath) as! HeaderTextHome
header.headerText.text = sectionHeader[indexPath.section ]
reusea = header
}
return reusea!
}
func showAlert(mesgTitle : String, mesgText : String) {
let alertController = UIAlertController(title: mesgTitle, message: mesgText, preferredStyle: UIAlertControllerStyle.alert)
let defaultAction = UIAlertAction(title: "Okay", style: UIAlertActionStyle.default, handler: nil)
let cancleAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: nil)
alertController.addAction(defaultAction)
alertController.addAction(cancleAction)
present(alertController, animated: true, completion: nil)
}
}
Above code i display an alert on click.
If I understood your question correctly, then one way of doing this would be to set the identifier for each UIViewController in your storyboard and then calling this in your didSelectItemAt:
let vc = self.storyboard?.instantiateViewController(withIdentifier: sectionArr[indexPath.section]) as! UIViewController
self.present(vc, animated: true, completion: nil)
If you are using segue then Set up All viewController segue in storyboard then use bellow code.
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
arr = sectionArr[indexPath.section] as! [String]
let viewControllerIdentifire = arr[indexPath.item]
self.performSegue(withIdentifier: viewControllerIdentifire, sender: IfYouWantToPassDataThanPutHereElseNil)
// showAlert(mesgTitle: "SELECTED CELL", mesgText: arr[indexPath.row])
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "Enquire" {
let vc = segue.destinationViewController as! EnquireViewController
vc.data = sender // if you want to pass data to viewCotroller
}
}

I am getting this error, this class is not key value coding-compliant for the key collectionView.' , [duplicate]

This question already has answers here:
Xcode - How to fix 'NSUnknownKeyException', reason: … this class is not key value coding-compliant for the key X" error?
(79 answers)
Closed 5 years ago.
I have a UIViewController, and embedded I have a UICollectionView, I also have a sub class called ChatCell
ChatCell Subclass:
class ChatCell: UICollectionViewCell {
#IBOutlet weak var chatLabel: UILabel!
#IBOutlet weak var chatImage: UIImageView!
}
class ChatRoom: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UICollectionViewDataSource, UICollectionViewDelegate {
#IBOutlet weak var collectionView2: UICollectionView!
// My error was ^ I changed the name and I did not update the outlet in the storyboard! Make sure you have the correct outlets, or they will not be recognized by xcode.
var secondClass : ChatCell?
struct Object {
var image: UIImage!
var title: String!
}
// Properties
var object: Object?
var objects: [Object] = []
var picker: UIImagePickerController!
// Do any additional setup after loading the view, typically from a nib.
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewDidLoad() {
super.viewDidLoad()
picker = UIImagePickerController()
picker?.allowsEditing = false
picker?.delegate = self
picker?.sourceType = .photoLibrary
// NavigationBar Characteristics
}
override func viewDidAppear(_ animated: Bool) {
self.navigationController?.isNavigationBarHidden = false
self.navigationController?.navigationBar.barTintColor = UIColor.black
self.navigationController?.navigationBar.isTranslucent = false
// self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Logout", style: .plain, target: self, action: #selector(handleLogout))
self.navigationItem.leftBarButtonItem?.tintColor = UIColor.green
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "+", style: .plain, target: self, action: #selector(didSelectCreateButton))
self.navigationItem.rightBarButtonItem?.tintColor = UIColor.green
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as UICollectionViewCell
let object = objects[indexPath.row]
secondClass?.chatLabel.text = object.title ?? ""
secondClass?.chatImage.image = object.image ?? UIImage()
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return objects.count
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
switch info[UIImagePickerControllerOriginalImage] as? UIImage {
case let .some(image):
object?.image = image
default:
break
}
picker.dismiss(animated: true) {
self.showCellTitleAlert()
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
object = nil
dismiss(animated: true) {
self.collectionView2!.reloadData()
}
}
// Alerts
func showCellTitleAlert() {
let alert = UIAlertController(title: "Cell Title", message: nil, preferredStyle: .alert)
alert.addTextField { $0.placeholder = "Title" }
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in
self.object = nil
})
alert.addAction(UIAlertAction(title: "Save", style: .default) { _ in
self.object?.title = (alert.textFields?.first.flatMap { $0.text })!
self.object.flatMap { self.objects.append($0) }
self.collectionView2?.reloadData()
})
present(alert, animated: true, completion: nil)
}
// Create new Cell
////////?//////////////
#IBAction func didSelectCreateButton() {
object = Object()
present(picker, animated: true, completion: nil)
}
}
In your storyboard (or xib) you have specified a connection to an outlet called collectionView but in your code you call it collectionView2.
Delete the bad connection and re-do it to point to your current variable name.

Nothing is appearing in the iOS simulator when I tried to allow users to create their own uicollectionviewcell

My code is building perfectly and I am trying to use the simulator but nothing is appearing but a blank white screen. I am trying to allow the user to create their own uicollectionviewcell with a title and an image. I have a ChatRoom View controller that has the initial entry point it also has a navigation controller segue connected as the root view controller. I also have a subclass ChatCell for the UicollectionViewcell. How can I fix this ? Here is my github of the project: https://github.com/fboch25/CollectionView2
//Subclass
class ChatCell: UICollectionViewCell {
#IBOutlet weak var chatLabel: UILabel!
#IBOutlet weak var chatImage: UIImageView!
}
// Original View Controller
class ChatRoom: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UICollectionViewDataSource, UICollectionViewDelegate {
#IBOutlet weak var collectionView2: UICollectionView!
var secondClass : ChatCell?
struct Object {
var image: UIImage!
var title: String!
}
// Properties
var object: Object?
var objects: [Object] = []
var picker: UIImagePickerController!
// Do any additional setup after loading the view, typically from a nib.
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewDidLoad() {
super.viewDidLoad()
picker = UIImagePickerController()
picker?.allowsEditing = false
picker?.delegate = self
picker?.sourceType = .photoLibrary
// NavigationBar Characteristics
}
override func viewDidAppear(_ animated: Bool) {
self.navigationController?.isNavigationBarHidden = false
self.navigationController?.navigationBar.barTintColor = UIColor.black
self.navigationController?.navigationBar.isTranslucent = false
// self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Logout", style: .plain, target: self, action: #selector(handleLogout))
self.navigationItem.leftBarButtonItem?.tintColor = UIColor.green
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "+", style: .plain, target: self, action: #selector(didSelectCreateButton))
self.navigationItem.rightBarButtonItem?.tintColor = UIColor.green
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as UICollectionViewCell
let object = objects[indexPath.row]
secondClass?.chatLabel.text = object.title ?? ""
secondClass?.chatImage.image = object.image ?? UIImage()
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return objects.count
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
switch info[UIImagePickerControllerOriginalImage] as? UIImage {
case let .some(image):
object?.image = image
default:
break
}
picker.dismiss(animated: true) {
self.showCellTitleAlert()
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
object = nil
dismiss(animated: true) {
self.collectionView2!.reloadData()
}
}
// Alerts
func showCellTitleAlert() {
let alert = UIAlertController(title: "Cell Title", message: nil, preferredStyle: .alert)
alert.addTextField { $0.placeholder = "Title" }
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in
self.object = nil
})
alert.addAction(UIAlertAction(title: "Save", style: .default) { _ in
self.object?.title = (alert.textFields?.first.flatMap { $0.text })!
self.object.flatMap { self.objects.append($0) }
self.collectionView2?.reloadData()
})
present(alert, animated: true, completion: nil)
}
// Create new Cell
////////?//////////////
#IBAction func didSelectCreateButton() {
object = Object()
present(picker, animated: true, completion: nil)
}
}
In your viewDidLoad add these two lines
collectionView2.delegate = self
collectionView2.dataSource = self
For your particular project I would make two changes. One change the button in the top right corners text to white so you can see it. Two change this method and you will start seeing your cells. Cannot believe I did not notice in the code above..
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! ChatCell
let object = objects[indexPath.row]
cell.chatLabel.text = object.title ?? ""
cell.chatImage.image = object.image ?? UIImage()
return cell
}

UICollectionView Functionality issues

I have a UICollectionViewCell on VC1, The cell contains, a image, a label, and 3 buttons.
When i click on the cell. That triggers my didSelectItemAtIndexPath to take me to an Edit item screen.
How can i access each button and relate it to the cell i am clicking on?
So if i have added 6 cells, and i click on cell 1, button 1, it takes me to a bio page with info on that person. if i click on cell 2 button 1, it brings me to same bio VC but with different info related to the cell i clicked on.
My confusion lies in where or how to set this up?
Thank you!
import UIKit
import Parse
class TrainersViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, AddNewTrainerViewControllerDelegate {
var trainers: [TrainerArray]
required init?(coder aDecoder: NSCoder) {
trainers = [TrainerArray]()
super.init(coder: aDecoder)
loadTrainerItems()
}
//connection to the collection view
#IBOutlet weak var collectionView: UICollectionView!
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
print("selected")
saveTrainerItems()
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return trainers.count
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("TrainerCell", forIndexPath: indexPath)
var buttonOne = cell.viewWithTag(10)
buttonOne = indexPath.row
let trainer = trainers[indexPath.row]
configureTrainerForCell(cell, withTrainerArray: trainer)
return cell
}
func configureTrainerForCell(cell: UICollectionViewCell, withTrainerArray trainer: TrainerArray) {
if trainer.trainerImage == nil {
let label = cell.viewWithTag(1000) as! UILabel
trainer.trainerImage = UIImage(named: "defaultImage")
label.text = trainer.name
} else {
let image = cell.viewWithTag(2000) as! UIImageView
image.image = trainer.trainerImage
let label = cell.viewWithTag(1000) as! UILabel
label.text = trainer.name
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//This method adds a new trainer to the trainer array
func addNewTrainerViewController(controller: AddNewTrainerViewController, didFinishAddingItem item: TrainerArray) {
let newRowIndex = trainers.count
trainers.append(item)
let indexPath = NSIndexPath(forRow: newRowIndex, inSection: 0)
let indexPaths = [indexPath]
collectionView.insertItemsAtIndexPaths(indexPaths)
dismissViewControllerAnimated(true, completion: nil)
saveTrainerItems()
}
func addNewTrainerViewController(controller: AddNewTrainerViewController, didFinishDeletingItem item: TrainerArray) {
if let index = trainers.indexOf(item) {
let indexPath = NSIndexPath(forRow: index, inSection: 0)
let indexPaths = [indexPath]
if let _ = collectionView.cellForItemAtIndexPath(indexPath) {
self.trainers.removeAtIndex(index)
self.collectionView.deleteItemsAtIndexPaths(indexPaths)
}
}
dismissViewControllerAnimated(true, completion: nil)
saveTrainerItems()
}
//This Method Edits a Trainer
func addNewTrainerViewController(controller: AddNewTrainerViewController, didFinishEditingItem trainer: TrainerArray) {
if let index = trainers.indexOf(trainer) {
let indexPath = NSIndexPath(forRow: index, inSection: 0)
if let cell = collectionView.cellForItemAtIndexPath(indexPath){
configureTrainerForCell(cell, withTrainerArray: trainer)
}
}
saveTrainerItems()
dismissViewControllerAnimated(true, completion: nil)
}
func addNewTrainerViewControllerDidCancel(controller: AddNewTrainerViewController) {
dismissViewControllerAnimated(true, completion: nil)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "AddTrainer" {
let navigationController = segue.destinationViewController as! UINavigationController
let controller = navigationController.topViewController as! AddNewTrainerViewController
controller.delegate = self
} else if segue.identifier == "EditTrainer" {
let navigationController = segue.destinationViewController as! UINavigationController
let controller = navigationController.topViewController as! AddNewTrainerViewController
controller.delegate = self
if let indexPath = collectionView.indexPathForCell(sender as! UICollectionViewCell) {
controller.trainerToEdit = trainers[indexPath.row]
}
}
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
}
func documentsDirectory() -> String {
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
return paths[0]
}
func dataFilePath() -> String {
return (documentsDirectory() as NSString)
.stringByAppendingPathComponent("Trainers.plist")
}
func saveTrainerItems() {
let data = NSMutableData()
let archiver = NSKeyedArchiver(forWritingWithMutableData: data)
archiver.encodeObject(trainers, forKey: "TrainersArray")
archiver.finishEncoding()
data.writeToFile(dataFilePath(), atomically: true)
}
func loadTrainerItems() {
let path = dataFilePath()
if NSFileManager.defaultManager().fileExistsAtPath(path) {
if let data = NSData(contentsOfFile: path) {
let unarchiver = NSKeyedUnarchiver(forReadingWithData: data)
trainers = unarchiver.decodeObjectForKey("TrainersArray") as! [TrainerArray]
unarchiver.finishDecoding()
}
}
}
#IBAction func logOut(sender: AnyObject) {
let alert = UIAlertController(title: "Are You Sure You Want To Log Out?", message: "Please Enter Your Username", preferredStyle: UIAlertControllerStyle.Alert)
alert.addTextFieldWithConfigurationHandler { (textField) -> Void in
}
alert.addAction(UIAlertAction(title: "Log Out", style: UIAlertActionStyle.Default, handler: { (action) -> Void in
let textF = alert.textFields![0] as UITextField
if textF.text! != PFUser.currentUser()?.username {
self.displayGenericAlert("Incorrect Username!", message: "Please Enter a Valid Username")
} else if textF.text! == PFUser.currentUser()?.username {
PFUser.logOut()
_ = PFUser.currentUser()
self.dismissViewControllerAnimated(true, completion: nil)
}
}))
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Default, handler: { (action) -> Void in
if action == true {
self.dismissViewControllerAnimated(false, completion: nil)
}}))
self.presentViewController(alert, animated: true, completion: nil)
}
func displayGenericAlert(title: String, message: String) {
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Ok", style: .Default, handler: { (action) -> Void in
}))
self.presentViewController(alert, animated: true, completion: nil)
}
#IBAction func bioSegueButton(sender: AnyObject) {
}
}
You can get data from your array from index 'indexpath.row' .
You can add a tag to the button that corresponds to the index of the cell it is in. In the cellForItemAtIndexPath you would add something like...
button.tag = indexPath.row
And in the selector for the button you can access it...
func buttonSelector(sender: UIButton) {
let index = sender.tag
let trainer = trainers[index]
}
EDIT:
A more complete version of what you might do in cellForRowAtIndexPath:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("TrainerCell", forIndexPath: indexPath) as? MyCollectionViewCell
var buttonOne = cell?.button1
buttonOne?.tag = indexPath.row
let trainer = trainers[indexPath.row]
configureTrainerForCell(cell, withTrainerArray: trainer)
return cell!
}
Your collection view cell class:
class MyCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var button1: UIButton! // connect this to the button in your interface builder's collection view cell.
// Do the same for any other subviews.
}
Also in interface builder change the class of the collection view cell prototype to this new custom class.

Resources