Making a Popup ViewController out of a UICollectionViewController - ios

I'm working with a UITableViewController and when clicking a cell i would like to have a UICollectionViewController be popped up.
I've been successful in presenting the UICollectionViewController from a UITableViewController. However, I'm not able to figure out on how to present it like a pop-up only taking portion of the screen. It currently feels the entire view.
I searched on stackoverflow but couldn't find a working solution.
UITableViewController
class SearchViewController: UITableViewController, UISearchBarDelegate {
let cellId = "cellId"
var filteredArray = [String]()
let books = Model().books
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.white
navigationItem.titleView = navSearchBar
setupView()
}
// Views.
let navSearchBar = NavSearchBar()
func setupView() {
tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellId)
tableView.delegate = self
tableView.dataSource = self
navSearchBar.delegate = self
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) { // Cancel button is touched.
self.dismiss(animated: true, completion: nil)
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return books.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
book = books[indexPath.row]
}
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)
cell.textLabel?.text = book
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
let cellLabelContent = cell!.textLabel!.text // Gets cell name.
let cellLabelIndex = bibleBooks.firstIndex(of: cellLabelContent!) // searches books array to get correct index of cell name.
print("Book name:", cellLabelContent!+",", "index:", cellLabelIndex!)
let notificName = Notification.Name(rawValue: searchedBookIndex)
NotificationCenter.default.post(name: notificName, object: cellLabelIndex)
dismiss(animated: true, completion: nil)
**HERE is where i present the collectionView**
let layout = UICollectionViewFlowLayout()
var topVC = UIApplication.shared.keyWindow?.rootViewController
while((topVC!.presentedViewController) != nil) {
topVC = topVC!.presentedViewController
let navController = UINavigationController(rootViewController: ChapterNumbersCollectionView(collectionViewLayout: layout))
topVC?.present(navController, animated: true, completion: nil)
}
}
UICollectionViewController
class ChapterNumbersCollectionView: UICollectionViewController {
let reuseIdentifier = "CellId"
override func viewDidLoad() {
super.viewDidLoad()
setupCollectionView()
setupNavigationItem()
}
private func setupCollectionView() {
collectionView.backgroundColor = .yellow
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
}
private func setupNavigationItem() {
let button = UIButton(type: .system)
button.setTitle("cancel", for: [])
button.addTarget(self, action: #selector(handleDismiss), for: .touchUpInside)
button.frame = CGRect(x: 0, y: 0, width: 34, height: 34)
self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: button)
}
#objc func handleDismiss() {
dismiss(animated: true, completion: nil)
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 200
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
cell.backgroundColor = .red
return cell
}

One approach would be to use view controller containment. You'd instantiate ChapterNumbersCollectionView in didSelectRow, but instead of presenting, add it as a child view controller.
Then, having added its view as a subview, animate it in using animateWithDuration.

Related

How to show view controller on selecting row cell of tableView(as a collection view cell)?

I have the Main View Controller which has a collection view with its collection view cells each initialized as a tableView to serve multiple rows inside of that collection view cell. If you're getting confused, below is the snapshot of the current state.
The problem is when I try to tap a tableView row cell to open another view controller, It fails and a selected state of table view cell is shown.
Here is the snapshot.
//HomeCollectionViewCell.swift
class HomeCollectionViewCell: UICollectionViewCell {
override func layoutSubviews() {
super.layoutSubviews()
setUpCellView()
}
func setUpCellView() {
let frame = CGRect(x:20, y:20, width: bounds.width - 40, height: 600)
let cell = CellView(frame: frame)
contentView.addSubview(cell)
}
}
//CellView.swift
class CellView: UITableView {
let quoteCell = "QuoteCell"
let newsCell = "NewsCell"
let articleCell = "ArticleCell"
override init(frame: CGRect, style: UITableViewStyle) {
super.init(frame: frame, style: .grouped)
self.layer.cornerRadius = 15
self.backgroundColor = .white
self.dataSource = self
self.delegate = self
self.register(QuoteTableViewCell.self, forCellReuseIdentifier: quoteCell)
self.register(NewsTableViewCell.self, forCellReuseIdentifier: newsCell)
self.register(ArticleTableViewCell.self, forCellReuseIdentifier: articleCell)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension CellView: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
switch indexPath.section {
case 0: return 35
case 1: return 140
case 2: return 100
case 3: return 140
default: return 0
}
}
}
extension CellView: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return categories.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return categories[section]
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch indexPath.section {
case 0: let cell = tableView.dequeueReusableCell(withIdentifier: dateCell)
cell?.textLabel?.text = "Today"
cell?.textLabel?.font = UIFont.systemFont(ofSize: 30, weight: UIFont.Weight.heavy)
return cell!
case 1: let cell = tableView.dequeueReusableCell(withIdentifier: quoteCell) as! QuoteTableViewCell
return cell
case 2: let cell = tableView.dequeueReusableCell(withIdentifier: newsCell) as! NewsTableViewCell
return cell
case 3: let cell = tableView.dequeueReusableCell(withIdentifier: articleCell) as! ArticleTableViewCell
return cell
default: let cell = tableView.dequeueReusableCell(withIdentifier: commonCell)
cell?.textLabel?.text = "LOL"
return cell!
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath.section {
case 0: print("Date Selected")
case 1: print("Quote Selected")
case 2: print("News Selected")
case 3: let homeViewController = HomeViewController()
let articleDetailViewController = ArticleDetailViewController()
//homeViewController.show(articleDetailViewController, sender: homeViewController)//homeViewController.navigationController?.pushViewController(articleDetailViewController, animated: true)
homeViewController.present(articleDetailViewController, animated: true, completion: nil)
print("Article selected")
default: print("LOL")
}
}
}
//HomeViewController.swift
class HomeViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupNavBar()
view.addSubview(collectionView)
setUpConstraints()
configure(collectionView: collectionView)
}
func setUpConstraints() {
_ = collectionView.anchor(view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, topConstant: 10, leftConstant: 10, bottomConstant: 10, rightConstant: 10, widthConstant: 0, heightConstant: 0)
collectionView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
}
lazy var collectionView : UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
let cv = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
cv.translatesAutoresizingMaskIntoConstraints = false
cv.alwaysBounceVertical = true
cv.clipsToBounds = true
cv.showsHorizontalScrollIndicator = false
cv.showsVerticalScrollIndicator = false
cv.backgroundColor = .clear
cv.isHidden = false
return cv
}()
}
private let reuseIdentifier = "Cell"
extension HomeViewController: UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
internal func configure(collectionView: UICollectionView) {
collectionView.register(HomeCollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
collectionView.dataSource = self
collectionView.delegate = self
collectionView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 20, right: 0)
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 7
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! HomeCollectionViewCell
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.bounds.width, height: 600)
}
}
Please tell where I'm doing wrong or What approach should I use?
Note- No use of storyboards/IB. Done things programmatically only.
Give identifiers("HomeViewController" and "ArticleDetailViewController") to view controllers and try below code in didSelectRow().
case 3:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let sourceViewController = storyboard.instantiateViewController(withIdentifier: "HomeViewController") as? HomeViewController
let destinationViewController = storyboard.instantiateViewController(withIdentifier: "ArticleDetailViewController") as? ArticleDetailViewController
let navigator: UINavigationController = sourceViewController as! UINavigationController
navigator.pushViewController(destinationViewController!, animated: true)
From what have you done, I want to point out that its not a good idea to present UIViewController from UView. You must write some custom delegates which will get fired once someone taps on those cells in the custom CellView class. Those delegates must be implemented in the view controller that contains the tableview. From the UIViewController you must write the code to present the new viewcontrollers.

Swift: How to reuse a ViewController properly

I got a HomeController of type UICollectionViewController which handles some PictureCells (contains a picture and a label).
Now I am sending one PictureCell to another ViewController to edit the label. This all works perfectly. I could send it back to the HVC using a protocol but instead of going back I want to go one step further and Display the edited PictureCell in a new ViewController.
Instead of creating a completely new one, I am subclassing the existing HomeController to reuse his CollectionView. All works fine and the view shows up but the edited PictureCell is not showing up at all, even tho I can show it's layer, the Cell itself with its content doesn't show up.
(Messy) Class-Diagram looks like this:
ClassDiagram
class HomeController: UICollectionViewController, UICollectionViewDelegateFlowLayout, MyProtocol {
override func viewDidLoad() {
super.viewDidLoad()
collectionView?.backgroundColor = UIColor.black
collectionView?.register(PictureCell.self, forCellWithReuseIdentifier: Constants.cellId)
}
//MARK: Get value from second VC
var valueSentFromSecondViewController: String?
var cellSentFromSecondViewController: PictureCell?
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
//Acting with Protocol here
}
//HERE ARE THE COLLECTIONVIEWFUNCTIONS
}
class PictureEditViewController: UIViewController, UITextFieldDelegate {
var delegate:MyProtocol?
var myCell: PictureCell?
let collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.backgroundColor = UIColor.white
return cv
}()
init(pictureCellInit: PictureCell?) {
self.myCell = pictureCellInit
super.init(nibName: nil, bundle: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
showThings()
}
#objc func showNextVC() {
let newViewController = PictureShowViewController(withCell: self.myCell)
newViewController.modalPresentationStyle = .overCurrentContext
present(newViewController, animated: true) //with dismiss
}
#objc func showThings() {
view.addSubview(collectionView)
self.collectionView.frame = CGRect(x: x, y: y, width: width, height: height)
self.setupViews()
}
func setupViews() {
//ADDING THE SUBVIEWS
}
func confBounds() {
//LAYOUT
}
#objc func handleDismiss() {
self.dismiss(animated: true, completion: nil)
}
class PictureShowViewController: HomeController {
//MARK: Variable/Constant declaration
var myCellToShow: PictureCell?
init(withCell: PictureCell?) {
let layoutUsing = UICollectionViewFlowLayout()
myCellToShow = withCell
super.init(collectionViewLayout: layoutUsing)
}
override func viewDidLoad() {
super.viewDidLoad()
collectionView?.backgroundColor = .white
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
collectionView?.addSubview(myCellToShow!)
self.collectionView?.reloadData()
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell = myCellToShow {
cell.layer.borderColor = UIColor.red.cgColor
cell.layer.borderWidth = 2
return cell
}
else {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Constants.cellId, for: indexPath) as! PictureCell
return cell
}
}
//Size of Cell
override func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let cellSize = CGFloat(view.frame.width)
return CGSize(width: cellSize, height: cellSize)
}
}
Does anyone have an idea where I went wrong?
It is a bad idea to use PictureCell to move your data around view controllers. UICollectionView reuses instances of cells so the content of the cell is bound to change anytime.
So instead of using your cell, hand over the underlying data and insert the data in to the newly dequeued collection view cell.
In the end,
var cellSentFromSecondViewController: PictureCell?
should be var pictureFromSecondViewController: YourPictureData
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Constants.cellId, for: indexPath) as! PictureCell
//Set your data
cell.picture = pictureFromSecondViewController
return cell
}

How to present a ViewController after pressing a button inside of a CollectionViewCell

Hey i'm new to programming and my problem is, i have a UICollectionViewController with 4 cells that are horizontal scrollable. Inside of the 4th cell i have a UIButton(optionsButton) on top of a UIView (ProfileContainerView).
The UIViewController I want to present is called ProfileEditViewController and is set up in Main.storyboard.
How can i present a UIViewController after pressing this button?
ProfileCell:
class ProfileCell: UICollectionViewCell {
let profileContainerView: UIView = {
let view = UIView()
return view
}()
lazy var optionsButton: UIButton = {
let btn = UIButton(type: .custom)
btn.setImage(#imageLiteral(resourceName: "Settings"), for: UIControlState.normal)
btn.addTarget(self, action: #selector(handleOptionsButton), for: UIControlEvents.touchUpInside)
return btn
}()
#objc func handleOptionsButton() {
print("Button pressed")
}
}
HomeViewController:
class HomeViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
let profileCelId = "profileCell"
override func viewDidLoad() {
super.viewDidLoad()
setupSwipeView()
}
func setupSwipeView() {
collectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: cell)
collectionView?.register(ProfileCell.self, forCellWithReuseIdentifier: profileCelId)
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if indexPath.item == 3 {
return collectionView.dequeueReusableCell(withReuseIdentifier: profileCelId, for: indexPath)
}
return cell
}
}
You can use delegates to implement this.
Below is the code to implement this
protocol ProfileCollectionViewCellDelegate {
func buttonPressedAtIndexPath(inCell: ProfileCell)
}
class ProfileCell: UICollectionViewCell {
var delegate : ProfileCollectionViewCellDelegate?
let profileContainerView: UIView = {
let view = UIView()
return view
}()
lazy var optionsButton: UIButton = {
let btn = UIButton(type: .custom)
btn.setImage(#imageLiteral(resourceName: "Settings"), for: UIControlState.normal)
btn.addTarget(self, action: #selector(handleOptionsButton), for: UIControlEvents.touchUpInside)
return btn
}()
#objc func handleOptionsButton() {
if self.delegate != nil {
self.delegate?.buttonPressedAtIndexPath(self)
}
}
}
For your HomeViewController
class HomeViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout, ProfileCollectionViewCellDelegate {
let profileCelId = "profileCell"
override func viewDidLoad() {
super.viewDidLoad()
setupSwipeView()
}
func setupSwipeView() {
collectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: cell)
collectionView?.register(ProfileCell.self, forCellWithReuseIdentifier: profileCelId)
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: profileCelId, for: indexPath)
cell.delegate = self
return cell
}
fun buttonPressedAtIndexPath(inCell: ProfileCell) {
let indexOfCell = self.collectionView.indexPath(for: cell)
if indexOfCell.row == 3 {
//Do your work here
}
}
}
You can present your ProfileEditViewController, which is styled in your Main.storyboard the following way:
1) Give your ProfileEditViewController a StoryBoard ID. E.g. "ProfileEditViewController" - Some question regarding this is here: What is a StoryBoard ID and how can i use this?
2) Register the UIViewController for the action on the UIButton or offer an appropriate callback functionality.
As your HomeViewController is also your Collection View's datasource, you can easily extend your DataSource method
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell`
Implementation could look like:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if indexPath.item == 3 {
let profileCell = collectionView.dequeueReusableCell(withReuseIdentifier: profileCelId, for: indexPath)
if let _cell = cell as? ProfileCell,
let button = _cell.optionsButton as? UIButton {
button.addTarget(self, action: #selector(handleOptionsButton), forControlEvents: UIControlEvents.TouchUpInside)
}
return profileCell;
}
return cell
}
Make sure that your buttons Action is now also being implemented by your HomeViewController
#objc func handleOptionsButton() {
print("Button pressed")
}
3) Now in HomeViewController.handleOptionsButton you need to provide a functionality to support the transition to that specific Controller with the desired StoryboardID:
let storyboard = UIStoryboard(name: "Main", bundle:Bundle.main)
let controller = storyboard.instantiateViewController(withIdentifier: "ProfileEditViewController")
self.present(controller, animated: true, completion: nil)
let proCell = ProfileCell()
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: self.cell, for: indexPath)
if indexPath.item == 3 {
let profileCell = collectionView.dequeueReusableCell(withReuseIdentifier: profileCelId, for: indexPath)
let button = proCell.optionsButton
button.addTarget(self, action: #selector(handleOptionsButton), for: UIControlEvents.touchUpInside)
return profileCell;
}
return cell
}

How to render UICollectionviewcell's vertically with different cell sizes

I am trying to build a clone of Instagram, and I decided to use a UICollectionViewController that returns 3 different cells and I set the scroll direction to horizontal, and set the pagination to true, so that I can have three different pages in the 2 vertical cells I will be loading 2 other uicollectionviewcell's that are nested 1 for the feed 1 for the dm, I am running into an issue when it comes to hiding the navigation bar when the user gets to the camera because Instagram has the navigation bar displayed for the feed cell and the messaging cell but not for the camera one. Here below is my code for the maincollectionviewcontroller.
import UIKit
import AVFoundation
class MainViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
let cellID = "cellId"
let messageCellID = "messageCellID"
let cameraCellID = "cameraCellID"
var swipeRight = UISwipeGestureRecognizer()
override func viewDidLoad() {
super.viewDidLoad()
let titleImage = UIImageView(image: #imageLiteral(resourceName: "Instagram_logo"))
titleImage.layer.masksToBounds = true
self.navigationItem.titleView = titleImage
setupCollectionView()
setupSwipeGesture()
}
// //Swipe right to get camera
// func setupSwipeGesture() {
// swipeRight.direction = .right
// self.navigationController?.isNavigationBarHidden = true
// let cameraViewController = ViewController()
// cameraViewController.transitioningDelegate = self
// navigationController?.pushViewController(cameraViewController, animated: true)
// }
func setupSwipeGesture() {
print("trying to swipe")
swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(swiped))
self.view.addGestureRecognizer(swipeRight)
swipeRight.direction = .right
}
func swiped(){
print("swipping to get Camera")
self.navigationController?.isNavigationBarHidden = true
let cameraViewController = ViewController()
cameraViewController.transitioningDelegate = self
navigationController?.pushViewController(cameraViewController, animated: true)
}
func setupCollectionView(){
collectionView?.backgroundColor = .white
collectionView?.register(MainViewFeedCellCollectionViewCell.self, forCellWithReuseIdentifier: cellID)
collectionView?.register(MainViewMessagedFeedCell.self, forCellWithReuseIdentifier: messageCellID)
collectionView?.register(MainViewCameraFeed.self, forCellWithReuseIdentifier: cameraCellID)
collectionView?.isPagingEnabled = true
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
scrollToMenuIndex(menuIndex: 0)
}
func goBackToMainPage(){
scrollToMenuIndex(menuIndex: 0)
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 3
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if (indexPath.item == 2){
return collectionView.dequeueReusableCell(withReuseIdentifier: messageCellID, for: indexPath)
}
else if (indexPath.item == 0){
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cameraCellID, for: indexPath)
return cell
}
else if (indexPath.item == 1){
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath)
return cell
}
else{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath)
return cell
}
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
print("\(indexPath.row)")
// if indexPath.row == 0{
// navigationController?.isNavigationBarHidden = true
// return CGSize(width: view.frame.width, height:` view.frame.height )
//}
return CGSize(width: view.frame.width, height: view.frame.height - 70)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
func scrollToMenuIndex(menuIndex: Int){
let index = IndexPath(item: menuIndex, section: 0)
collectionView?.scrollToItem(at: index, at: .centeredHorizontally, animated: true)
}
}
What I did to solve a similar problem was to add the UIScrollViewDelegate, to my UIViewController. Here's an interpretive answer based off of what you provided. Due to the fact that only one UICollectionViewCell appears at a time, this should do the trick. I'm not sure if this is the best way to get it done, but it worked for me:
var visibleCurrentCell: IndexPath? {
for cell in self.collectionView.visibleCells {
let indexPath = self.collectionView.indexPath(for: cell)
return indexPath
}
return nil
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(checkIfCameraIsShowing), userInfo: nil, repeats: false)
}
func checkIfCameraIsShowing() {
if let visibleCurrCell = visibleCurrentCell, let _ = collectionView.cellForItem(at: visibleCurrCell) as? CameraCollectionViewCell {
self.navigationController?.isNavigationBarHidden = true
}
}

pushViewController using uibutton to a UICollectionviewController Programatically Swift

I want to push a UICollectionViewController when i press a uibutton. I have test some and when i press the button it navigates to a blank ViewController.
Root View Controller (CategoryViewController)
class CategoryViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//UIButton
let image = UIImage(named: "menudo") as UIImage?
let button = UIButton(type: UIButtonType.Custom) as UIButton
button.frame = CGRectMake(100, 100, 100, 100)
button.setImage(image, forState: .Normal)
button.addTarget(self, action: #selector(CategoryViewController.action(_:)), forControlEvents:.TouchUpInside)
self.view.addSubview(button)
}
func action(sender: UIButton!) {
let layout = UICollectionViewLayout()
let collectionViewController = MealCollectionViewController(collectionViewLayout: layout)
navigationController?.pushViewController(collectionViewController, animated: true)
}
I want to show this ViewController when i press the uibutton (MealCollectionViewController)
import Foundation
import UIKit
class MealCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
//Creating the CellId for reusable cell
private let cellId = "cellId"
override func viewDidLoad() {
super.viewDidLoad()
//Creating CollectionView
collectionView?.backgroundColor = UIColor.whiteColor()
//setting the cellId reusable to show on screen USE CATEGORY CELL BECAUSE MEALCOLLECTION VIEW IS NOT A CELL
collectionView?.registerClass(CategoryCell.self, forCellWithReuseIdentifier: cellId)
}
//Creating the layout for the cell
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(cellId, forIndexPath: indexPath) as! CategoryCell
return cell
}
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
return CGSizeMake(view.frame.width, view.frame.height)
}
}
If you are Using storyboard then use this code...
let meal: MealCollectionViewController = (self.storyboard?.instantiateViewControllerWithIdentifier("STORYBIARD_CONTROLLER_IDEBTIFIER_NAME"))! as! MealCollectionViewController
self.navigationController?.pushViewController(meal, animated: true)
Use this code -
let mealController = self.storyboard?.instantiateViewControllerWithIdentifier("your controller identifier name here") as MealCollectionViewController
self.navigationController?.pushViewController(mealController, animated: true)

Resources