I've been working on this issue for the better part of a few days. I am attempting to segue from a UICollectionViewCell to a ViewController. While I understand how to do this, the segue is only triggered by selecting multiple cells (i.e. two or more taps, but must include different cells and not be outside of the CollectionView).
How can I alter my code to ensure that the segue happens only for one cell without the need to select more than one cell at a time (i.e. a normal segue, tap on Cell to segue).
What I've done so far:
Set up a Show segue from the UICollectionViewCell to the ViewController.
Implemented the CollectionView method didSelectItemAtIndexPath and prepareForSegue to pass data to the destination.
Disabled multiple section every object, to include the CollectionView, the Cell, and the items in the Cell.
Ensured that "User Interaction Enabled" on all the aforementioned fields.
Cell and Push segue have appropriate reuse ID.
My code for my CollectionViewController is as follows:
let reuseID = "HighscoreReuser"
#IBOutlet var addressBar: UISearchBar!
var noUsernameErrorMessage: UIAlertController = UIAlertController()
var pageLoadErrorMessage: UIAlertController = UIAlertController()
var noUsernameCount: Int = 0
var currentPlayer: Player = Player()
var titles = [String]()
var levelArray: [Int] = [Int]()
let sectionInsets = UIEdgeInsets(top: 20.0, left: 0.0, bottom: 0.0, right: 0.0)
override func viewDidLoad() {
super.viewDidLoad()
var tap:UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "DismissKeyboard")
self.collectionView?.addGestureRecognizer(tap)
titles = ["Lots of strings be here."]
addressBar = UISearchBar(frame: CGRectMake(0, 0, UIScreen.mainScreen().bounds.width - 30, 20))
addressBar.delegate = self
addressBar.showsScopeBar = true
var leftNavBarButton = UIBarButtonItem(customView: addressBar)
self.navigationItem.leftBarButtonItem = leftNavBarButton
var cellHeight = 85.0
var cellWidth = UIScreen.mainScreen().bounds.width / 3
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 23
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseID, forIndexPath: indexPath) as CollectionViewCell
cell.levelLabel.text = self.titles[indexPath.row]
let curr = indexPath.row + 1
println(curr)
let imgName = "skill\(curr).png"
cell.skillPicture.image = UIImage(named: imgName)
cell.frame.size.height = 85.0
cell.frame.size.width = UIScreen.mainScreen().bounds.width / 3
return cell
}
func collectionView(collectionView: UICollectionView!,
layout collectionViewLayout: UICollectionViewLayout!,
sizeForItemAtIndexPath indexPath: NSIndexPath!) -> CGSize {
return CGSize(width: UIScreen.mainScreen().bounds.width / 3, height: 85.0)
}
func collectionView(collectionView: UICollectionView!,
layout collectionViewLayout: UICollectionViewLayout!,
insetForSectionAtIndex section: Int) -> UIEdgeInsets {
return sectionInsets
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
return 0
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
return 0
}
override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
//not needed if placed in storyboard
//self.performSegueWithIdentifier("PushToCalc", sender: indexPath)
println("tapped")
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "PushToCalc" {
let indexPaths: NSArray = self.collectionView!.indexPathsForSelectedItems()
let indexPath: NSIndexPath = indexPaths[0] as NSIndexPath
println(indexPath)
let destination = segue.destinationViewController as UIViewController
destination.navigationItem.title = String(indexPath.item)
}
}
.... and my CollectionViewCell, if it matters:
import Foundation
import UIKit
class CollectionViewCell: UICollectionViewCell {
#IBOutlet weak var skillPicture: UIImageView!
#IBOutlet weak var levelLabel: UILabel!
}
I think you have to set cancelsTouchesInView to false to let the gesture recognizer allow your touch to pass through.
So under your var tap:UITapGestureRecognizer declaration try adding
tap.cancelsTouchesInView = false
Related
Im having issue with making page control work for a collection view which is inside table view. There are actually 2 collection views in the view controller, one is outside the tableView and other one is inside. I want page control for inside one. Let me share code below and then explain what is causing trouble:
class HomeViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
override func viewDidLoad() {
super.viewDidLoad()
//setup stories collection view
let nib = UINib(nibName: "StoryCollectionViewCell", bundle: nil)
cvStories.register(nib, forCellWithReuseIdentifier: "StoryCollectionViewCell")
let layout1 = UICollectionViewFlowLayout()
layout1.scrollDirection = .horizontal
layout1.sectionInset = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
collectionViewStories.setCollectionViewLayout(layout1, animated: true)
collectionViewStories.delegate = self
collectionViewStories.dataSource = self
tblHome.dataSource = self
tblHome.delegate = self
}
// MARK: - Table View
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tblHome.dequeueReusableCell(withIdentifier: "HomeTableViewCell", for: indexPath) as! HomeTableViewCell
cell.collectionViewPostImages.dataSource = self
cell.collectionViewPostImages.delegate = self
cell.collectionViewPostImages.tag = indexPath.row
cell.collectionViewPostImages.reloadData()
cell.pageControl.hidesForSinglePage = true
cell.pageControl.numberOfPages = self.posts[cell.collectionViewPostImages.tag].imagesArray?.count ?? 0
return cell
}
//MARK: - Collection View
func numberOfSections(in collectionView: UICollectionView) -> Int {
if collectionView == cvStories {
return 2
}
else {
return 1
}
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if collectionView == collectionViewStories {
return stories.count
}
else {
return posts[collectionView.tag].imagesArray?.count ?? 0
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView == collectionViewStories {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "StoryCollectionViewCell", for: indexPath) as! StoryCollectionViewCell
//code to show stories
return cell
}
else {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "HomeCollectionViewCell", for: indexPath) as! HomeCollectionViewCell
//code to show images
return cell
}
}
}
//TableViewCell Class
class HomeTableViewCell: UITableViewCell {
#IBOutlet weak var collectionViewPostImages: UICollectionView!
#IBOutlet weak var pageControl: UIPageControl!
var currentPage = 0
override func awakeFromNib() {
let flowLayout = UICollectionViewFlowLayout()
flowLayout.itemSize = CGSize(width: UIScreen.main.bounds.size.width, height: cvPostImages.frame.size.height)
flowLayout.scrollDirection = .horizontal
flowLayout.minimumInteritemSpacing = 0
flowLayout.minimumLineSpacing = 0
collectionViewPostImages?.collectionViewLayout = flowLayout
collectionViewPostImages.showsHorizontalScrollIndicator = false
collectionViewPostImages.isPagingEnabled = true
}
//ScrollView delegate method
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let pageWidth = scrollView.frame.width
self.currentPage = Int((scrollView.contentOffset.x + pageWidth / 2) / pageWidth)
self.pageControl.currentPage = self.currentPage
}
}
The whole code is like Instagram app, stories at top and posts with images in tableView. Whole code is in single View controller and everything works fine. Even dots (page number) are correct according to number of pages however when you swipe between them they do not change. I saw many solutions and in those pageControl.numberOfPages was used in cellForItemAt function but its out of scope for me so I just called it as cell.pageControl.numberOfPages in cellForRowAt instead. First time dealing with collectionView inside tableView so getting confused getting it worked.
The main problem is you use cell.collectionViewPostImages.delegate = self in HomeViewController but your method scrollViewDidScroll in cell HomeTableViewCell.
Collectionview's own scrollview delegate methods triggering in UICollectionViewDelegate. Thats why scrollViewDidScroll is not triggered in your cell.
Solution is using scrollViewDidScroll in where you delegete the collectionview. It is HomeViewController
By the way, I dont recommend to use cell.collectionViewPostImages.dataSource = self cell.collectionViewPostImages.delegate = self in reusable cell. You dont want to make ...delegate = self on everytime when cell reused. You can take it in awakeFromNib in cell class
I have a tableview with a UISwitch in each of the cells. What I am trying to do is that whenever the UISwitch is Toggled On, it adds that cell into an array and when the switch is Toggled Off it removes it. Right now it only adds and doesn't remove.
Once this is complete I need the CollectionView that is also within this ViewController to update and visually show the newStringArray Cells based on the number in that array and that also is able to appear and disappear based on the cells that have their UISwitch toggled on.
import UIKit
class NewMoveViewController: UIViewController {
private var stringSource = ["String 1,", "String 2", "String 3"]
var newStringArray = Array<String>()
private let tableView: UITableView = {
let tableView = UITableView()
tableView.rowHeight = 100
return tableView
}()
private var collectionView: UICollectionView?
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(tableView)
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.itemSize = CGSize(width: 50, height: 50)
collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView?.register(NewMoveCollectionViewCell.self, forCellWithReuseIdentifier: NewMoveCollectionViewCell.identifier)
collectionView?.showsHorizontalScrollIndicator = false
title = "Add to Group"
tableView.register(NewMoveTableViewCell.self, forCellReuseIdentifier: NewMoveTableViewCell.identifier)
tableView.delegate = self
tableView.dataSource = self
collectionView?.backgroundColor = .systemBlue
collectionView?.dataSource = self
collectionView?.delegate = self
guard let myCollection = collectionView else {
return
}
view.addSubview(myCollection)
// Do any additional setup after loading the view.
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
collectionView?.frame = CGRect(x: 0, y: 100, width: view.frame.size.width, height: 50)
tableView.frame = CGRect(x: 0, y: 200, width: view.frame.size.width, height: view.frame.size.height)
}
}
extension NewMoveViewController : UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: NewMoveTableViewCell.identifier, for: indexPath) as! NewMoveTableViewCell
let switchView = UISwitch(frame: .zero)
switchView.setOn(false, animated: true)
switchView.tag = indexPath.row
switchView.addTarget(self, action: #selector(self.switchDidChange(_:)), for: .valueChanged)
cell.accessoryView = switchView
cell.configure(with: "", label: "test")
return cell
}
#objc func switchDidChange(_ sender: UISwitch) {
newStringArray.append(stringSource[sender.tag])
// newStringArray.remove(stringSource.remove(at: [s]))
print(newStringArray)
}
func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
return false
}
}
extension NewMoveViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return newStringArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: NewMoveCollectionViewCell.identifier, for: indexPath) as! NewMoveCollectionViewCell
return cell
}
}
the hardest part is to remove an object from an array, my approach on these situations is to transform my array in a NSMutableArray because it have a function to remove an specific object, then make a delegate in the cell that informs the viewController to remove the object from the list and reload the tableView.
the delegate wil be something like this:
protocol RemoveObjectFromCell {
func removeObjectIncell(object: MyObject)
}
class myCell: UITableViewCell {
//your outlets and variables
var object: MyObject?
var delegate: removeObjectIncell?
func setupCell(object: myObject) {
//configure your cell with the specific object
}
}
make sure of calling the delegate on the switch action inside you cell class like this:
#IBAction func switchPressed(sender: UISwitch) {
if !sender.isOn {
self.delegate?.removeObjectIncell(object: self.object)
}
in the view controller implement your protocol and use the required function like this:
class myViewController: UIViewController, RemoveObjectFromCell {
//everything that goes in your class
func removeObjectIncell(object: MyObject) {
self.myArray.remove(object)
DispatchQueue.main.async {
self.myTableView.reloadData()
}
}
}
In order to get changes you want you have to set property which is gonna indicate whether switch is on or off
Something like: var switchIsActive = false
and simply change it in function and if it is turned on you perform one action when it is off you perform another one. Also after function you have to reload your tableView tableView.reloadData()
You can remove elements in your array by their tag by calling Array.remove(at: Int). It can be done by the cells [indexPath.row]
I am building an app with NSCollectionView and behaviour of NSCollectionView is so strange, sometimes it makes cell's visible and sometimes are not.
#IBOutlet weak var resourceCollectionView: NSCollectionView!
private func prepareCollectionView() {
let flowLayoutForEvent = NSCollectionViewFlowLayout()
flowLayoutForEvent.scrollDirection = .vertical
flowLayoutForEvent.minimumInteritemSpacing = 100
resourceCollectionView.collectionViewLayout = flowLayoutForEvent
resourceCollectionView.delegate = self
resourceCollectionView.dataSource = self
resourceCollectionView.isSelectable = true
resourceCollectionView.backgroundColors = [.clear]
resourceCollectionView.register(SimpleCell.self, forItemWithIdentifier: NSUserInterfaceItemIdentifier(rawValue: "SimpleCell"))
}
Then applied the function
public override func viewDidLoad() {
super.viewDidLoad()
prepareCollectionView()
}
Here is extension function for NSCollectionView
extension DashboardController : NSCollectionViewDelegateFlowLayout, NSCollectionViewDataSource {
// 1
public func numberOfSections(in collectionView: NSCollectionView) -> Int {
return 1
}
// 2
public func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
// 3
public func collectionView(_ itemForRepresentedObjectAtcollectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
let cell = resourceCollectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "SimpleCell"), for: indexPath) as! SimpleCell
return cell
}
public func collectionView(_ collectionView: NSCollectionView, didSelectItemsAt indexPaths: Set<IndexPath>) {
print("selected item > ", indexPaths )
}
public func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> NSSize {
return NSSize(width: 10 , height:10)
}
}
Here is programmatically cell for NSCollectionView
class SimpleCell: NSCollectionViewItem {
private var containerView: NSView!
private var containBox: NSBox = {
var box = NSBox()
box.boxType = .custom
box.fillColor = NSColor.purple
box.translatesAutoresizingMaskIntoConstraints = false
return box
}()
override func loadView() {
containerView = NSView()
self.view = containerView
containerView.bounds = self.view.bounds
containerView.addSubview(containBox)
containBox.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
containBox.leftAnchor.constraint(equalTo: containerView.leftAnchor).isActive = true
containBox.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true
containBox.rightAnchor.constraint(equalTo: containerView.rightAnchor).isActive = true
}
}
resourceCollectionView not showing the cells and there is a strange behaviour such as when I add a line resourceCollectionView.reloadData() it shows up and then hides all cells automatically.
What is the missing points for the situation?
Thanks in advance
Edit:
I've solved my problem, when I show another NSViewController I used
self.view = anotherViewController.view
then no functions of NSCollectionView is triggered.
Then I changed it to
self.view.window?.contentViewController = anotherViewController
Then it worked.
I've solved my problem, when I show another NSViewController I used
self.view = anotherViewController.view
then no functions of NSCollectionView is triggered.
Then I changed it to
self.view.window?.contentViewController = anotherViewController
It solved my problem.
class ViewController: UICollectionViewController {
var selectedRow : Int?
let data = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]
override func viewDidLoad() {
super.viewDidLoad()
collectionView.register(UINib(nibName: "CollectionViewCell", bundle: nil), forCellWithReuseIdentifier : "MyCell")
}
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return data.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath) as! CollectionViewCell
cell.Label.text = String(data[indexPath.row])
return cell
}}
class CollectionViewCell: UICollectionViewCell {
#IBOutlet weak var Label: UILabel!
#IBOutlet weak var button: UIButton!
#IBAction func buttonPressed(_ sender: UIButton) {
if Label.textColor == .red{
Label.textColor = .black
} else if Label.textColor == .black{
Label.textColor = .red
}}
public override func awakeFromNib() {
super.awakeFromNib()}}
I want to recognize whether cell is selected or not.
but I really don't know where in I have to use what function.
many people are saying using setSelected function but I think there is no such function.
I'm beginner so I don't know well.
what I want to is make "if I select one of that number then that cell's textColor turn red.
and then I select another cell. then that cell's textColor turn red and original one turn black again."
what function I have to use and where I have to use function.
There are so many ways to do it, I prefer the below way.
Change: 1
You need to add buttonPressed method into UIViewController
Change: 2
You need to add code for UILabel text color into cellForItemAt.
Full code:
class ViewController: UICollectionViewController {
var selectedRow : Int?
let data = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]
override func viewDidLoad() {
super.viewDidLoad()
collectionView.register(UINib(nibName: "CollectionViewCell", bundle: nil), forCellWithReuseIdentifier : "MyCell")
}
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return data.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath) as! CollectionViewCell
cell.button.tag = indexPath.item
cell.button.addTarget(self, action:#selector(buttonPressed(_:)) , for: .touchUpInside)
cell.Label.text = String(data[indexPath.row])
if selectedRow == indexPath.item{
cell.Label.textColor = .black
}else{
cell.Label.textColor = .red
}
return cell
}
#objc func buttonPressed(_ sender: UIButton) {
if selectedRow == sender.tag{
selectedRow = nil
}else{
selectedRow = sender.tag
}
collectionView.reloadData()
}
}
You should overload UICollectionViewDelegate's collectionView(_:didSelectItemAt:) method in your ViewController class. It gets called whenever user taps on a cell.
i have a collection view which has an array of images. when i press on any of the images it will open that image in full screen in another class. i tried to add swipe gesture recognizer in the second view controller but i dont know how to access the array that is in the first view controller.
This is my first view controller that displays the images in collection view
class sowrController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource{
#IBOutlet weak var collectionView: UICollectionView!
var albums = [AlbumModel]()
let db : DBHelperMo2lfat = DBHelperMo2lfat()
var selectedIndex : Int = -1
var posts : Post!
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
self.albums.removeAll()
self.albums.append(contentsOf: self.db.fetchAllImages())
self.collectionView.reloadData()
DataService.ds.REF_POSTS_SOWR.observe(.value, with: { (snapshot) in
if let snapshot = snapshot.children.allObjects as? [FIRDataSnapshot] {
self.albums.removeAll()
for snap in snapshot {
print ("SNAP: \(snap)")
if let postDict = snap.value as? Dictionary<String, AnyObject>{
let album : AlbumModel = AlbumModel(id: postDict["id"] as! String, name: postDict["image_name"] as! String, path: postDict["image_path"] as! String, url: postDict["image_path"] as! String, localPath: "")
if let items = snap.children.allObjects as? [FIRDataSnapshot] {
for itemSnap in items {
if let albumSnap = itemSnap.value as? Dictionary<String, AnyObject> {
album.childAlbums.append(AlbumModel(id: albumSnap["id"] as! String, name: albumSnap["image_name"] as! String, path: albumSnap["image_path"] as! String, url: albumSnap["image_path"] as! String, localPath: ""))
}
}
}
self.albums.append(album)
}
}
self.collectionView.reloadData()
}
})
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.albums.count
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Constants.BookCellReuseIdentifier, for: indexPath) as? collectionViewCellSowr {
let album = albums[indexPath.item]
cell.initWithAlbumModel(album: album)
return cell
}else {
return collectionViewCellSowr()
}
}
private struct Constants {
static let BookCellReuseIdentifier = "cell"
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.selectedIndex = indexPath.row
self.performSegue(withIdentifier: "showAlbum", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.identifier == "showAlbum"
{
let vc = segue.destination as! imageFullScreen
vc.images = self.albums[self.selectedIndex]
}
}
This is the second view controller that makes the images go in full screen
class imageFullScreen: UIViewController{
var images : AlbumModel?
let db : DBHelperMo2lfat = DBHelperMo2lfat()
#IBAction func pictureSwipe(_ sender: Any) {
}
#IBOutlet weak var caption: UILabel!
#IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
self.caption.text = images?.imageName
let url = URL(string: (images?.imagePath)!)
self.imageView.sd_setImage(with: url, placeholderImage: nil, options: [.progressiveDownload,.retryFailed])
}
EDIT:
Ok, so here is a collection view controller that creates image view as a subview and responding to swipe gestures. Please make sure you have two images "Image" and "Image-1" in your assets folder.
//
// CollectionViewController.swift
// test
//
// Created by Yonatan Vainer on 05/08/2017.
// Copyright © 2017 Sensus Healthcare LLC. All rights reserved.
//
import UIKit
private let reuseIdentifier = "id"
class CollectionViewController: UICollectionViewController {
var imageView = UIImageView(frame: CGRect(x: 0, y: 100, width: 300, height: 300))
var index = 0;
let names = ["Image","Image-1"]
override func viewDidLoad() {
super.viewDidLoad()
//For left swipe
let left = UISwipeGestureRecognizer(target: self, action: #selector(self.goLeft(_:)))
left.direction = .left
imageView.addGestureRecognizer(left)
//For right swipe
let right = UISwipeGestureRecognizer(target: self, action: #selector(self.goRight(_:)))
right.direction = .right
imageView.addGestureRecognizer(right)
imageView.isUserInteractionEnabled = true
self.view.addSubview(imageView)
self.view.layoutSubviews()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Register cell classes
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// 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 {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of items
return names.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
// Configure the cell
let nail = UIImageView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
nail.image = UIImage(named: names[indexPath.row])
cell.backgroundView = nail
return cell
}
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
imageView.image = UIImage(named: names[indexPath.row])
index = indexPath.row
}
func goLeft(_ gesture: UISwipeGestureRecognizer){
index += 1
if index<0{
index = 0
}
imageView.image = UIImage(named: names[index])
}
func goRight(_ gesture: UISwipeGestureRecognizer){
index -= 1
if index>1{
index = 1
}
imageView.image = UIImage(named: names[index])
}
// 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
}
*/
/*
// Uncomment these methods to specify if an action menu should be displayed for the specified item, and react to actions performed on the item
override func collectionView(_ collectionView: UICollectionView, shouldShowMenuForItemAt indexPath: IndexPath) -> Bool {
return false
}
override func collectionView(_ collectionView: UICollectionView, canPerformAction action: Selector, forItemAt indexPath: IndexPath, withSender sender: Any?) -> Bool {
return false
}
override func collectionView(_ collectionView: UICollectionView, performAction action: Selector, forItemAt indexPath: IndexPath, withSender sender: Any?) {
}
*/
}
==================================================================
In storyboard, click on your collection view and embed navigation controller.
This will add a top bar with the back button.
Attached image.
I'm not sure I completely understand your question, because I don't understand what the array has to do with a gesture recognizer, but if you are just trying to access the array from the previous ViewController, this should work if you have a navigation controller :
let vcIndex = self.navigationController?.viewControllers.index(where: { (viewController) -> Bool in
if let _ = viewController as? sowrController {
return true
}
return false
})
let prevVC = self.navigationController?.viewControllers[vcIndex!] as! sowrController
let albums:[AlbumModel] = prevVC.albums