0

I have a collectionView. I have its dataSource and delegate methods set and I call func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { } when the user first makes a selection which works fine.

If the user leaves the view controller and comes back to it I call the below methods in viewWillAppear to programmatically force cell selection and scroll back to the cell that was initially chosen.

let whateverCellWasChosen = 29
let indexPath = IndexPath(item: whateverCellWasChosen, section: 0)

collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: false)
collectionView.selectItem(at: indexPath, animated: false, scrollPosition: .centeredHorizontally)

// problem is here
collectionView(self.collectionView, didSelectItemAt: indexPath)

But when trying to call the manual version of didSelectItem I keep getting an error of:

Cannot call value of non-function type 'UICollectionView'

enter image description here

The error stems from the first argument that accepts the collectionView. Why is it giving me a problem?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Lance Samaria
  • 17,576
  • 18
  • 108
  • 256
  • You shouldn't be trying to call any of the data source or delegate methods yourself. – rmaddy Nov 29 '18 at 23:43
  • Don't know your context , but here a similar problem that my answer went hand in hand with it https://stackoverflow.com/questions/35039756/cannot-call-value-of-non-function-type-string – Shehata Gamal Nov 29 '18 at 23:44
  • @rmaddy It's a calendar, the user picks a date, I keep the date inside custom delegate, they pop the vc, then go back to it, I would expect them to still see the date that they choose. In view didAppear I programmatically scroll to the date, then manually select it. I read a few posts that said using collectionView.selectItem(at: ...) doesn't trigger didSelect https://stackoverflow.com/a/45412980/4833705 – Lance Samaria Nov 29 '18 at 23:46
  • If you have code that you want to run in **didSelectRowAt** then make it inside a function and call it from `didSelectRowAt` and from `viewWillappear` , not tried but i think this won't select the row as it happens by ios that call`didSelectRowAt` at the end – Shehata Gamal Nov 29 '18 at 23:47
  • @Sh_Khan Initially I used selectItem and it worked fine but then ran across these 2 posts: stackoverflow.com/a/45412980/4833705 and stackoverflow.com/a/46784289/4833705. Apple: https://developer.apple.com/documentation/uikit/uicollectionview/1618057-selectitem specifically "This method does not cause any selection-related delegate methods to be called" – Lance Samaria Nov 29 '18 at 23:51
  • and what special thing in it that you want to run ? – Shehata Gamal Nov 29 '18 at 23:54
  • 1
    Is this in the viewWillAppear of the same class that is the CollectionView delegate? – Jason Nov 29 '18 at 23:56
  • @Sh_Khan not sure if you read the comments I made above describing my use for it but in a nutshell the reason I want to use it is because I'm manually scrolling to the cell, then selecting it, and I want to manually trigger didSelect – Lance Samaria Nov 29 '18 at 23:57
  • @Sh_Khan I'm going to try your function suggestion to see if it works. I have to run to the supermarket I'll try it when I get back – Lance Samaria Nov 30 '18 at 00:00
  • @Jason no its in the viewWillAppear of a different vc. The Calendar itself is it's own class, I create an instance it inside let's say vc1. Inside vc1 is where I eventually call the code from my question in viewWillAppear. That's a good question because the Calendar's collectionView's delegate isn't accessed inside vc1. – Lance Samaria Nov 30 '18 at 00:05
  • @Jason your question in the comments led me to the answer which was the accepted answer. That was the problem right there, since vc1 created an instance of the Calendar but didn't call the calendar's collectionView's delegate it would't accept the argument. The accepted answer resolved it. I wrapped it in an if let an it worked: 'if let delegate = calendar.collectionView.delegate { delegate.collectionView!(calendar.collectionView, didSelectItemAt: indexPath) }'. Thanks for the help! – Lance Samaria Nov 30 '18 at 00:13
  • @Sh_Khan I found the the problem, well really Jason did. It was because I didn’t have access to the collectionView’s delegate because it was in a different class. Thanks for help! – Lance Samaria Nov 30 '18 at 00:21
  • Glad I could help :) best of luck with your app – Jason Nov 30 '18 at 18:40
  • @Jason thabks enjoy your day – Lance Samaria Nov 30 '18 at 18:42

1 Answers1

1

Use

collectionView.delegate?.collectionView!(collectionView, didSelectItemAt: indexPath)
Chris Shaw
  • 1,610
  • 2
  • 10
  • 14
  • I'm trying it now – Lance Samaria Nov 29 '18 at 23:40
  • in the comments @Jason asked "Is this in the viewWillAppear of the same class that is the CollectionView delegate" which was where the problem stemmed from. The collectionView was inside a separate Calendar class which I created an instance of the calendar inside let's call it vc1. Since vc1 created an instance of the Calendar but didn't call the calendar's collectionView's delegate it wouldn't accept the argument. I wrapped it in an if let and it worked: 'if let delegate = calendar.collectionView.delegate { delegate.collectionView!(calendar.collectionView, didSelectItemAt: indexPath) }' – Lance Samaria Nov 30 '18 at 00:18