func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return interests.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt cellForItemAtindexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(Storyboard.CellIdentifier, forIndexPath:indexPath) as! InterestCollectionViewCell
cell.interest = self.interest[indexPath.item]
return cell
}
Correct your method signature as
Swift
func collectionView(_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
Objective c
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;
documentation
Change to this:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(Storyboard.CellIdentifier, forIndexPath:indexPath) as! InterestCollectionViewCell
cell.interest = self.interest[indexPath.item]
return cell
}
UPDATE
And if this is the UICollectionView function you also needs to add the override keyword before func
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(Storyboard.CellIdentifier, forIndexPath:indexPath) as! InterestCollectionViewCell
cell.interest = self.interest[indexPath.item]
return cell
}
extension ViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return interests.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Storyboard.cellIdentifier, for: indexPath) as! InterestCollectionViewCell
cell.interest = interests[(indexPath as NSIndexPath).item]
return cell
}
}
//MARK:- extension of collection view
extension CreateTapUpFirstVC : UICollectionViewDelegate, UICollectionViewDataSource , UICollectionViewDelegateFlowLayout{
// MARK: - Collection View delegate & datasource
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return arrCategory.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TappUpCell", for: indexPath as IndexPath) as! TappUpCell
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath){
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
let bounds = UIScreen.main.bounds
let height = bounds.size.height
if(height == 736) {
// return UIEdgeInsetsMake(top, left, bottom, right);
return UIEdgeInsetsMake(20, 40, 20, 40)
} else if(height == 667){
return UIEdgeInsetsMake(20, 40, 20, 40)
} else if(height == 568) {
return UIEdgeInsetsMake(20, 20, 10, 20)
} else if(height == 480) {
return UIEdgeInsetsMake(20, 20, 10, 20)
} else {
return UIEdgeInsetsMake(20, 40, 20, 40)
}
}
func collectionView(_ collectionView: UICollectionView,layout collectionViewLayout: UICollectionViewLayout,minimumLineSpacingForSectionAt section: Int) -> CGFloat {
let bounds = UIScreen.main.bounds
// let width = bounds.size.width
let height = bounds.size.height
if(height == 736) {
return 10//20
} else if(height == 667){
return 5//15
} else {
return 5//10
}
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 100.0, height: 100.0);
}
}
Related
I have a UICollectionView with a horizontal scroll that shows 3 cells for each page but when I get to the last page there is only one element and it does not let me scroll to show this last element.
This is my list:
var benefitIcons = ["ic_benefit_frappe", "ic_benefit_birthday", "ic_benefit_2x1", "ic_benefit_points", "ic_benefit_combo", "ic_benefit_cine", "ic_benefit_tickets", "ic_benefit_refill", "ic_benefit_klic", "ic_benefit_pay"]
This is the method for UICollectionView:
extension ProfileCCViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return benefitIcons.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell = benefitCollection.dequeueReusableCell(withReuseIdentifier: "BenefitCell", for: indexPath) as? UserBenefitsCell {
cell.benefitIcon.image = UIImage(named: benefitIcons[indexPath.row])
cell.benefitLbl.text = benefitDescriptions[indexPath.row]
return cell
} else {
return UICollectionViewCell()
}
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.bounds.width/3, height: collectionView.bounds.height)
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
benefitControl.currentPage = indexPath.row
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let offSet = scrollView.contentOffset.x
let width = scrollView.frame.width
let horizontalCenter = width / 2
benefitControl.currentPage = Int(offSet + horizontalCenter) / Int(width)
}
}
This how look like correctly:
But when I'm scrolling to the last item and is uneven doesn't scroll to this last section:
Have an issue with collection view cell.
i've got a collection view (vertical scroll) with 2 sections (1st is ServiceCell and the 2nd is OfferCell as ). First section is with 1 item - another collection view that is set in class ServiceCell: UIcollectionViewCell {} (horizontal scroll) with multiply subcells (ServiceSubCell).
i can't understand where i have to implement didselect method for subcells
main view conroller looks like this:
extension HomeScreenViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func numberOfSections(in collectionView: UICollectionView) -> Int {
2
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if section == 0 {
return 1
}
return offers.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if indexPath.section == 0 {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ServiceCell.reuseId, for: indexPath) as! ServiceCell
return cell
}
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: OfferCellSubCell.reuseId, for: indexPath) as! OfferCellSubCell
cell.backgroundColor = .white.withAlphaComponent(0.6)
cell.layer.cornerRadius = 20
cell.setup(with: offers[indexPath.row])
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if indexPath.section == 0 {
// this part doesn't work
let serviceVC = ServiceScreenViewController() as ServiceScreenViewController
serviceVC.category = servicesCategoriesArray[indexPath.row]
self.navigationController?.pushViewController(serviceVC, animated: true)
} else {
let offerVC = OfferScreenViewController() as OfferScreenViewController
offerVC.offerNew = offers[indexPath.row]
self.navigationController?.pushViewController(offerVC, animated: true)
}
}
}
Service cell with extension
class ServiceCell: UICollectionViewCell, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return servicesCategoriesArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ServiceCellSubCell.reuseId, for: indexPath) as! ServiceCellSubCell
cell.setup(with: servicesCategoriesArray[indexPath.row])
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 140, height: 140)
}
}
You should implement "didSelect" in ServiceCell
and you should implement in your ViewController "should highlight" for first section to "false"
func collectionView(_ collectionView: UICollectionView,
shouldHighlightItemAt indexPath: IndexPath) -> Bool {
return yourServiceSection ? false : true
}
the below code must be in ServiceCell and ViewController
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
collectionview.deselectItem(at: indexPath, animated: true)
}
in your "ServiceCell" you must add this extension:
import Foundation
import UIKit
extension ServiceCell: UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return viewModel.list.count ?? 0
}
func collectionView(_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier:
ServiceSubCell.nameOfClass,
for: indexPath) as? ServiceSubCell
if let item = viewModel.data?.item(at: indexPath.item) {
cell?.config(item: item)
}
return cell ?? UICollectionViewCell()
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: SizeConstant.ServiceSubCellWidth.rawValue,
height: SizeConstant.ServiceSubCellHeight.rawValue)
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
collectionview.deselectItem(at: indexPath, animated: true)
// implement your code you need
}
}
we are using UICollectionView for displaying some data's. My problem is when scrolling cell horizontal cell's are cutting down . How to fix it?
Here is my tried code:
func numberOfSections(in collectionView: UICollectionView) -> Int
{
return 1
}
func collectionView(_ collectionView: UICollectionView,layout collectionViewLayout: UICollectionViewLayout,minimumInteritemSpacingForSectionAt section: Int) -> CGFloat
{
return 1.0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,minimumLineSpacingForSectionAt section: Int) -> CGFloat
{
return 1.0
}
func collectionView(_ collectionView : UICollectionView,layout collectionViewLayout:UICollectionViewLayout,sizeForItemAt indexPath:IndexPath) -> CGSize
{
let width = UIScreen.main.bounds.width
return CGSize(width: width,height: collectionView.frame.size.height)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets
{
return UIEdgeInsetsMake(0, 0, 0, 0)
// top, left, bottom, right
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return 5
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let ViewSize = UIScreen.main.bounds.width
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomCell", for: indexPath as IndexPath) as! CSDashboardCustomCell
cell.MainView.frame = CGRect(x: 10, y: 10, width: ViewSize - 40, height: 142)
cell.MainView.backgroundColor = UIColor.white
cell.MainView.layer.shadowColor = UIColor.lightGray.cgColor
cell.MainView.layer.shadowOpacity = 1
cell.MainView.layer.shadowOffset = CGSize.zero
cell.MainView.layer.shadowRadius = 2
cell.MainView.layer.cornerRadius = 6
return cell
}
I want to merge two different sections that uses two different cells respectively(cellA and cellB). Using the following code I could get a collection view with two sections.
import UIKit
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource{
#IBOutlet var testCollectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
self.testCollectionView.delegate = self
self.testCollectionView.dataSource = self
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 2
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if section == 0 {
return 3
} else {
return 1
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if indexPath.section == 0 {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "taskCell", for: indexPath) as! CellA
cell.layer.cornerRadius = 2
cell.layer.shadowColor = UIColor(red:0.82, green:0.82, blue:0.82, alpha:1.0).cgColor
cell.layer.shadowOffset = CGSize.zero
cell.layer.shadowOpacity = 1
cell.layer.shadowRadius = 4
cell.layer.masksToBounds = false
return cell
} else {
let cell2 = collectionView.dequeueReusableCell(withReuseIdentifier: "addNewCell", for: indexPath) as! CellB
return cell2
}
}
}
extension ViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = testCollectionView.bounds.width/2 - 30
let height = width
return CGSize(width: width, height: height)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsetsMake(30, 20, 10, 20)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 20
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print(indexPath.row)
}
}
And the output looks like this.
Now, I want the section 1(CellB) to be merged with section 0(CellA). Like this.
I couldn't find the solution to achieve this. Any help will be appreciated.
You can show both cell types in the same section with these changes:
Add properties for the number of aCells and bCells. This is better than putting the magic numbers 3 and 1 in your code because it documents what the numbers represent. If you ever need to change them, you can change them in one spot.
Change numberOfSections to return 1.
Change numberOfItemsInSection to return the sum of the number of A cells and the number of B cells: return aCells + bCells.
In cellForItemAt, compare indexPath.item to aCells to figure out when to switch over to B cells.
var aCells = 3
var bCells = 1
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return aCells + bCells
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if indexPath.item < aCells {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "taskCell", for: indexPath) as! CellA
cell.layer.cornerRadius = 2
cell.layer.shadowColor = UIColor(red:0.82, green:0.82, blue:0.82, alpha:1.0).cgColor
cell.layer.shadowOffset = CGSize.zero
cell.layer.shadowOpacity = 1
cell.layer.shadowRadius = 4
cell.layer.masksToBounds = false
return cell
} else {
let cell2 = collectionView.dequeueReusableCell(withReuseIdentifier: "addNewCell", for: indexPath) as! CellB
return cell2
}
}
I am trying to create collectionView inside another collectionViewCell. I can get the cell of outer collectionView however, compiler is not executing inner cell. How can I get both the cells?
P.S I am new at this.
CollectionViewController Class:
class CollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout{
#IBOutlet var collectionView1: UICollectionView!
var coll2 = CollectionViewCell()
override func viewDidLoad() {
super.viewDidLoad()
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 3
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width, height: 150)
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)as! CollectionViewCell
cell.backgroundColor = UIColor.black
return cell
}
}
CollectionViewCell CLass:
class CollectionViewCell: UICollectionViewCell {
#IBOutlet var collectionView2: UICollectionView!
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView2.frame.width, height: 150)
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell1 = collectionView.dequeueReusableCell(withReuseIdentifier: "cell2", for: indexPath)as! CollectionViewCell2
cell1.backgroundColor = UIColor.red
return cell1
}
enter image description here
}
set the delegates and data source of inner collection view to the first collection view cell.
override func awakeFromNib()
{
super.awakeFromNib()
// Initialization code
self.collectionView2?.delegate = self
self.collectionView2?.dataSource = self
}
The reason why CollectionViewCell is not setting up the collectionView2 is because you didn't set delegate and dataSource properties of collectionView2 to the instance of CollectionViewCell.
I have created a method called setupViews in CollectionViewCell so that it can be called when you are dequeuing a CollectionViewCell in CollectionViewController so that the delegate and dataSource are being setup properly.
class CollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 3
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width, height: 150)
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)as! CollectionViewCell
cell.backgroundColor = UIColor.black
cell.setupViews() // added this call
return cell
}
}
class CollectionViewCell: UICollectionViewCell, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
#IBOutlet weak var collectionView2: UICollectionView!
// added this method
func setupViews() {
collectionView2.delegate = self
collectionView2.dataSource = self
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView2.frame.width, height: 150)
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell1 = collectionView.dequeueReusableCell(withReuseIdentifier: "cell2", for: indexPath)
cell1.backgroundColor = UIColor.red
return cell1
}
}