So I have an issue I've been battling with for days now. I have a collectionView which is designed to have large cells (width-wise) which go off screen. The height is fixed. The idea is to basically scroll to the end (see below):
To achieve being able to scroll left and right, I've had to override the width inside collectionViewContentSize in my flowLayout. Like below.
override var collectionViewContentSize: CGSize {
var size = super.collectionViewContentSize
size.width = largeWidth
return size
}
This achieves increasing the horizontal scroll area (which is what I want) but the cells start to disappear once I reach a certain point. It's almost as if the cells are being dequeued when they shouldn't be. Any ideas on this. This is the final straw for my project but I'm out of ideas.
Many thanks
Code snippet can be found below. You should be able to just copy and paste this into any project:
class HomeViewController: UIViewController {
let collectionView: UICollectionView
let collectionViewLayout = CustomCollectionViewFlowLayout()
init() {
collectionView = UICollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
super.init(nibName: nil, bundle: nil)
collectionView.backgroundColor = UIColor.red.withAlphaComponent(0.4)
collectionView.register(SomeCell.self, forCellWithReuseIdentifier: "SomeCell")
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
collectionView.delegate = self
collectionView.dataSource = self
}
override func viewDidLoad() {
super.viewDidLoad()
collectionView.frame = view.bounds
view.addSubview(collectionView)
}
}
class SomeCell: UICollectionViewCell {
}
extension HomeViewController: UICollectionViewDataSource,
UICollectionViewDelegate,
UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 150
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SomeCell", for: indexPath) as! SomeCell
cell.backgroundColor = .blue
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 10000, height: 70)
}
}
class CustomCollectionViewFlowLayout: UICollectionViewFlowLayout {
override var collectionViewContentSize: CGSize {
var size = super.collectionViewContentSize
size.width = 10000
return size
}
}
Related
I have a collectionView at the top of my App view and I want to display some ads inside it,
I made a ready array for some pictures that I want to display them in the collection view.
Now I'm looking for a method that I can make them horizontally scroll automatically.
class HomeVC: UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
setupCollectionViewCell()
}
#IBOutlet weak var collectionView: UICollectionView!
var array = [ "https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcR8aTilga7j-8GfP4OUXUx1bV3E2EJaFt29QdSBD8OgcLBLCUiG&usqp=CAU?",
"https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcRVq4AqZIDQ_UPnSd-PxQGkEutZnlu76NbZ4xETWelVnULLJ614&usqp=CAU",
"https://scontent.ffjr1-2.fna.fbcdn.net/v/t1.0-9/72577_563558293672959_39183751_n.jpg?_nc_cat=101&_nc_sid=dd9801&_nc_ohc=YySniLzpf_sAX-B8YFE&_nc_ht=scontent.ffjr1-2.fna&oh=12da3f0ae2404066684d742b4f785cfc&oe=5ED9FCDA",
"https://img.particlenews.com/image.php?type=thumbnail_1024x576&url=2zUI4r_0OJWDY4z00",
"https://content3.jdmagicbox.com/comp/def_content/advertising_agencies/default-advertising-agencies-9.jpg",
"https://miro.medium.com/max/895/1*2gq5_jgNSYJnLzCqIIYVGA.jpeg"]
}
Here below my registered cell that I want to make the autoscroll inside it by infinite array looping .
So can you help me how to do that?
extension HomeVC: UICollectionViewDelegate, UICollectionViewDataSource {
func setupCollectionViewCell () {
collectionView.delegate = self ; collectionView.dataSource = self
collectionView.register(UINib(nibName: "homeAdCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "adCell")
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return array.count
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewlayout: UICollectionViewLayout, sizeForItemAt IndexPath: IndexPath) -> CGSize {
print ("Size func called")
return CGSize(width: 250, height: 75)
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "adCell", for: indexPath) as! homeAdCollectionViewCell
cell.update(SURL: array[indexPath.row])
return cell
}
}
Set the Timer in ViewDidLoad and scroll to next item using collectionView.ScrollToitem method
If you want infinite scrolling with autoscroll effect, you can check this library:
https://github.com/WenchaoD/FSPagerView
I am struggled in passing images from collection view cell to another collection view cell.
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let mainStoryboard:UIStoryboard = UIStoryboard(name: "Main" , bundle: nil)
let vc = mainStoryboard.instantiateViewController(withIdentifier: "ImageViewController") as! ImageViewController
let imageItem = image[indexPath.row]
vc.images = imageItem.image
self.navigationController?.pushViewController(vc, animated: true)
}
then in ImageViewController
class ImageViewController: UIViewController ,UICollectionViewDelegate , UICollectionViewDataSource {
#IBOutlet weak var imageCollectionView: UICollectionView!
var image: string!
override func viewDidLoad() {
super.viewDidLoad()
self.imageCollectionView.reloadData()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return image.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = imageCollectionView.dequeueReusableCell(withReuseIdentifier: "ImageCollectionViewCell", for: indexPath) as! imageCollectionViewCell
let url: URL = NSURL(string: image)! as URL
cell.images.af_setImage(withURL: url)
return cell
}
import UIKit
//for the firstVC
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let mainStoryboard:UIStoryboard = UIStoryboard(name: "Main" , bundle: nil)
if let vc = mainStoryboard.instantiateViewController(withIdentifier: "ImageViewController") as? ImageViewController
vc.reciveImageFromFirstVC = image[indexPath.row]
self.navigationController?.pushViewController(vc, animated: true)
}
// for the second page image view controller
class ImageViewController : UIViewController {
var image:String!
var reciveImageFromFirstVC : String? {
didSet {
guard let reciveImg = reciveImageFromFirstVC else {
print("Can't get image for some reason")
return}
self.image = reciveImg
self.imageCollectionView.reloadData()
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = imageCollectionView.dequeueReusableCell(withReuseIdentifier: "ImageCollectionViewCell", for: indexPath) as! imageCollectionViewCell
let url: URL = NSURL(string: image)! as URL
cell.images.af_setImage(withURL: url)
return cell
}
}
i hope i helped you
thanks
Im new to swift and im trying to figure out a way to select multiple images and pass them as array in a API request.I tried to use DKImagePickerController, in which im able to select multiple images and even preview them but i have no idea how to pass them to an api as an array.
The code is as follows:
import UIKit
class CameraTabViewController: UIViewController,UICollectionViewDataSource, UICollectionViewDelegate{
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func saveCamBtn(_ sender: Any) {
let parent = self.parent as! DiaryEntryViewController
parent.CameraView.isHidden = true
}
#IBAction func selectPhotoBtn(_ sender: Any) {
let pickerController = DKImagePickerController()
pickerController.defaultSelectedAssets = self.assets
pickerController.didCancel = { ()
}
pickerController.didSelectAssets = { [unowned self] (assets: [DKAsset]) in
self.updateAssets(assets: assets)
}
self.present(pickerController, animated: true)
}
var pickerController: DKImagePickerController!
var assets: [DKAsset]?
#IBOutlet var previewView: UICollectionView!
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int{
return self.assets?.count ?? 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let asset = self.assets![indexPath.row]
var cell: UICollectionViewCell?
var imageView: UIImageView?
if asset.isVideo {
cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CellVideo", for: indexPath)
imageView = cell?.contentView.viewWithTag(1) as? UIImageView
} else {
cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CellImage", for: indexPath)
imageView = cell?.contentView.viewWithTag(1) as? UIImageView
}
if let cell = cell, let imageView = imageView {
let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
let tag = indexPath.row + 1
cell.tag = tag
asset.fetchImageWithSize(layout.itemSize.toPixel(), completeBlock: { image, info in
if cell.tag == tag {
imageView.image = image
}
})
}
return cell!
}
func updateAssets(assets: [DKAsset]) {
self.assets = assets
self.previewView?.reloadData()
}
}
I would like to create list of rows using UICollectionView with each row can click and go to another controller.
I create custom cell in xib and class for it.
This is my code:
class CollectionCellXIB: UICollectionViewCell {
#IBOutlet weak var label: UILabel!
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func awakeFromNib() {
super.awakeFromNib()
}
}
class Collection: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
#IBOutlet weak var collectionView: UICollectionView!
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 2
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
var cell: CollectionCellXIB
self.collectionView!.registerNib(UINib(nibName: "CollectionCellXIB", bundle: nil), forCellWithReuseIdentifier: "cell")
if indexPath.row == 0 {
cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! CollectionCellXIB
cell.label.text = "cell 1"
} else {
cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! CollectionCellXIB
cell.label.text = "cell 2"
}
return cell
}
}
Unfortunatelly, segues not working. When I clicked on a row, nothing happend. Method shouldPerformSegueWithIdentifier wasn't called.
So, question is, how to use custom cells with xib and using segues?
In my custom view controller defined as follows:
class Wall : UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, WallLayoutDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let layout = WallLayout()
layout.delegate = self
let collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: layout)
collectionView.registerClass(WallCell.self, forCellWithReuseIdentifier: Wall.reuseIdentifier)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.backgroundColor = UIColor.blackColor()
self.view.addSubview(collectionView)
self.collectionView = collectionView
}
// CODE
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
return CGSizeMake(50, 100)
}
}
The function sizeForItemAtIndexPath is never called. How it comes?
I found that it is because the layout is up to me when I use UICollectionViewDelegateFlowLayout and cannot be deduced by the collection view.