I have slide menu based on tableView. Also I have tab bar created on IB.
First item on tab bar is like Home page. By defaut when run app that item display home screen. When select one of items from menu it should open on the same view as Home page.
//part of the code from menu item responsible to select Home page tab bar item
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
ContainerVC.tabBarViewController?.selectedIndex = 0
}
//viewWillAppear function on separated view controller
override func viewWillAppear(_ animated: Bool){
super.viewWillAppear(true)
let vc = self.storyboard?.instantiateViewController(withIdentifier: "DynNews")
self.navigationController?.pushViewController(vc!, animated: true)
}
This works only once, when start app. Later on app showing up just Home page. This is because tab bar load view only once and then selecting tab index does not call viewWillAppear but I do not know how to solve this.
You can achieve this functionality by number of different approaches.
To navigate inside a tabbar you should embed your controllers in a navigation controller.
This image will help you understand.
Further more you can take help from this link and this link. Also you can check out number of libraries on cocoacontrols and github for the require functionality. For better understanding I would recommend apple documentation.
Related
I have a view controller which has a table view and in the didSelectRowAt indexPath I instantiate the destination view controller, embed it into a navigation controller and present it... here is some code
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let destVC = DetailVC(frame: self.view.frame)
//passing data to the destVC ...
destVC.modalTransitionStyle = .partialCurl
let nav = UINavigationController(rootViewController: destVC)
present(nav, animated: true, completion: nil)
}
Working like a charm so far. When the detail VC appears everything's great, the tableView works perfectly, the leftBarButtonItem dismisses the detailVC as it should, but whenever I press anywhere on the upper side of the screen the detail view somehow automatically dismisses itself, which I don't want. I'm gonna leave a link to an image to see exactly what part of the screen automatically enables the dismiss function:
http://prntscr.com/kaibxg
I've been struggling with this and I didn't find any solution. I don't know why this is happening. When I use the pushViewController function, the detail VC is all right and is not popping itself out, but the thing is I really need to use the .partialCurl transition animation. I tried to find a way to somehow use .partialCurl when pushing the VC but I didn't find anything about that. Any help, answer, question is more than welcomed and appreciated. Thank you all in advance.
I have a scenario like I am using AKSideMenu and Tabbarcontroller both have same items like home, profile etc means home can access from tab bar as well as from side menu.My problem is that access from tab bar is fine but if I select Home from side menu then tab bar item is select correctly but view controller along with tab bar is not correct(selecting home from side menu display selected home tab bar but view controller is profile view or some random).
Please find code below.
public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
self.sideMenuViewController!.contentViewController = nil
switch indexPath.row {
case 0:
self.sideMenuViewController!.setContentViewController(getLandingStoryBoard().instantiateViewController(withIdentifier: "MyTicketsViewController"), animated: true)
self.tabBarController?.selectedIndex = 0
self.sideMenuViewController!.hideMenuViewController()
case 1:
self.sideMenuViewController!.setContentViewController(getHistoryStoryboard().instantiateViewController(withIdentifier: "BiddingHistoryViewController"), animated: true)
self.tabBarController?.selectedIndex = 1
self.sideMenuViewController!.hideMenuViewController()
}
}
I think your issue is you're setting the content view controller to a new vc instantiated from the storyboard instead of setting it to the selected view controller of the tab bar controller.
try
self.tabBarController!.selectedIndex = 0
self.sideMenuViewController!.setContentViewController(self.tabBarController!.selectedViewController!, animated: true)
Either that or the content view controller should always be the tab bar controller.
I made a view controller with a UISearchController and a UITableView . There are two different kind of search you can select from the search scope buttons : groups and people. Both searches work and show results on the table. However, if you click on each cell they should direct you to different dynamic pages (a dynamic group page or a dynamic person profile page). The one for groups works, while the one for profiles doesn't. Meaning whenever I click on the a person cell from the results that I got, nothing happens and I get the following warning printed on the console :
Warning: Attempt to present <MyProject.profileView: 0x13e9df000> on <MyProject.SearchPage: 0x142a1d8f0> which is already presenting <UISearchController: 0x142a1f7c0>
If you have any idea why this could be happening it'd be really appreciated if you could let me know.
EDIT : Here's the function that should link the cell to the different view controllers :
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if self.searchForGroups {
let detailCell:PFObject = self.filteredGroups.objectAtIndex(indexPath.row) as! PFObject
let vc = self.storyboard!.instantiateViewControllerWithIdentifier("DynamicCellView") as! DynamicCellView
vc.GroupId = detailCell.objectId!
self.presentViewController(vc, animated: false, completion: nil)
}else{
//Link to use profile
let user = self.peopleResults[indexPath.row]
let vc = self.storyboard!.instantiateViewControllerWithIdentifier("ProfileView") as! profileView
vc.profileId = user.objectId!
self.presentViewController(vc, animated: true, completion: nil)
}
}
I was having the same warning and this fixed it for me. You need to stop presenting the search controller so you can present other controller while you are leaving the view.
override func viewDidDisappear(_ animated: Bool) {
if SearchController.isActive == true {
SearchController.isActive = false
}
}
I was figuring the same original issue and none of this resolved it for me.
Actually you just have to dismiss the UISearchController as it is said because it is already presenting to the current view.
So, when you want to launch your action, you just have to call this :
if searchController.isActive {
self.searchController.dismiss(animated: false) {
// Do what you want here like perform segue or present
}
}
Hope this will help!
I hit the same error while trying to perform a segue when tapping on a search result. This isn't an ideal workaround but dismissing the searchController before performing the segue fixed it for me:
self.searchController.dismiss(animated: false) {
self.performSegue(withIdentifier: "<YOUR SEGUE IDENTIFIER>", sender: cell)
}
I'm not sure if the above answers worked properly in previous version but in swift 5, calling dismiss will cause the segue to trigger properly but the search bar will remain active and when they dismiss the triggered segue (come back to the search page) the search bar will look active but the results will not be.
Also dismissing from viewDidDisappear() did not work properly. Here's how I did it.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//Do some stuff here
if searchController.isActive{
searchController.isActive = false
}
performSegue(withIdentifier: "<yourSegueIdentifierHere>", sender: nil)
}
Dismissing UISearchController (proposed in this thread in dozen different ways) is a working solution. One more workaround I've found is just having
definesPresentationContext = true
in viewDidLoad() of a View Controller having UISearchController. This workaround is better in a way the once you navigate back, UISearchController is still showing the search results.
Without the code is kind of difficult to help you. That error may be happening because you are breaking the view controller hierarchy.
The message is saying that you have 3 view controllers involved:
SearchPage is presenting UISearchController
profileView is not yet presented but should be presented on UISearchController or should replace it (For that UISearchController should be dismissed first)
Take in mind that a view controller can present only 1 view controller at the time but it can have several child view controllers (such as a navigation controller).
For more information you can check: https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/TheViewControllerHierarchy.html#//apple_ref/doc/uid/TP40007457-CH33-SW1
Just as a comment, its a good coding practice to start your class name with a uppercase letter ('ProfileView' instead of 'profileView')
I am struggling to create an app which consists of a slide out menu, as well as multiple tabbed views once the user has clicked on a menu item.
Basically the app is a tutorial app - the different menu items will be the different sections, and each section has multiple sub-sections that i would like the user to be able to scroll through in a tabbed fashion. Example: Menu item: 'Cooking' - and when user clicks on it I want him/her to be able to scroll through tabs such as 'baking', 'barbeque' and 'fried food' etc.
What is the best way to do this? So far I have successfully created a slideout menu using a swRevealController, also the slideout menu enables me to navigate to different view controllers when I click a menu Item.
Now what would be the best way to add some subsections?
Ultimately I want to create an iOS equivalent of an android 'drawer with swipe tabs'.
Currently my storyboard looks like this. How do I add multiple views (accessed via tabs) for each menu item?
Simple method is to subclass UITableViewController.
Setup your different cells and then override didSelectRowAtIndexPath, example :
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
switch (indexPath.row)
{
case 0:
let storyboard = UIStoryboard(name: "LoginScreen", bundle: nil)
let controller = storyboard.instantiateInitialViewController() as UIViewController!
self.presentViewController(controller, animated: false, completion: nil)
break;
case 1:
//calling popup
let SB = UIStoryboard(name: "PopUpStoryboard", bundle: nil)
let controller = SB.instantiateViewControllerWithIdentifier("aboutPopup")
self.presentViewController(controller, animated: true, completion: nil)
// discard menu
self.revealViewController().revealToggleAnimated(true)
break;
default:
break;
}
}
A popup would usually be displayed on mainscreen so you discard the slideout menu, a regular view is just presented on top of it.
I am looking for the best-practice method of doing the following:
I have two TabBarController views embedded in a NavigationController and one which I don't want to include as a tab but is embedded in a NavigationController:
FeedView (TableViewController)
VenueView (CollectionViewController)
SelectView (ViewController)
In VenueView (2), I have the following code to bring up SelectView (3):
override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
let selectVC: SelectViewController! = self.storyboard?.instantiateViewControllerWithIdentifier("selectVC") as! SelectViewController
selectVC.currentVenue = venueItems[indexPath.row]
presentViewController(selectVC, animated: true, completion: nil)
}
This segue works, however SelectView(3) doesn't have a navigation bar at the top although it is embedded in a separate NavigationController. If I hook it up to the other NavController in the IB, it adopts/becomes the third tab in the BarTabController. I don't want that.
How do I hook it up so that there is a NavBar (with a back button that will go back to either view) but no Tab?
Also, there is a button on SelectView(3). When this button is tapped I'd like it to segue to FeedView(1) - while persisting some data ie 'pushing into the feed'. What kind of segue should I use for this? I've tried many combinations and ran into some strange bugs and I find View management very confusing.
Storyboard image below for reference
Views are in order from top to bottom (1-3):
In order to do this you need to fix your problem, you need to present the navigation controller which contains SelectView but not SelectView itself as you do now.
You should set a storyboard identifier to your 3'rd navigation controller and apply this change:
let selectNavigationController = self.storyboard?.instantiateViewControllerWithIdentifier("selectNavigationController") as! UINavigationController
let selectVC = selectNavigationController.topViewController as! SelectViewController
selectVC.currentVenue = venueItems[indexPath.row]
presentViewController(selectNavigationController, animated: true, completion: nil)