UICollectionViewDropDelegate: Drag cells on Delete Icon - ios

I have a collectionview and will support the drag and drop functionality of iOS 11. One requirement is that cells need to be removed by dragging them on a garbage bin on the bottom of the view. Is there a another possibility then using a second collectionview that holds that delete symobol?
Unfortunately a UIView can't be a UICollectionViewDropDelegate.

Best solution so far is to put an invisible collectionview above the delete icon. Here is my code:
import UIKit
class DragDropViewController: UIViewController
{
private var items1 = [String]()
//MARK: Outlets
#IBOutlet weak var collectionView1: UICollectionView!
#IBOutlet weak var collectionView2: UICollectionView!
#IBOutlet weak var trashImage: UIImageView!
private func createData(){
for index in 1...130{
items1.append("\(index)")
}
}
private func indexForIdentifier(identifier: String)->Int?{
return items1.firstIndex(of: identifier)
}
//MARK: View Lifecycle Methods
override func viewDidLoad()
{
super.viewDidLoad()
createData()
trashImage.alpha = 0
trashImage.layer.cornerRadius = 30
self.collectionView1.dragInteractionEnabled = true
self.collectionView1.dragDelegate = self
self.collectionView1.dropDelegate = self
self.collectionView2.dropDelegate = self
}
//MARK: Private Methods
/// This method moves a cell from source indexPath to destination indexPath within the same collection view. It works for only 1 item. If multiple items selected, no reordering happens.
///
/// - Parameters:
/// - coordinator: coordinator obtained from performDropWith: UICollectionViewDropDelegate method
/// - destinationIndexPath: indexpath of the collection view where the user drops the element
/// - collectionView: collectionView in which reordering needs to be done.
private func reorderItems(coordinator: UICollectionViewDropCoordinator, destinationIndexPath: IndexPath, collectionView: UICollectionView)
{
let items = coordinator.items
if items.count == 1, let item = items.first, let sourceIndexPath = item.sourceIndexPath
{
var dIndexPath = destinationIndexPath
if dIndexPath.row >= collectionView.numberOfItems(inSection: 0)
{
dIndexPath.row = collectionView.numberOfItems(inSection: 0) - 1
}
collectionView.performBatchUpdates({
self.items1.remove(at: sourceIndexPath.row)
self.items1.insert(item.dragItem.localObject as! String, at: dIndexPath.row)
collectionView.deleteItems(at: [sourceIndexPath])
collectionView.insertItems(at: [dIndexPath])
})
coordinator.drop(items.first!.dragItem, toItemAt: dIndexPath)
}
}
/// This method copies a cell from source indexPath in 1st collection view to destination indexPath in 2nd collection view. It works for multiple items.
///
/// - Parameters:
/// - coordinator: coordinator obtained from performDropWith: UICollectionViewDropDelegate method
/// - destinationIndexPath: indexpath of the collection view where the user drops the element
/// - collectionView: collectionView in which reordering needs to be done.
private func removeItems(coordinator: UICollectionViewDropCoordinator, destinationIndexPath: IndexPath, collectionView: UICollectionView)
{
collectionView.performBatchUpdates({
for item in coordinator.items
{
guard let identifier = item.dragItem.localObject as? String else {
return
}
if let index = indexForIdentifier(identifier: identifier){
let indexPath = IndexPath(row: index, section: 0)
items1.remove(at: index)
collectionView1.deleteItems(at: [indexPath])
}
}
})
}
}
// MARK: - UICollectionViewDataSource Methods
extension DragDropViewController : UICollectionViewDataSource
{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return collectionView == self.collectionView1 ? self.items1.count : 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell1", for: indexPath) as! DragDropCollectionViewCell
cell.customLabel.text = self.items1[indexPath.row].capitalized
return cell
}
}
// MARK: - UICollectionViewDragDelegate Methods
extension DragDropViewController : UICollectionViewDragDelegate
{
func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem]
{
let item = self.items1[indexPath.row]
let itemProvider = NSItemProvider(object: item as NSString)
let dragItem = UIDragItem(itemProvider: itemProvider)
dragItem.localObject = item
return [dragItem]
}
func collectionView(_ collectionView: UICollectionView, itemsForAddingTo session: UIDragSession, at indexPath: IndexPath, point: CGPoint) -> [UIDragItem]
{
let item = self.items1[indexPath.row]
let itemProvider = NSItemProvider(object: item as NSString)
let dragItem = UIDragItem(itemProvider: itemProvider)
dragItem.localObject = item
return [dragItem]
}
}
// MARK: - UICollectionViewDropDelegate Methods
extension DragDropViewController : UICollectionViewDropDelegate
{
func collectionView(_ collectionView: UICollectionView, canHandle session: UIDropSession) -> Bool
{
return session.canLoadObjects(ofClass: NSString.self)
}
func collectionView(_ collectionView: UICollectionView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UICollectionViewDropProposal
{
if collectionView === self.collectionView1
{
return collectionView.hasActiveDrag ?
UICollectionViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath) :
UICollectionViewDropProposal(operation: .forbidden)
}
else
{
if collectionView.hasActiveDrag{
return UICollectionViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath)
}
for item in session.items
{
guard let identifier = item.localObject as? String else {
return UICollectionViewDropProposal(operation: .forbidden)
}
//not every cell is allowed to be deleted
if Int(identifier)! % 3 == 0{
return UICollectionViewDropProposal(operation: .forbidden)
}
}
trashImage.backgroundColor = UIColor.red.withAlphaComponent(0.4)
return UICollectionViewDropProposal(operation: .move, intent: .unspecified)
}
}
func collectionView(_ collectionView: UICollectionView, performDropWith coordinator: UICollectionViewDropCoordinator)
{
let destinationIndexPath: IndexPath
if let indexPath = coordinator.destinationIndexPath
{
destinationIndexPath = indexPath
}
else
{
// Get last index path of table view.
let section = collectionView.numberOfSections - 1
let row = collectionView.numberOfItems(inSection: section)
destinationIndexPath = IndexPath(row: row, section: section)
}
if coordinator.proposal.operation == .move{
if coordinator.proposal.intent == .insertAtDestinationIndexPath{
self.reorderItems(coordinator: coordinator, destinationIndexPath:destinationIndexPath, collectionView: collectionView)
}
else{
self.removeItems(coordinator: coordinator, destinationIndexPath: destinationIndexPath, collectionView: collectionView)
}
}
}
func collectionView(_ collectionView: UICollectionView, dropSessionDidExit session: UIDropSession) {
trashImage.backgroundColor = UIColor.clear
}
func collectionView(_ collectionView: UICollectionView, dropSessionDidEnd session: UIDropSession) {
trashImage.backgroundColor = UIColor.clear
}
}

Related

want to add a collectionView inside tableView by downloading data from firebase to show . ios App Swift

want to add a UICollectionView inside UITableView by downloading data from firebase to show
Now I'm done with the interface part, but I'm stuck in the problem, can't bring data from firebase to show in the UICollectionView.
I can't run collectionView.reloadData() because the UICollectionView is different in class, how should I fix it?
func showImageRewardData(rewardID:String) {
let databaseRef = Database.database().reference().child("reward").child(rewardID).child("rewardImage")
databaseRef.observe(DataEventType.value, with: { (Snapshot) in
if Snapshot.childrenCount>0{
self.rewardDataArr.removeAll()
for rewardImage in Snapshot.children.allObjects as! [DataSnapshot]{
let rewardObject = rewardImage.value as? [String: AnyObject]
if(rewardObject?["imageURL"] != nil){
let imageUrl = rewardObject?["imageURL"]
let Data = rewardDetailClass(rewardImage: imageUrl as? String)
self.rewardDataArr.insert(Data, at: 0)
}
YOURVIEWCONTROLLER.SWIFT
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let CellIdentifier: String = "Cell_NotesList"
var cell: Cell_NotesList? = (tableView.dequeueReusableCell(withIdentifier: CellIdentifier) as? Cell_NotesList)
if cell == nil {
let topLevelObjects: [Any] = Bundle.main.loadNibNamed("Cell_NotesList", owner: nil, options: nil)!
cell = (topLevelObjects[0] as? Cell_NotesList)
cell?.selectionStyle = .none
}
cell?.reloadCollectionView(arr: arrofofthumbImages)
return cell!
}
YourCell.SWIFT
class Cell_NotesList: UITableViewCell {
var imagesArr = NSMutableArray()
override func awakeFromNib() {
collectionView.register(UINib.init(nibName: "cell_ImageCollection", bundle: nil), forCellWithReuseIdentifier: "cell_ImageCollection")
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
extension Cell_NotesList : UICollectionViewDataSource {
func reloadCollectionView(arr:NSMutableArray) {
imagesArr = arr
collectionView.reloadData()
self.layoutIfNeeded()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return imagesArr.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell : cell_ImageCollection? = collectionView.dequeueReusableCell(withReuseIdentifier: "cell_ImageCollection", for: indexPath) as? cell_ImageCollection
//YOUR CODE HERE
return cell!
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
}
}
extension Cell_NotesList : UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 120.0, height: 120.0)
}
}
extension UICollectionViewCell {
var indexPath: IndexPath? {
return (superview as? UICollectionView)?.indexPath(for: self)
}
}
In class that extends UICollectionView, put one setter method like
func setData(data: String){
// Update your cell view here like
Label.text = data
}

Reorder Collection View Cells buggy

I'm able to get the cells to move around but it's buggy. When you move them around the pictures change and they don't stay where you move them. When you scroll down and scroll back, they move back.
//
// CollectionViewController.swift
// 1.7 Task: Displaying Sets of Data: Collection View
//
// Created by Eric Andersen on 3/26/18.
// Copyright © 2018 Eric Andersen. All rights reserved.
//
import UIKit
class CollectionViewController: UICollectionViewController {
var batmanDataItems = [DataItem]()
var jokerDataItems = [DataItem]()
var allItems = [[DataItem]]()
var longPressGesture: UILongPressGestureRecognizer!
override func viewDidLoad() {
for i in 1...29 {
if i > 0 {
batmanDataItems.append(DataItem(title: "Title #\(i)", kind: Kind.Batman, imageName: "bat\(i).jpg"))
} else {
batmanDataItems.append(DataItem(title: "Title #0\(i)", kind: Kind.Batman, imageName: "bat0\(i).jpg"))
}
}
for i in 1...8 {
if i > 0 {
jokerDataItems.append(DataItem(title: "Another Title #\(i)", kind: Kind.Joker, imageName: "jok\(i).jpg"))
} else {
jokerDataItems.append(DataItem(title: "Another Title #0\(i)", kind: Kind.Joker, imageName: "jok0\(i).jpg"))
}
}
allItems.append(batmanDataItems)
allItems.append(jokerDataItems)
super.viewDidLoad()
let width = collectionView!.frame.width / 3
let layout = collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = CGSize(width: width, height: width)
longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(self.handleLongGesture(gesture:)))
collectionView?.addGestureRecognizer(longPressGesture)
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Register cell classes
// Do any additional setup after loading the view.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
// MARK: UICollectionViewDataSource
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 2
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return allItems[section].count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! DataItemCell
let dataItem = allItems[indexPath.section][indexPath.item]
cell.dataItem = dataItem
return cell
}
override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
let sectionHeader = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "SectionHeader", for: indexPath) as! DataItemHeader
var title = ""
if let kind = Kind(rawValue: indexPath.section) {
title = kind.description()
}
sectionHeader.title = title
return sectionHeader
}
override func collectionView(_ collectionView: UICollectionView, canMoveItemAt indexPath: IndexPath) -> Bool {
return true
}
override func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
// print("Starting Index: \(sourceIndexPath.item)")
// print("Ending Index: \(destinationIndexPath.item)")
}
// MARK: UICollectionViewDelegate
// Uncomment this method to specify if the specified item should be highlighted during tracking
override func collectionView(_ collectionView: UICollectionView, shouldHighlightItemAt indexPath: IndexPath) -> Bool {
return true
}
// Uncomment this method to specify if the specified item should be selected
override func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
return true
}
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
allItems[indexPath.section].remove(at: indexPath.row)
self.collectionView?.performBatchUpdates({
self.collectionView?.deleteItems(at: [indexPath])
}) { (finished) in
self.collectionView?.reloadItems(at: (self.collectionView?.indexPathsForVisibleItems)!)
}
}
#objc func handleLongGesture(gesture: UILongPressGestureRecognizer) {
switch(gesture.state) {
case .began:
guard let selectedIndexPath = collectionView?.indexPathForItem(at: gesture.location(in: collectionView)) else {
break
}
collectionView?.beginInteractiveMovementForItem(at: selectedIndexPath)
case .changed:
collectionView?.updateInteractiveMovementTargetPosition(gesture.location(in: gesture.view!))
case .ended:
collectionView?.endInteractiveMovement()
default:
collectionView?.cancelInteractiveMovement()
}
}
}
enter image description here
I'm new. I know this is easy but I'm still getting the hang of this. Thanks for your patience!
Moving the row only updates the screen, but it doesn't change your model (the array that supplies the data to your collectionView). Then when cells go off screen and back on, they are loaded from your array which hasn't changed, which is why the cells go back to where they were.
You need to override func collectionView(_:moveItemAt:to:) and update your data array to reflect the row that was moved.
override func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
// Remove the source item from the array and store it in item
let item = allItems[sourceIndexPath.section].remove(at: sourceIndexPath.item)
// insert the item into the destination location
allItems[destinationIndexPath.section].insert(item, at: destinationIndexPath.item)
}

CollectionView issue - Swift

I make music player using collectionView. I want to when selected collectionView like radio button. If another cell is selected, the selected cell should not be selected. but is not working.
I dont want multi selection. : https://i.stack.imgur.com/ATj3J.png
How do I work? TT I need your help. thx.
this my code.
import UIKit
class PracticeViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
var homeClassInPrac = HomeViewController()
var songPlayOff = UIImage(named: "play")
var songPlayOn = UIImage(named: "iconStop")
var buttonCounter = [Int]()
var freqNameList = ["Delta 1","Theta 1","Alpha 1","Beta 1","Delta 2","Theta 2","Alpha 2","Beta 2","Delta 3","Theta 3","Alpha 3","Beta 3","Delta 4","Theta 4","Alpha 4","Beta 4"]
#IBOutlet var practiceCollection: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
practiceCollection.delegate = self
practiceCollection.dataSource = self
self.practiceCollection.allowsMultipleSelection = false
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
self.practiceCollection.reloadData()
return freqNameList.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell:PracticeCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "pracCell", for: indexPath) as! PracticeCollectionViewCell
cell.pracImgView.image = songPlayOff
cell.pracLabel.text = freqNameList[indexPath.row]
if buttonCounter.contains(indexPath.row){
cell.pracImgView.image = songPlayOn
}
else{
cell.pracImgView.image = songPlayOff
}
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if buttonCounter.contains(indexPath.row){
let index = buttonCounter.index(of: indexPath.row)
buttonCounter.remove(at: index!)
self.practiceCollection.reloadData()
homeClassInPrac.audioPlayer2.stop()
}
else{
buttonCounter.removeAll()
buttonCounter.append(indexPath.row)
self.practiceCollection.reloadData()
let buttonInt = buttonCounter[0]
homeClassInPrac.playSound2(freqName: freqNameList[buttonInt])
}
print("Select\(buttonCounter)")
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
print("Deselect\(buttonCounter)")
let index = buttonCounter.index(of: indexPath.row)
buttonCounter.remove(at: index!)
self.practiceCollection.reloadData()
print("Deselect\(buttonCounter)")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
I think problem is you are reloading collectionView in numberOfItems method
so Just remove
self.practiceCollection.reloadData()
Change buttonCounter to Array of Bool with equal count to freqNameList
var buttonCounter : Array<Bool> = [false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]
In cellForItem method use :
if buttonCounter[indexPath.row]{
cell.pracImgView.image = songPlayOn
}
else{
cell.pracImgView.image = songPlayOff
}
In didSelectItem use :
buttonCounter[indexPath.row] = true
homeClassInPrac.playSound2(freqName: freqNameList[buttonInt])
self.practiceCollection.reloadData()
In didDeselectItem use :
buttonCounter[indexPath.row] = false
self.practiceCollection.reloadData()

can't delete item from collectionView

I have simple collectionview which shows 1 column on iphone and 2 columns on iPad
There is a button which removing an item from collectionview but when I press the button I got this error:
The number of sections contained in the collection view after the update (3) must be equal to the number of sections contained in the collection view before the update (4), plus or minus the number of sections inserted or deleted (0 inserted, 0 deleted).'
And this is my code
protocol AudioListDataProtocol: class {
func search(searchText: String)
func playComposition(composition: Composition, data: [Composition], play: Bool)
func endEditing()
}
class AudioListDataAdapter: NSObject, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UISearchBarDelegate, AudioItemCellProtocol {
var delegate: AudioListDataProtocol!
var isFavoriesList = false
private var data = [Composition]()
private var collectionView: UICollectionView!
private var searchBar: UISearchBar!
private let cellIdentifier = "AudioCellIdent"
private var selectedIndexPath: IndexPath!
private var cellWidth = 0 as CGFloat
private var sectionCount = 0
private var itemCount = 0
//MARK: public methods
func initSearchBar(searchBar: UISearchBar) -> Void {
self.searchBar = searchBar
self.searchBar.delegate = self
self.searchBar.returnKeyType = .done
self.searchBar.placeholder = DicionaryManager.shared.getStringValue(dKey: AMKeys.mobile_label_search_here)
}
func initCollection(collection: UICollectionView) -> Void {
self.collectionView = collection
self.collectionView.dataSource = self
self.collectionView.delegate = self
self.collectionView.register(UINib.init(nibName: "AudioItemCell", bundle: nil), forCellWithReuseIdentifier: cellIdentifier)
}
func setListData(data: [Composition], itemsPerSection: Int, itemWidth: CGFloat) -> Void {
cellWidth = itemWidth
self.data = data
itemCount = itemsPerSection
sectionCount = Int(ceil(Double(self.data.count / itemCount)))
}
func reload() {
collectionView.reloadData()
}
//MARK: UISearchBarDelegate
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
searchBar.showsCancelButton = true
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchText.characters.count >= 3 {
if let d = delegate {
d.search(searchText: searchText)
}
}
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchBar.text = ""
if let d = delegate {
d.search(searchText: "")
d.endEditing()
}
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
if let d = delegate {
d.endEditing()
}
}
//MARK: UICollectionViewDataSource
func numberOfSections(in collectionView: UICollectionView) -> Int {
return sectionCount
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return itemCount
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as? AudioItemCell {
return cell
}
return UICollectionViewCell()
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
let c = cell as! AudioItemCell
c.setupComposition(composition: data[curItemIndex(indexPath: indexPath)])
c.indexPath = indexPath
c.favoriteState = isFavoriesList
c.delegate = self
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
PlayerManager.shared.changePlaylist()
var item: Composition
item = data[curItemIndex(indexPath: indexPath)] as Composition
item.isPlaying = true
item.showPlayer = true
collectionView.reloadItems(at: [indexPath])
selectedIndexPath = indexPath
delegate.playComposition(composition: item, data: data, play: true)
}
func playingCompositionForReload(composition: Composition) {
composition.isPlaying = true
composition.showPlayer = true
collectionView.reloadData()
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: cellWidth, height: 90)
}
//MARK: helpers methods
func updateState(play: Bool) -> Void {
if (selectedIndexPath) != nil {
let item = data[curItemIndex(indexPath: selectedIndexPath)]
item.isPlaying = !item.isPlaying
} else {
selectedIndexPath = IndexPath(row: 0, section: 0)
let item = data[0]
item.isPlaying = true
item.showPlayer = true
}
collectionView.reloadItems(at: [selectedIndexPath])
}
private func curItemIndex(indexPath: IndexPath) -> Int {
return indexPath.section * itemCount + indexPath.item
}
//MARK: AudioItemCellProtocol
func removeCellAtIndexpath(indexPath: IndexPath) {
collectionView.performBatchUpdates({
self.data.remove(at: self.curItemIndex(indexPath: indexPath))
sectionCount = Int(ceil(Double(self.data.count / self.itemCount)))
self.collectionView.deleteItems(at: [indexPath])
}, completion: nil)
}
}
And this button pressed code
delegate.removeCellAtIndexpath(indexPath: indexPath)
What I did wrong here and why its crashing?
Please help I stuck on this a day.
The problem is with your numberOfItemsInSection method and the use of the itemCount property. You are returning a fixed number. You are assuming every section has the same fixed number of items. Instead, you should be returning the current number of records in your data source for the given section.
It would help a lot if you setup your data source to be an array of arrays where the outer array represents your sections and each inner array is the items in that section. Then you simply return the array count instead of some predetermined variable.

How can I check if the core data is empty?

I am using core data to populate a collection view. Now i want to check if it is empty or not. I want to do additional stuff if it is empty. How can I achieve that?
if myJokes.isEmpty == true {
noFavorites.isHidden = false
}
I have tried to check it likes this but it did not work:
class ViewController2: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDelegate, UICollectionViewDataSource {
var myJokes : [MyJokes] = []
override func viewDidLoad() {
super.viewDidLoad()
getData()
myCollectionView.reloadData()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return myJokes.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = myCollectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell2
if myJokes.isEmpty == true {
noFavorites.isHidden = false
}
cell.backView.layer.cornerRadius = 10
let task = myJokes[indexPath.row]
cell.textLabel.text = task.favoriteJokes!
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: myCollectionView.frame.width, height: 58)
}
func getData() {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
do {
myJokes = try context.fetch(MyJokes.fetchRequest())
} catch {}
}
#IBAction func menuBtnPressed(_ sender: Any) {
if menuShowing {
menuConstraint.constant = -171
UIView.animate(withDuration: 0.4, animations: {
self.view.layoutIfNeeded()
})
}

Resources