Creating a child view controller from a collection view - ios

I am trying to create a child view for my collection view, but whenever I run the app and select a cell from the collection view, nothing appears. How do I fix this so that the tableView is then displayed once a cell is selected?
Here is the code for my collectionView.
import UIKit
class ContentViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
let imageArray = [UIImage(named: "image 1"), UIImage(named: "image 2"), UIImage(named: "image 3")]
override func viewDidLoad() {
super.viewDidLoad()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return imageArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomCell", for: indexPath) as! CustomCell
cell.mapIconImage.image = imageArray[indexPath.row]
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let child = MapItemsViewController()
addChild(child)
view.addSubview(child.view)
child.didMove(toParent: self)
}
class CustomCell: UICollectionViewCell {
#IBOutlet weak var mapIconImage: UIImageView!
}

Related

The currencyLabel outlet from the ViewController to the UILabel is invalid. Outlets cannot be connected to repeating content

I inserted Label into CollectionView cell but when I made outlet this error appeared.
error: The currencyLabel outlet from the ViewController to the UILabel is invalid. Outlets cannot be connected to repeating content
class ViewController: UIViewController {
var currency = Currency.getCurrency()
#IBOutlet var currencyLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
extension ViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return currency.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "currencyCell", for: indexPath) as! CurrencyCollectionViewCell
let currencyList = currency[indexPath.row]
currencyLabel.text = "\(currencyList.currency) \n \(currencyList.cash)"
return cell
}
}
You need to create IBOutlet of your currencyLabel in CurrencyCollectionViewCell class, and use it like
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "currencyCell", for: indexPath) as! CurrencyCollectionViewCell
let currencyList = currency[indexPath.row]
cell.currencyLabel.text = "\(currencyList.currency) \n \(currencyList.cash)"
return cell
}
You have made a simple mistake.
You should make below outlet in CollectionViewCell not in your ViewController.
#IBOutlet var currencyLabel: UILabel!

How to set my UIButton tittle inside of uicollection view

so I want to set my button tittle like this with my array, but the result the button title didn't show my array
//viewcontroller
let menus = ["Topokki","Sundubu","Galbitang"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return menus.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionViewCell
cell.menusButton.titleLabel?.text = menus[indexPath.item]
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print(indexPath.item)
}
//collectionviewcell class
class CollectionViewCell: UICollectionViewCell {
#IBOutlet weak var menusButton: UIButton!
}
Try:
cell.menusButton.setTitle(menus[indexPath.item], forState: .normal)
From docs about titleLabel of UIButton
To set the actual text of the label, use setTitle(_:for:) (button.titleLabel.text does not let you set the text)
So... you need to set title of your button by calling setTitle(_:for:)
cell.menusButton.setTitle(menus[indexPath.item], for: .normal)

UICollectionViewCell not updating view after selection

Have an issue where:
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
is called when an item is selected, but I cannot change any cell properties from this method.
I created a new project with a stripped down UICollectionViewController to change the background color of a cell when selected. It also doesn't work. Here it is:
import UIKit
private let reuseIdentifier = "Cell"
class CollectionViewController: UICollectionViewController {
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
cell.backgroundColor = UIColor.blue
return cell
}
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = self.collectionView(self.collectionView, cellForItemAt: indexPath)
cell.backgroundColor = UIColor.green
}
}
The only thing I did in Storyboard is delete the standard View Controller and replace it with a UICollectionViewController, create a subclass of UICollectionViewController and set the controller in the storyboard as that class.
Also, I can confirm that the cell's index path is returned from this method when called from inside the didSelectItemAt method:
self.collectionView.indexPathsForSelectedItems
You are using the wrong API. Never call the delegate method collectionView(_ cellForItemAt:, use cellForItem(at:
if let cell = collectionView.cellForItem(at: indexPath) {
cell.backgroundColor = UIColor.green
}
But be aware that this change is not persistent. When the user scrolls the color will change back to blue.
You can achieve that as below,
ViewController
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ColoursViewCell", for: indexPath) as! ColoursViewCell
return cell
}
UICollectionViewCell
class ColoursViewCell: UICollectionViewCell {
#IBOutlet var photoImageView: UIImageView?
override var bounds: CGRect {
didSet {
self.layoutIfNeeded()
}
}
override var isSelected: Bool{
didSet{
if self.isSelected{
self.photoImageView?.backgroundColor = UIColor.random
}else{
self.photoImageView?.backgroundColor = UIColor.lightGray
}
}
}
}
you can have sample projects from this link I have in GitHub
https://github.com/hadanischal/RandomColors/tree/develop

Custom Layout UICollectionView

How do I set a horizontal orientation to a collection view in Swift? I need want the row layout to be like the picture below.
#IBOutlet weak var collectionView: UICollectionView!
let cellIdentifier = "cellViewID"
let objects = ["Cat", "Dog", "Fish"]
let images_array = ["break_down_grey", "break_down_grey", "Fish"]
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return objects.count;
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! CustomCollectionViewCell
cell.title.text=objects[indexPath.row]
cell.imageView.image = UIImage(named: images_array[indexPath.row])
print(cell)
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("Cell \(indexPath.row) selected")
}
import UIKit
class CustomCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var title: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
}

Why Collection Reusable View not shown?

I would like to create UICollectionView with header. I set Collection Reusable View on mainStoryBoard but, nothing is shown on device. I tried to search but could not find out why it is not appearing. I
Main Story Board
On device
import UIKit
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
#IBOutlet weak var collectionView: UICollectionView!
var images = ["medal1","medal2","medal3","medal4","medal5","medal6","medal7","medal8","medal9","medal10","medal1","medal2","medal3","medal14"]
var texts = ["hi","yes","hoo","such","hi","yes","hoo","such","hi","yes","hoo","such","hi","yes"]
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
}
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return images.count
}
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomCell", for: indexPath) as! CustomCell
cell.myImage.image = UIImage(named: images[indexPath.row])
cell.achievementLabel.text = texts[indexPath.row]
return cell
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
}
import UIKit
Class for collection View
class CustomCell: UICollectionViewCell {
#IBOutlet weak var myImage: UIImageView!
#IBOutlet weak var achievementLabel: UILabel!
}
class for Collection Reusable View
import UIKit
class CollectionReusableView: UICollectionReusableView {
#IBOutlet weak var reuseableVimage: UIImageView!
}
> import UIKit
class ViewController: UIViewController, UICollectionViewDelegate {
#IBOutlet weak var collectionView: UICollectionView!
var images = ["medal1","medal2","medal3","medal4","medal5","medal6","medal7","medal8","medal9","medal10","medal1","medal2","medal3","medal14"]
var texts = ["hi","yes","hoo","such","hi","yes","hoo","such","hi","yes","hoo","such","hi","yes"]
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
}
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
if kind == UICollectionElementKindSectionHeader {
let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "HeaderView", for: indexPath)
// do any programmatic customization, if any, here
return view
}
fatalError("Unexpected kind")
}
}
You have to implement viewForSupplementaryElementOfKind:
Implement collectionView(_:viewForSupplementaryElementOfKind:at:), for UICollectionElementKindSectionHeader or UICollectionElementKindSectionFooter, as appropriate.
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
if kind == UICollectionElementKindSectionHeader {
let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "CollectionReusableView", for: indexPath) as! CollectionReusableView
// do any programmatic customization, if any, here
return view
}
fatalError("Unexpected kind")
}
Make sure the header reusable view in IB has
the appropriate base class; and
the appropriate "reuse identifier"
In IB, make sure the collection view's "Accessories" have checkmarks next "Section Header" and "Section Footer", as appropriate.
Try to implement this. There's an example in RayWenderlich that could be useful for you: https://www.raywenderlich.com/136161/uicollectionview-tutorial-reusable-views-selection-reordering
override func collectionView(_ collectionView: UICollectionView,
viewForSupplementaryElementOfKind kind: String,
at indexPath: IndexPath) -> UICollectionReusableView {
switch kind {
case UICollectionElementKindSectionHeader:
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind,
withReuseIdentifier: "CollectionReusableView",
for: indexPath) as! CollectionReusableView
headerView.reuseableVimage ....
return headerView
default:
assert(false, "Unexpected element kind")
}
}

Resources