Hi I have implemented a custom animated push when my collection View Cell is tapped. The issue I'm having is that when this view controller is pushed forward, my custom segmented controller is on top of it still. Here is my code for my push:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let vc = PopUpCellViewController(nibName: "PopUpCellViewController", bundle: nil)
let cell = collectionView.cellForItem(at: indexPath)
sourceCell = cell
self.navigationController?.pushViewController(vc, animated: true)
}
Let me know if you can help me put this Segmented control below my "PopUpCellViewController" when it is called.
You are probably adding your custom segmented controller as a subview to the navigation bar. Never do that: you must not add any subviews to a navigation bar. Instead, make the segmented controller your view controller's navigationItem.titleView. It will then occupy the center of the navigation bar, but only in that one view controller (not after the push).
Related
I have a UICollectionView with horizontal scrolling direction.
It has a button. On that button click i want to show a list tableView. My question is where should i implement table view delegate method,
in BasicVC, where i create collectionView,
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let c = collectionView.dequeueReusableCell(withReuseIdentifier:"cell", for: indexPath)
let btn = c.viewWithTag(9) as? UIButton
btn?.layer.masksToBounds = true
btn?.layer.cornerRadius = (btn?.frame.size.height)!/2
btn?.backgroundColor = getRandomColor()
return c
}
or in collectionCell class.
class PlayerHeaderCell: UICollectionViewCell{
#IBOutlet weak var btn: UIButton!}
tableView delegate methods needs to implemented in UICollectionViewCell like so
class PlayerHeaderCell: UICollectionViewCell, UITableViewDataSource, UITableViewDelegate{
#IBOutlet weak var btn: UIButton!
#IBOutlet weak var tableView: UITableView!
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")!
return cell
}
}
It sounds like you want a table view to popup on top of the collection view like a drop down menu right? If you're wanting to have a table view that is displayed over top your current view, I'd recommend creating a new view controller for it in your story board that contains the table view, and then presenting that controller on top of the current view. The result would be a table view floating wherever you want on top of your collection view.
Unlike what the other answer said, do NOT make the collection cell the table view delegate, it just doesn't make sense unless you want a different table view for every cell, in which case you should do this and set the delegate to be the selected collection cell.
To implement the popup table view:
Create a view controller in storyboard
Create a new table view, place it INSIDE the new view controllers default view (the default view is used as the background but will be invisible.)
Set view controller's presentation to be Over Content
Set the new view controllers background view to be completely transparent by changing its color
Ctrl drag from your previous view controller to your new view controller and create a modal segue, give it some identifier string "id".
Call performSegue with the ID you set will cause the table view to appear as it is in the new view controller you created.
The advantage to this approach is that your table view can be designed in it's view controller and wont clutter up the original view controller in a storyboard. Just my thoughts, you seem to be doing things programatically so I'm not sure if it's suitable to your use case but I hope it helps.
It depends on where you are showing the tableview. I mean when you tap button, if you are navigating to a new controller with tableview, the delegate should be in the new controller. Or if you are showing the tableview in the same controller, the delegates will be in BasicVC. I think the collection cell has only the button.
This is my understanding. Someone please correct if I am wrong.
I've created a view controller that has a table view embedded in it and in each section of the table I have a cell containing a horizontal collection view. This is what it looks like. The collection view delegate is hooked up to the table view cell and the table view delegate is hooked up to the main view controller.
I want to segue on a cell tap to a new view controller using the navigation controller's push method and pass data from the collection view cell to the new view controller. However, I can't call that navigation controller's push method from inside my collection view's didSelectItem function as that is nested inside my table view cell and not the actual view controller. Some help would be appreciated, thank you!
This is the main view controller's cellForItem function
class SearchController: UIViewController, UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ExploreRow", for: indexPath) as! ExploreRow
let category = classTypes[indexPath.section]
cell.configureCell(type: category)
return cell
}
}
and this is the code within the table view cell's didSelectItem for the collection view cell
class ExploreRow: UITableViewCell, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("Selected \(indexPath.row)")
}
}
The print function works fine but I can't call the navigation controller to push the new view controller from inside that table view.
Implement a delegate protocol or call-back closure from your table view cell to the table view controller. Then you have:
CollectionViewCell tapped
TableViewCell is CollectionView's delegate - it processes the tap
In didSelectItem, TableViewCell tells TableViewController which CollectionViewCell was tapped
TableViewController handles it from there
I'm trying to push a View Controller from a TableView displayed inside a UiViewController that is included in a UITabBarController (it's more simple that it looks...)
The View Controller is pushed BUT the UITabBar is hidden by this view controller, and I'd like to keep this UITabBar displayed.
I tried a lot of things, unsuccessfully.
Here is my code:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let v = UIViewController()
v.view=UIView(frame: CGRectMake(0,0,self.view.frame.size.width,200))
v.view.backgroundColor=UIColor.redColor()
v.hidesBottomBarWhenPushed = false
self.tabBarController?.navigationController?.hidesBottomBarWhenPushed = false
self.tabBarController?.navigationController?.pushViewController(v, animated: true)
}
Any hint will be really appreciated.
Regards,
I have a Tab Bar Controller setup. When the user selects a tab, it takes them to a UIViewController. Currently I have a UITableView setup in this View Controller. What I would like to do is, upon selecting a cell from TableView1, I'd like to have a "push" effect where TableView2 comes in from the right side of the screen, and take over.
I've found the following question, similar to mine:
UITableView segue within the same ViewController
One of the suggestion is exactly what I want to achieve, however I could not get it to have that slide effect.
What I've done is added two UITableViews, then tableView1.hidden = true in viewDidLoad.
Then in code:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
var cell: UITableViewCell!
if tableView == tableView1
{
// Dequeue the cell to load data
cell = tableView.dequeueReusableCellWithIdentifier("ID1", forIndexPath: indexPath)
....
}
else if tableView == tableView2
{
// Dequeue the cell to load data
cell = tableView.dequeueReusableCellWithIdentifier("ID2", forIndexPath: indexPath)
....
}
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
if tableView == tableView1
{
tableView2.hidden = false
tableView1.hidden = true
playlistVideosTableView.reloadData()
// Deselects the row
tableView1.deselectRowAtIndexPath(indexPath, animated: true)
}
}
However, it doesn't have that "slide effect" and makes the tableview appears instant.
I could make another UIViewController with the second tableview but I don't want to make my Tab Bar disappear.
How can I achieve this, and how can I ensure the ensure gets back to the first UITableView?
Thanks
I would recommend to simply create another UIViewController that has a UITableView, so preferably a UITableViewController.
Then in tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) you call a segue to the new ViewController. This will give you the desired effect and is a cleaner solution as well.
You will not lose your TabBar either with this solution if you embed all ViewControllers in this tab into a NavigationController.
EDIT: sample code
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
performSegueWithIdentifier("editSpecialStage", sender: tableView.cellForRowAtIndexPath(indexPath))
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let indexPath = self.tableView.indexPathForCell(sender as! UITableViewCell)!
let secondViewController = segue.destinationViewController as! SecondViewController
}
And in the Storyboard you have a NavigationController as the first ViewController from the TabBar. Then the first ViewController and then the second, connected via push segue.
I could make another UIViewController with the second tableview but I don't want to make my Tab Bar disappear.
Why will your tab bar disappear? It wouldn't if you used a UINavigationController!
Just do what I say, alright?
First create that new view controller and connect the two VCs with a show segue
First VC -show-> Second VC
Now the whole picture would look like
Tab Bar VC -view controllers-> First VC -show-> Second VC
Now modify this to
Tab Bar VC -view controllers-> Navigation Controller -root vc-> First VC -show-> Second VC
Now the segue will slide the Second VC to the left and your tab bar won't disappear!
I have a tableView with identical cells. After selecting one of them I would like to open another ViewController.
I tried this code:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: IndexPath) {
let destination = EditViewController()
navigationController?.pushViewController(destination, animated: true)
}
but it didn't open another ViewController.
Can You give me a hint?
Just go inside you storyboard, Select you initiate view controller, Then click on Editor > Embedded In and select Navigation controller, Then Your code will be work. This mean you have set the navigation stack for your view controllers from initial view controller.
Most probably you just don't have the navigationController there - use rather present to show the viewController:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: IndexPath) {
let destination = EditViewController()
self.present(destination, animated: true, completion: nil)
}
Or if you want the viewController to be pushed, make sure that you embed the tableViewController into a UINavigationController.