How to trigger an function of an UICollectionViewCell inside an UICollectionViewController? - swift

I would like to trigger the animation3() function (which is a function inside PageCell() which is a UICollectionViewCell) inside the BreathingSwpipingController which is a UICollectionViewController.
class BreathingSwipingController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
var pageCell: PageCell?
override func viewDidLoad() {
super.viewDidLoad()
collectionView.backgroundColor = .white
collectionView.register(PageCell.self, forCellWithReuseIdentifier: "cellId")
collectionView.isPagingEnabled = true
setupStartStopButton()
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 3
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
pageCell = (collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as? PageCell)!
return pageCell!
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.frame.width, height: collectionView.frame.height)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
#objc func startStopTapped() {
pageCell!.animation3()
}
}

Make PageCell a delegate of BreathingSwipingController by making a protocol
protocol BreathingSwipingDelegate: class {
func doSth()
}
now inside UICollectionViewController define a weak var delegate: BreathingSwipingDelegate?
then head to PageCell file and conform to that protocol
class PageCell: BreathingSwipingDelegate .... {
func doSth() {
animation3()
}
var mController = BreathingSwipingController()
override init(style: .....) {
mController.delegate = self
.
.
.
.
}
}
now in BreathingSwipingController make the following
#objc func startStopTapped() {
delegate?.doSth()
}

Related

my xcode version is 13 and not support the collectionView below method

import UIKit
class ViewController: UIViewController,UICollectionViewDelegate,UICollectionViewDataSource {
var shoppingapp:[String] = ["cher","sale Small","shoes"]
override func viewDidLoad() {
super.viewDidLoad()
}
//this function is not working in my xcode 13 not calle this function
# func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
# return shoppingapp.count
# }
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! MyCollectionCell
cell.shoppinfappimage.image = UIImage(named: shoppingapp[indexPath.row] + ".jpeg")
cell.shoppinfappimage.layer.cornerRadius=50.0
return cell
}
}
I don't know which other method is there I am learning and practical in iOS application development****
First, please remove # from the code. Divide him into the ViewController extension.
extension ViewController: UICollectionViewDelegate,UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return shoppingapp.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! MyCollectionCell
cell.shoppinfappimage.image = UIImage(named: shoppingapp[indexPath.row] + ".jpeg")
cell.shoppinfappimage.layer.cornerRadius=50.0
return cell
}
}
But when I saw your code, I think you didn't declare delegate and DataSource.
//in viewDidLoad
collectionView.delegate = self
collectionView.dataSource = self
Write the code above in viewDidLoad. So I couldn't do a lot either.
If it didn't work, try it like this.
#available(iOS 13.0, *)
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return shoppingapp.count
}
I hope the writing helps me.

Cant display image in UICollectionView cell

I need to display images in collection view cells but when I'm trying to do that I'm getting 10 empty cells and I don't know where im making mistakes
Here is my code of ViewController
class NewGalleryViewController: UIViewController {
var presenter: ViewToPresenterPhotoProtocol?
var builder: GalleryRequestBuilder?
#IBOutlet var collectionView: UICollectionView!
let reuseIdentifier = "customCVCell"
#objc func refresh() {
presenter?.refresh()
}
override func viewDidLoad() {
super.viewDidLoad()
self.setupPresenterIfNeed()
presenter?.viewDidLoad()
// Do any additional setup after loading the view.
}
func setupPresenterIfNeed() {
self.collectionView.backgroundColor = UIColor.white
if self.presenter == nil {
let presenter = GalleryPresenter()
presenter.view = self
self.presenter = presenter
self.builder = GalleryRequestBuilder()
}
}
}
extension NewGalleryViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.presenter?.photos.count ?? 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! PhotoCollectionViewCell
KFImage.url(builder?.createImageUrl(name: (presenter?.photos[indexPath.item].name)!))
.onSuccess { result in
cell.imageView.image = result.image
}
return cell
}
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 180, height: 128)
}
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 20.0
}
// MARK: - UICollectionViewDelegate protocol
private func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
// handle tap events
print("You selected cell #\(indexPath.item)!")
}
}
extension NewGalleryViewController: PresenterToViewPhotoProtocol{
func onFetchPhotoSuccess() {
self.collectionView.reloadData()
self.collectionView!.collectionViewLayout.invalidateLayout()
self.collectionView!.layoutSubviews()
self.collectionView.refreshControl?.endRefreshing()
}
func onFetchPhotoFailure(error: String) {
print("View receives the response from Presenter with error: \(error)")
self.collectionView.refreshControl?.endRefreshing()
}
}
And Here is the code of cell
class PhotoCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var imageView: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
}
I've checked the link I'm making request to and it works. So problem is not in link. Maybe I should reload items after getting images?
You should set your UICollectionView delegate and data source once the view is loaded:
override func viewDidLoad() {
super.viewDidLoad()
// Add this lines
collectionView.delegate = self
collectionView.dataSource = self
self.setupPresenterIfNeed()
presenter?.viewDidLoad()
}

CollectionView don't update visible cell

Good afternoon!
Faced with this problem, there is a collection in which cells in the whole screen
the cell is configured with data,
and there are events inside the cell that make the collection reload,
it is not possible to make a check, if the cell is now visible, it is not necessary to update it completely, but only part of the data, I do not yet understand how to do it, can someone be able to prompt?!))
Test project))
import UIKit
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
#IBOutlet weak var collectionViwe: UICollectionView!
let dataSource = [1,2,3,4,5,6,7,8,9]
override func viewDidLoad() {
super.viewDidLoad()
collectionViwe.isPagingEnabled = true
collectionViwe.register(Cell.self, forCellWithReuseIdentifier: "Cell")
// Do any additional setup after loading the view.
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return dataSource.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! Cell
let text = String(dataSource[indexPath.row])
if cell.label.text != text {
cell.label.text = text
cell.label.backgroundColor = .random()
}
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return view.frame.size
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return .zero
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
collectionView.reloadData()
}
}
class Cell: UICollectionViewCell {
let label = UILabel()
override init(frame: CGRect) {
super.init(frame: frame)
label.backgroundColor = .red
addSubview(label)
label.frame = CGRect(x: 36, y: 36, width: 200, height: 100)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension CGFloat {
static func random() -> CGFloat {
return CGFloat(arc4random()) / CGFloat(UInt32.max)
}
}
extension UIColor {
static func random() -> UIColor {
return UIColor(red: .random(),
green: .random(),
blue: .random(),
alpha: 1.0)
}
}

Autolayout strange behaviour on Ipad

collection view getting right size with auto layout but view size on collection view is not working properly view on collection view taking size from storyboard design. its depend what you setting size in storyboard design. its working perfectly in Iphone but not working in Ipad. i tried to setting size in size for item at section but its not working.
dropbox link of project is here.
let isPad = UIDevice.current.userInterfaceIdiom == .pad
import UIKit
class AchivementVC: UIViewController {
#IBOutlet weak var clcAchivement:UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func btnBackClick(sender:UIButton)
{
self.navigationController?.popViewController(animated: true)
}
}
extension AchivementVC:UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout
{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "achiveCell", for: indexPath) as! AchiveClcCell
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
print(collectionView.frame)
if(isPad)
{
return CGSize(width: (collectionView.frame.size.width * 0.5)-30, height: (collectionView.frame.size.width * 0.45)-30)
}
else
{
return CGSize(width: (collectionView.frame.size.width * 0.5)-10, height: (collectionView.frame.size.width * 0.45)-10)
}
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
if(isPad)
{
return 30
}
else
{
return 10
}
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
if(isPad)
{
return 30
}
else
{
return 10
}
}
}
class AchiveClcCell:UICollectionViewCell
{
override func awakeFromNib() {
self.setNeedsLayout()
}
override func layoutSubviews() {
}
}
You should call super.layoutSubviews() when you override layoutSubviews

UICollectionViewLayout methods never get called

I am working with a UICollectionView and I am trying to use the UICollectionViewLayout methods to adjust the sizing of the cell however they are never being called. The methods are :
sizeForItemAtIndexPath, minimumInterimItemSpacingForSectionAtIndex, and minimumLineSpacingForSectionAtIndex
these 3 methods are never being called and I'm not sure where/ how to call them from. below is my code in Swift 3
import Foundation
import UIKit
class CollectionVC: UICollectionViewController {
var Sections = [SectionService]()
override func viewDidLoad() {
createServiceSections()
}
func createServiceSections(){
ServiceSections.append(ServiceSection(headerTitle: "1", items: 2, headerImage: UIImage(named: "Default"), stats: nil))
ServiceSections.append(ServiceSection(headerTitle: "2", items: 3, headerImage: UIImage(named: "Default"), stats: nil))
ServiceSections.append(ServiceSection(headerTitle: "3", items: 3, headerImage: UIImage(named: "Default"), stats: nil))
ServiceSections.append(ServiceSection(headerTitle: "4", items: 5, headerImage: UIImage(named: "Default"), stats: nil))
}
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return ServiceSections.count
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return ServiceSections[indexPath.section].items.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell1 = collectionView.dequeueReusableCell(withReuseIdentifier: "servicecell", for: indexPath) as! ServicesCellView
cell1.serviceLabel.text = "test"
cell1.serviceImage.image = ServiceSections[indexPath.section].headerImage
return cell1
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
print("size for item at indexPath")
var cellSize: CGSize
let collectionViewWidth = self.collectionView!.bounds.size.width
cellSize = CGSize(width: (collectionViewWidth * 0.48), height: (collectionViewWidth * 0.48))
return cellSize
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInterItemSpacingForSectionAtIndex section: Int) -> CGFloat {
print("min spacing section")
return 1
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
print("min line spacing section")
return 1
}
}
With help from Xinatanil, I was able to fix the issue. First, I had to change my class line to this
class CollectionVC: UICollectionViewController, UICollectionViewDelegateFlowLayout {
and then I had to change the methods declarations to Swift 3 syntax...
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
var cellSize: CGSize
let collectionViewWidth = self.collectionView!.bounds.size.width
cellSize = CGSize(width: (collectionViewWidth * 0.48), height: (collectionViewWidth * 0.48))
return cellSize
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 1
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 1
}
I think, you haven't set collectionView delegate
Please try:
self.collectionView.delegate = self in viewDidLoad() method
Actually UICollectionViewDelegateFlowLayout inherits from UICollectionViewDelegate. So setting the delegate will be sufficient.
Happy Coding!