How to display image of selected UICollectioNViewCell in UIView? (Swift 3) - ios

I am new to iOS development, so please bear with me if this is obvious.
I have a UICollectionView on the bottom half of a view controller; it currently displays all photos in my photo library. There is a UIView on the top half of the same view controller.
Q: When I select a UICollectionViewCell (i.e. a photo), how do I display that photo in the UIView on the same view controller?
I imagine I'll have to use didSelectItemAt somehow to save the index path of the selected image in order to display that image in the UIView. (I've included what I have thus far for didSelectItemAt.) How do I refresh the content of the UIView as different photos are selected?
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let selectedVideo = collectionView.cellForItem(at: indexPath)
selectedVideo?.alpha = 0.5
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
let deselectedVideo = collectionView.cellForItem(at: indexPath)
deselectedVideo?.alpha = 1.0
}

put ImageView into your view then make IBOutlet of imageview . you get cell of collectionview , set image of collectionviewcell of imageview image into top imageView
You can try this
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let selectedCell = collectionView.cellForItem(at: indexPath) as! MyCollectionViewCell
yourview.imageView.image = selectedCell.imageView.image
}

From my understanding on the comments you have described earlier, there are 2 ways you can implement.
Using UIViewController, drop a UIView and a UICollectionView.
Using UICollectionViewController, and create a UICollectionReusableView
I'm assuming that you are using the 1st method,
Drop an #IBOutlet for the above UIImageView and name it myImageView for example.
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let selectedImage = collectionView.cellForItem(at: indexPath)
myImageView.image = selectedImage.myImageView.image
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let selectedVideo = collectionView.cellForItem(at: indexPath)
view.imageView.image = selectedVideo
}

Related

Implement delegate in didSelectItemAt

I am using delegate to make a connection between a UICollectionViewCell and a UICollectionViewController. In this connection I want to say, if user clicks on a UIView its super class is changed, I already did it by using gesture.
The only problem is, I think I have to implement this delegation into the didSelectItemAt protocol of UIcollectionView', which I am not sure to how to do it.
For example, first I did it in the cellForItemAt, which was a mistake, buy I could implement easily.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "listCell", for: indexPath) as? ListCell
cell?.selectionDelegate = self // implement the delegate
}
but I don't know how to do the same thing in didSelectItemAt, because I think I should do it here, not in cellForItemAt
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
}
Thank you so much for your help in advance
Let's say you had your original selection delegate:
protocol SelectionDelegate {
func didSelect(_ cell: ListCell)
}
Then you can easily implement collectionView's didSelect by just calling your selection delegate:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard let cell = collectionView.cellForItem(at: indexPath) as? ListCell else { return }
didSelect(cell)
}

iOS12 UICollectionView willDisplay cell called on all cells

My keyboard extensions which consists of a UICollectionView of UIImages keeps crashesing on iOS12 after exceeding 53MB of RAM
collectionView:willDisplay cell is called on all cells, regardless if they are shown
NOTE: didEndDisplaying gets never called
func collectionView(_ collectionView: UICollectionView, willDisplay c: UICollectionViewCell, forItemAt indexPath: IndexPath)
can i bring back the behaviour of collectionView:willDisplay so its called only when the cell is really displayed?
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell: EmojiCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "EmojiCollectionViewCell", for: indexPath) as! EmojiCollectionViewCell
return cell
}
func collectionView(_ collectionView: UICollectionView, willDisplay c: UICollectionViewCell, forItemAt indexPath: IndexPath) {
let cell = c as! EmojiCollectionViewCell
let imageName = String(format:"%#-%#", categories[selectedCategory], NSNumber(value: indexPath.row + 1));
let emojiImage = UIImage(named: imageName)
cell.setupWithEmojiImage(image: emojiImage)
}
func collectionView(_ collectionView: UICollectionView, didEndDisplaying c: UICollectionViewCell, forItemAt indexPath: IndexPath) {
let cell = c as! EmojiCollectionViewCell
cell.setupWithEmojiImage(image: nil)
}
You're probably calling reloadData() or something within a tableview datasource method, causing an infinite loop. what is the code in setupWithEmojiImage(image: nil)? I think you should place the following in cellForRow instead of willDisplay:
let imageName = String(format:"%#-%#", categories[selectedCategory], NSNumber(value: indexPath.row + 1));
let emojiImage = UIImage(named: imageName)
cell.setupWithEmojiImage(image: emojiImage)
Also avoid using the bang operator (!) to force unwrapping, this leads to crashing if the object doesn't exist. Do this:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell: EmojiCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "EmojiCollectionViewCell", for: indexPath) as? EmojiCollectionViewCell {
return cell
}
return UITableViewCell()
}

UIcollectionview list of horizontal toggle button in Swift

I would like to create a list of horizontal buttons in UIcollectionview. Only one and only button can be selected and it will change to red color, problem is the selected cell will be reuse then there is possibility two red buttons appear in a same time, what should I do to solve this?
Store the index of the selected row in didSelectRow , then inside cellForItemAt
var selectedIndex = -1
var urlArr = [url1,url2,url3,url4,url5]
//
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CellIdentifier1, for: indexPath as IndexPath) as! imagesCollectionViewCell
let currentUrl = urlArr[indexPath.row]
if(indexPath.row == selectedIndex)
{
// red
}
else
{
// default
}
}
if you want to create multiple toggle cells in UICollectionView then use this.
var selectedIndexes = NSMutableArray()
var items = [item1,item2,item3,item4,item5]
in cellForItemAt method. check for selected indexPath.row
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: yourIdentifier, for: indexPath as IndexPath) as! yourCell
if selectedIndexes.contains(indexPath.row){
// make it active
}else{
// make it default
}
}
And in didSelectItemAt method add and remove indexPath from the Array to toggle the button of cell
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if selectedIndexes.contains(indexPath.row){
selectedIndexes.add(indexPath.row)
}else{
selectedIndexes.remove(indexPath.row)
}
collectionView.reloadData()
}

UICollectionViewCell Deselect Pre-Selected Cell on First Tap

I am modally presenting a viewcontroller that hosts a viewcollection with "pre-selected" cells formatted to a different background color based on data passed on segue.
When I tap on one of these "pre-selected" cells, it takes two taps to trigger the didDeselectItemAt delegate method. I understand why this is happening while debugging, where the cell although of different color is not necessarily recognized in a selected state. Is there any way to trigger didDeselectItemAt first for the "pre-selected" cells?
I've tried, within the delegate method cellForItemAt, to incorporate, as part of a conditional statement that changes the cell background color, setting cell.isSelected = true. Similarly within the same delegate method, I've also tried invoking a function that would invoke the delegate method didSelectItemAt with indexPaths of these "pre-selected" cells. Both produced the same result.
Below is (abbreviated) relevant code snippets:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath as IndexPath) as! ExampleCollectionViewCell
if preselectedDataPoints { cell.backgroundColor = blue }
else { cell.backgroundColor = white }
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath)
cell?.backgroundColor = blue
preselectedDataPoints.append(newDataPoint)
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath)
cell?.backgroundColor = white
preselectedDataPoints.remove(at: existingDataPoint)
}
Programatically call collectionView.deselectItem(at: indexPath, animated: true) in didSelectItem if cell is preselected.
Refrer code
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if preselectedDataPoints {
collectionView.deselectItem(at: indexPath, animated: true)
}else{
let cell = collectionView.cellForItem(at: indexPath)
cell?.backgroundColor = blue
preselectedDataPoints.append(newDataPoint)
}
}
or
Directly call what ever code you need to execute in deSelect method
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if preselectedDataPoints {
let cell = collectionView.cellForItem(at: indexPath)
cell?.backgroundColor = white
preselectedDataPoints.remove(at: existingDataPoint)
}else{
let cell = collectionView.cellForItem(at: indexPath)
cell?.backgroundColor = blue
preselectedDataPoints.append(newDataPoint)
}
}

Outlet is nil in UICollectionViewCell

I have a UICollectionViewCell defined like so:
import UIKit
class GalleryCellCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var image: UIImageView!
}
Xcode put this in automatically when I added the outlet. In my UICollectionViewController's
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
function, I then try to set an image. My code is
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! GalleryCellCollectionViewCell
let imagePackage = imagePackages?[indexPath.item]
let uiImage = imagePackage?.getUIImage()
cell.image.image = uiImage
return cell
}
In my variable viewer for the debugger, I can see that uiImage is not nil. However, cell.image is nil. Why would this be? Did I not link it up correctly in the storyboard?
You can access image with another approach using tag.
from Interface builder (IB) of the cell go to attribute tab (third tab) and set tag for the image (like 5)
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! GalleryCellCollectionViewCell
let imagePackage = imagePackages?[indexPath.item]
let uiImage = imagePackage?.getUIImage()
var cellImg:UIImageView = cell!.viewWithTag(5) as! UIImageView;
cellImg.image = uiImage
return cell
}

Resources