Save Updated Order Of CollectionView Images To UserDefaults - Swift - swift

I have a collectionview which loads images and displays them. I have implemented gestures so that a person can hold and reorder the images, however the order does not save. Is there a way to save this order through User Defaults? If so, where would I implement this to save the order and load again? Below is my code for collectionView. Thanks in advance, any help is much appreciated!
func collectionView(_ imageCollection: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.posts.count
}
func collectionView(_ imageCollection: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = imageCollection.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! ImageCollectionViewCell
let post = self.posts[indexPath.item]
cell.imageView.sd_setImage(with: URL(string: post.imageURL))
return cell
}
func collectionView(_ imageCollection: UICollectionView, didSelectItemAt indexPath: IndexPath) {
switch mMode {
case .view:
imageCollection.deselectItem(at: indexPath, animated: true)
case .select:
dictionarySelectedIndexPath[indexPath] = true
}
}
func collectionView(_ imageCollection: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
if mMode == .select {
dictionarySelectedIndexPath[indexPath] = false
}
}
func collectionView(_ collectionView: UICollectionView, canMoveItemAt indexPath: IndexPath) -> Bool {
return true
}
func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let item = posts.remove(at: sourceIndexPath.row)
posts.insert(item, at: destinationIndexPath.row)
}

Base on your example code, I think it looks fine just missing to reload. :)
func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let item = posts.remove(at: sourceIndexPath.row)
posts.insert(item, at: destinationIndexPath.row)
collectionView.reloadData() //the missing code
}

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.

Change `numberOfItemsInSection` parameter of a collection view

How is it possible to change numberOfItemsInSection parameter of a collection view?
I have made a basic setup of a collection view. And now I try to make a button, that changes the amount of items in it.
The general setup is a standard one:
func numberOfSections(in collectionView: UICollectionView) -> Int {
1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
arrayA.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
cell.imageView.image = arrayA[indexPath.item][0].image
return cell
}
The question is - how to configure a button, so it could change numberOfItemsInSection parameter from current arrayA.count to some other (e.x. arrayB.count)?
Example:
You could take a common a flag to toggle between arrayA and arrayB. When the button is clicked as
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return isUseArrayA ? arrayA.count : arrayB.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
cell.imageView.image = isUseArrayA ? arrayA[indexPath.item][0].image : arrayB[indexPath.item][0].image
return cell
}
#IBAction func changeSource(sender: UIButton) {
if sender.tag == 0 {
isUseArrayA = true
sender.tag = 1
} else {
sender.tag = 0
isUseArrayA = false
}
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
self.collectionView.reloadData()
}
}
// No need of numberOfSection because it is bydefault 1.
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
arrayA.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
cell.imageView.image = arrayA[indexPath.item][0].image
return cell
}
#IBAction func changeArrayCount(sender: UIButton) {
arrayA.append(image)
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
self.collectionView.reloadData()
}
}

Xcode Swift UICollectionView: cellForItemAt IndexPath not called but numberOfItemsInSection does

I am currently programming an app with UICollectionView only when I start the app the CollectionView is not displayed. In my app I do not use the StoryBoard but only the ViewController. That's why I inherit from UICollectionViewController in my app. But when I start the app, the UICollectionView is simply not displayed. Through print commands I found out that the numberOfItemsInSection method is called, but the cellForItemAt indexPath is not. I also know that this will probably be a double question, but I still haven't found a solution for 2 hours. CollectionView.delegateand collectionView.dataSource are both set to = self and there are actually no problems with the constrains because I can turn the background of the UICollectionView to black, for example, and everything is displayed correctly there.
I hope someone can help me.
Best regards
// MARK: - Collectionview
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
print("Item wurde erstellt")
return messages.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! ChatMessageCollectionViewCell
let message = messages[indexPath.item]
cell.textView.text = message.message
setUpCell(cell, message)
cell.bubbleViewWidthAnchor?.constant = estimateFrameForText(text: message.message!).width + 32
print("Celle wird erstellt")
return cell
}
I think you have missed the height and width for the cell. You should also check the message array count, perhaps it is zero.
extension YouClass: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return messages.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! ChatMessageCollectionViewCell
let message = messages[indexPath.item]
cell.textView.text = message.message
setUpCell(cell, message)
cell.bubbleViewWidthAnchor?.constant = estimateFrameForText(text: message.message!).width + 32
print("Celle wird erstellt")
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collBanner.frame.width, height: 140)
}
}

Collection view loading only one cell at a time

Edited
I am using custom collection cells to load in collectionview. But when the collection view loadeds expecting behaviour cellforindex delegate will call for 3 indexpath but in this case only calling 0th indexpath 3 time.
override func viewDidLoad()
{
super.viewDidLoad()
let nib = UINib(nibName: "cellName", bundle: nil)
self.collectionvView?.register(nib, forCellWithReuseIdentifier: "cellId")
}
func numberOfSections(in collectionView: UICollectionView) -> Int
{
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return 10
}
func collectionView(_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
print("indexpath.row ----------------- ",indexPath.row)
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId",for: indexPath) as! DetailCollectionViewCell
return cell
}
Check All This
self.arrIds.count = 3
numberOfSections = 1
numberOfItemsInSection
cellForItemAt

UIcollectionView Cell set ZIndex . I want to create Card Cell using UICollectionView

Swift
I am trying to create card style cell. So i am using collection view and set minimumLineSpacingForSectionAt in negative this code is working it looks good.
Problem is when I have a scroller bottom to top then first cell is a top side but I don't have a need on top here i have attached my code please check. I have Attached Error Image after scrolling issue
class SecondViewController: UIViewController,UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {
let kItemSpace: CGFloat = -60.0
#IBOutlet weak var collection_setting: UICollectionView!
#IBOutlet var btn_top: UIButton!
var ary: NSMutableArray = NSMutableArray()
var ary_show: NSMutableArray = NSMutableArray()
override func viewDidLoad() {
super.viewDidLoad()
ary = ["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15"]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//-----------------------------------------------------------------------------------
// MARK: - collection DataSource & Delegate
//-----------------------------------------------------------------------------------
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.ary.count
}
// make a cell for each cell index path
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "smallCollectionViewCell", for: indexPath as IndexPath) as! smallCollectionViewCell
cell.inner_view.dropShadow()
cell.inner_view.backgroundColor = .random()
cell.layer.zPosition = -1
cell.lbl_.text = "DEMO - \(indexPath.row)"
//cell.bringSubview(toFront: collectionView)
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.frame.size.width, height: 100 )
}
public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
{
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: NSInteger) -> CGFloat {
return kItemSpace
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
print(indexPath.row)
if(indexPath.row == 14)
{
print("--------------->",indexPath.row)
cell.layer.zPosition = 0
}else
{
cell.layer.zPosition = -1
}
}
}
Demo - 7 ,Demo - 8 , Demo - 9 is looking good but others are not showing as I want . first time this is looking correctly. this problem has come after scrolling.
Try this code please.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "smallCollectionViewCell", for: indexPath as IndexPath) as! smallCollectionViewCell
if cell == nil {
cell.inner_view.dropShadow()
cell.inner_view.backgroundColor = .random()
}
cell.layer.zPosition = -1
cell.lbl_.text = "DEMO - \(indexPath.row)"
return cell
}
cell.layer.zPosition = CGFloat(array.count - indexPath.row)