Selected UICollectionViewCell and performing a segue - swift

Wanting to store a users selected collection cell title as a local variable, so then it can be passed along to the next view using a segue. I'm having trouble with the didSelectItemAt function, even if I put a print statement there, nothing happens when a cell is selected.
GoalsViewController
import Foundation
import UIKit
class GoalsViewController: UIViewController {
#IBOutlet weak var collectionView: UICollectionView!
var selectedGoal: String = ""
var goalArray = ["Goal 1", "Goal 2"]
var imageArray = ["1", "2"]
override func viewDidLoad() {
super.viewDidLoad()
collectionView.dataSource = self
collectionView.delegate = self
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToGoalDetail" {
let secondVC = segue.destination as! GoalDetailViewController
secondVC.goalSelectedOnHome = selectedGoal
}
}
}
extension GoalsViewController: UICollectionViewDataSource, UICollectionViewDelegate {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return goalArray.count
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
selectedGoal = goalArray[indexPath.row]
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "GoalCell", for: indexPath) as! GoalsCollectionViewCell
cell.goalTitleLabel.text = goalArray[indexPath.row]
cell.backgroundColor = UIColor.darkGray
cell.featuredImageView.image = UIImage(named: "\(imageArray[indexPath.row])")
return cell
}
}
GoalsCollectionViewCell
import UIKit
class GoalsCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var featuredImageView: UIImageView!
#IBOutlet weak var goalTitleLabel: UILabel!
#IBOutlet weak var backgroundColorView: UIView!
}
GoalsDetailViewController
import UIKit
class GoalDetailViewController: UIViewController {
#IBOutlet weak var closeButtonImage: UIImageView!
#IBOutlet weak var goalDetailTitle: UILabel!
#IBOutlet weak var closeButton: UIButton!
var goalSelectedOnHome = ""
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
goalDetailTitle.text = goalSelectedOnHome
closeButton.setImage(UIImage(named: "closeIcon"), for: .normal)
closeButton.addTarget(self, action: #selector(closeButtonTapped), for: .touchUpInside)
}
#objc func closeButtonTapped(sender:UIButton!) {
self.dismiss(animated: true, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

Related

Cannot get CollectionViewCells to work in SWIFT

I have tried this numerous ways but I am unable to get it to work. I am trying to add a simple image and two text labels to a collection view cell and when the build completes the tableview is just blank. I am brand new too SWIFT but I am pretty sure I am missing something simple. What am I doing wrong?
ViewController
import UIKit
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate{
let locationName = ["Hawaii Resort", "Mountain Expedition", "Scuba Diving"]
let locationImage = [UIImage(named: "img0"), UIImage(named: "img1"), UIImage(named: "img2")]
let locationDescription = ["Lorem Ipsum 0", "Lorem Ipsum 1", "Lorem Ipsum 2"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return locationName.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
cell.locationName.text = locationName[indexPath.row]
cell.locationImage.image = locationImage[indexPath.row]
cell.locationDescription.text = locationDescription[indexPath.row]
return cell
}
}
CollectionViewCell
import UIKit
class CollectionViewCell: UICollectionViewCell {
#IBOutlet weak var locationImage: UIImageView!
#IBOutlet weak var locationName: UILabel!
#IBOutlet weak var locationDescription: UILabel!
}
You need to connect the collectionView to the ViewController.
Beneath locationDescription add:
#IBOutlet weak var collectionView: UICollectionView!
Then connect it on the storyboard.
Then within the viewDidLoad,set the delegate and data source to self
self.collectionView.delegate = self
self.collectionView.datasource = self

in the Table view I want to add some images but when I run it doesn't show and I already import the images in assets.xcassets

I already make an array to access the picture.. Can someone help? thanks
Here is my code:
import UIKit
class MainMenuViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
let labeltitle = ["Acme De la Vie Tee", "Anti Social Social Club Black Hoodie", "CDG Play Gold Black Tee"]
let labelprice = [("RM 240"), ("RM 305"), ("RM 418")]
let myImage = [UIImage(named: "adlv1"), UIImage(named: "assc"), UIImage(named: "cdg1")]
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return labeltitle.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MainMenuTableViewCell
cell.label11?.text = labeltitle[indexPath.row]
cell.label2?.text = labelprice[indexPath.row]
cell.myImage.image = self.myImage[indexPath.row]
return cell
}
}
Here is my code for MainMenuTableViewCell
import UIKit
class MainMenuTableViewCell: UITableViewCell {
#IBOutlet weak var label11: UILabel!
#IBOutlet weak var label3: UILabel!
#IBOutlet weak var label2: UILabel!
#IBOutlet weak var myImage: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
you need to register your tableviewcell in viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
tableView.register(MainMenuTableViewCell.self, forCellReuseIdentifier: "cell")
}
Apple Documentation
More Info
Did u add constraint ?
Select to viewController and do reset the suggested constraint and im sure it will be solved
cell.myImage.image = self.myImage[indexPath.row]
try to change your image Array name

I don't know what I have to do in order to make (2) work.. in swift

I want to make things like this.
(1). if I press one of that button(A) among 31. that number(A) turn red.
(2). then if I press another button(B) then (A) turn black again and then (B) turn red.
**
class ViewController: UICollectionViewController {
var collectionViewCell = CollectionViewCell()
let data = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]
override func viewDidLoad() {
super.viewDidLoad()
collectionView.register(UINib(nibName: "CollectionViewCell", bundle: nil), forCellWithReuseIdentifier : "MyCell")
}
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return data.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath) as! CollectionViewCell
cell.Label.text = String(data[indexPath.row])
return cell
}
}
class CollectionViewCell: UICollectionViewCell {
#IBOutlet weak var Label: UILabel!
#IBOutlet weak var button: UIButton!
#IBAction func buttonPressed(_ sender: UIButton) {
if Label.textColor == .red{
Label.textColor = .black
} else if Label.textColor == .black{
Label.textColor = .red
}
}
public override func awakeFromNib() {
super.awakeFromNib()
}
}
You have to use isSelected and func setSelected(_ selected: Bool, animated: Bool) {
But first you need to know that in Swift we use camelCase styling for variables.
Now we would have to change a little bit your cell implementation:
class CollectionViewCell: UICollectionViewCell {
#IBOutlet weak var label: UILabel!
#IBOutlet weak var button: UIButton!
public override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
if selected {
label.textColor = .red
} else {
label.textColor = .black
}
}
#IBAction func buttonPressed(_ sender: UIButton) {
self.isSelected = !self.isSelected
}
}
Also don't forget to update cell.Label.text = String(data[indexPath.row]) to cell.label.text = String(data[indexPath.row])
EDIT
As Leo Darbus pointed out it would be better to use isSelected.toggle() than self.isSelected = !self.isSelected, since it's already provided by system
You have to save the row number of the selected cell in the view controller.
Rather than modifying the color in the cell add a callback closure. In cellForRow handle the callback to set the current row to red and the previous row to black by reloading the row.
Something like this
class ViewController: UICollectionViewController {
var selectedRow : Int?
let data = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]
override func viewDidLoad() {
super.viewDidLoad()
collectionView.register(UINib(nibName: "CollectionViewCell", bundle: nil), forCellWithReuseIdentifier : "MyCell")
}
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return data.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath) as! CollectionViewCell
cell.Label.textColor = indexPath.item == selectedRow ? .red : .black
cell.callback = { [unowned self] in
if let row = self.selectedRow {
self.selectedRow = indexPath.item
collectionView.reloadItems(at: [IndexPath(item: row, section: 0)])
}
cell.Label.textColor = .red
}
cell.Label.text = String(data[indexPath.row])
return cell
}
}
class CollectionViewCell: UICollectionViewCell {
#IBOutlet weak var Label: UILabel!
#IBOutlet weak var button: UIButton!
var callback : (() -> Void)?
#IBAction func buttonPressed(_ sender: UIButton) {
callback?()
}
}

How to expand an xib collectionviewcell height dynamically?

I am looking to make my xib custom collection view cell height dynamic when clicked upon rather than using a fixed variable height.
I have tried using constraints on the heights of the cell in the storyboard.
This is the MotCollectionViewCell.swift code:
import UIKit
protocol ExpandedCellDelegate:NSObjectProtocol{
func topButtonTouched(indexPath:IndexPath)
}
class MotCollectionViewCell: UICollectionViewCell {
#IBOutlet var heightConstraint: NSLayoutConstraint!
#IBOutlet var topButton: UIButton!
weak var delegate:ExpandedCellDelegate?
public var indexPath:IndexPath!
#IBAction func topButtonTouched(_ sender: UIButton) {
if let delegate = self.delegate{
delegate.topButtonTouched(indexPath: indexPath)
}
}
#IBOutlet var testLbl: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
}
This is the BarChartViewControllerCell.Swift code :
import UIKit
import Charts
class BarChartViewController: UIViewController, ChartViewDelegate, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, ExpandedCellDelegate {
// Bar Chart Properties
#IBOutlet var barChartView: BarChartView!
var dataEntry: [BarChartDataEntry] = []
// Chart Data
var result = [String]()
var mileage = [String]()
var colours = [UIColor]()
var list = [Tester]()
// Collection View properties
#IBOutlet var collectionView: UICollectionView!
var expandedCellIdentifier = "MotCollectionViewCell"
var cellWidth:CGFloat{
return collectionView.frame.size.width
}
var expandedHeight : CGFloat = 258
var notExpandedHeight : CGFloat = 75
var dataSource = ["data0","data1","data2","data3","data4"]
var isExpanded = [Bool]()
override func viewDidLoad() {
super.viewDidLoad()
isExpanded = Array(repeating: false, count: dataSource.count)
//Register nib cell
let nibCell = UINib(nibName: expandedCellIdentifier, bundle: nil)
collectionView.register(nibCell, forCellWithReuseIdentifier: expandedCellIdentifier)
}
// Collection View functions
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return dataSource.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: expandedCellIdentifier, for: indexPath) as! MotCollectionViewCell
cell.indexPath = indexPath
cell.delegate = self
//configure Cell
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
if isExpanded[indexPath.row] == true{
return CGSize(width: cellWidth, height: expandedHeight)
}else{
return CGSize(width: cellWidth, height: notExpandedHeight)
}
}
func topButtonTouched(indexPath: IndexPath) {
isExpanded[indexPath.row] = !isExpanded[indexPath.row]
UIView.animate(withDuration: 0.8, delay: 0.0, usingSpringWithDamping: 0.9, initialSpringVelocity: 0.9, options: UIView.AnimationOptions.curveEaseInOut, animations: {
self.collectionView.reloadItems(at: [indexPath])
}, completion: { success in
print("success")
})
}
}
When the cell is clicked, the cell expands to the height which I declared as a constant, what I am trying to achieve is have the cell expand according to the data within it.

How to properly implement NSCollectionView in swift4?

can you check what's wrong with my codes? I can successfully run the application but with empty content. Thanks!
import Cocoa
class MainViewController: NSViewController {
#IBOutlet weak var scrollView: NSScrollView!
#IBOutlet weak var collectionView: NSCollectionView!
override func viewDidLoad() {
super.viewDidLoad()
// Do view setup here.
self.initView()
self.initCollectionView()
}
func initView() {
let nib = NSNib(nibNamed: NSNib.Name(rawValue: "NavCollectionViewCell"), bundle: nil)
//ßßself.collectionView.register(nib, forItemWithIdentifier: NSUserInterfaceItemIdentifier(rawValue: "NavCollectionViewCell"))
self.collectionView.register(nib, forItemWithIdentifier: .collectionViewItem)
}
func initCollectionView() {
self.collectionView.delegate = self
self.collectionView.dataSource = self
}
}
extension MainViewController: NSCollectionViewDelegate, NSCollectionViewDataSource {
func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
return 3
}
func numberOfSections(in collectionView: NSCollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
// 4
let item = collectionView.makeItem(withIdentifier: .collectionViewItem, for: indexPath)
return item
}
}
extension NSUserInterfaceItemIdentifier {
static let collectionViewItem = NSUserInterfaceItemIdentifier("NavCollectionViewCell")
}