Embed Material CardTableView in UINavigationController - ios

I am trying to setup a master/detail view with CardTableView as my root and am having trouble implementing
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//code
}
I want to use a self.navigationController?.pushViewController so that the detail view can easily come back to the table view. However when I try to embed this in a Navigation controller I get a strange looking title bar:
This is my view hierarchy:
let tabs = AppPageTabBarController(viewControllers:[InvitedViewController(), CoordinatingViewController(), PastViewController()])
let toolbar = AppToolbarController(rootViewController: tabs)
let navigationController = UINavigationController(rootViewController:toolbar)
let fabController = AppFABController(rootViewController: navigationController)
let snackBarController = AppSnackbarController(rootViewController:fabController)
let navDrawer = MyTeeUpsViewController(rootViewController: snackBarController, leftViewController: NavDrawerContainerController())
self.present(navDrawer, animated: true)
Wondering if there are any alternatives to this approach

By default, UINavigationController shows its own navigation bar above your view controller(s). In your screenshot, it's the large, light-colored bar above your views. If you don't want this, you'll have to set it so when you instantiate the navigation controller:
// You may want to animate it if you hide/show it after it's onscreen
navigationController.setNavigationBarHidden(true, animated: false)

Related

How to properly use didSelectRowAt in splitViewController on compact device in swift?

I'm using a splitViewController to display a master view and a detail view.
When I tap on a row, the detail view updates correctly.
Then, when I'm in portrait view, I collapse the splitview detail view, so that that master list items are shown as follows:
And when I tap on a row, I correctly move to the detail view, as shown:
The problem I'm having is that if I rotate the device in the detail view shown above, while I'm in the detail view, the rotation correctly goes back to the splitView, however, now when I select a row, the delegate method does not update the detail view. It only seems to work if I start out in the splitView and stay in that view, or if I start out in the collapsed view and stay in that. If I rotate, then the delegate method does not seem to work.
I found a prior post, which shows how to use the delegate method to update the detail view using objective C code, using the didSelectRow function. I tried to duplicate this code with the following swift code:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let navigationVC = UINavigationController()
var detailVC = TestsDetailAdvertVC()
if let tests = controller.fetchedObjects, tests.count > 0 {
//if there is, keep track of the test which is selected
selectedTest = tests[indexPath.row]
if let isCollapsed = splitViewController?.isCollapsed {
if isCollapsed {
//solves problem of navigating to the detail view in compact view
// on the iPhone (compact) the split view controller is collapsed
// therefore we need to create the navigation controller and detail controller
detailVC = self.storyboard!.instantiateViewController(withIdentifier: "detailVC") as! TestsDetailAdvertVC
navigationVC.setViewControllers([detailVC], animated: false)
self.splitViewController?.showDetailViewController(detailVC, sender: self)
detailVC.testToEdit = selectedTest
} else {
// if the split view controller shows the detail view already there is no need to create the controllers
// so we just pass the correct test using the delegate
// if the test variable is set, then it calls the showDetail function
delegate?.testToEdit = selectedTest
}
}
}
}
I think that somehow when the one or the other method is used to update the detail view it works, but then when it switches back and forth, it stops working. I wonder if anyone has solved this issue using swift code who could point me to an example.
Note: After some additional searching, I realized that there are a few of delegate methods for the splitViewController, including:
func primaryViewControllerForExpandingSplitViewController:
and
func primaryViewControllerForCollapsingSplitViewController:
and
splitViewController:separateSecondaryViewControllerFromPrimaryViewController:
I've been fiddling around with these methods, but so far haven't been able to get them to work, and I haven't found any posts that show examples of how they are used.
Thanks.
I figured out how to make the detail view update properly, using an answer from a prior post at:
In UISplitViewController, can't make showDetailViewController:sender: push onto detail navigationController
my code to solve the problem is updated using swift code:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
var detail = UINavigationController()
var testVC = TestsDetailAdvertVC()
if let tests = controller.fetchedObjects, tests.count > 0 {
//if there is, keep track of the test which is selected
selectedTest = tests[indexPath.row]
if let isCollapsed = splitViewController?.isCollapsed {
if isCollapsed {
//in collapsed view, the correct detail view controller is not
//yet substantiated, so we need to substantiate it
testVC = self.storyboard?.instantiateViewController(withIdentifier: "detailVC") as! TestsDetailAdvertVC
detail.setViewControllers([testVC], animated: true)
testVC.testToEdit = selectedTest
} else {
//in expanded view, the correct view controller needs
//to be identified, using the appropriate view controller for
//the splitview controller
let vc = self.splitViewController?.viewControllers[1]
//which is a navigation controller
if vc is UINavigationController {
detail = vc as! UINavigationController
//which we then use to identify the correct detail view
testVC = detail.viewControllers.first as! TestsDetailAdvertVC
testVC.testToEdit = selectedTest
}
}
}
}
self.splitViewController?.showDetailViewController(detail, sender: self)
}
The key solution is that on the collapsed splitviewcontroller, the detail view has to be instantiated form the storyboard. However, on the expanded splitviewcontroller, the detail view has to come from the expanded navigation controller. Then when I rotate the correct detail view controller updates correctly.

Regarding Side menu with Tabbarcontroller

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.

UIPageViewController in UINavigationController popping issue

Short story:
Going from UIPageViewController (that presents proper DetailViewController) to UITableViewController, then changing (on didSelectRowAtIndexPath) the DetailViewController of the UIPageViewController and navigationController?.popViewControllerAnimated(true), displays proper UIPageViewController with changed DetailViewController but the whole view is moved down by the height of the navigationBar. Clicking on the screen sends it under the bar (where it should be).
Long story:
I embedded UIPageViewController into UINavigationController. Navigation bar translucent
I created a DetailViewController in my storyboard with a scrollView inside it.
I created custom function in the UIPageViewController to return desired UIViewController
func viewDetailViewController(index: Int) -> DetailViewController? {
if let storyboard = storyboard, page = storyboard.instantiateViewControllerWithIdentifier("DetailViewController") as? DetailViewController {
// Setting the page variables that it stores
return page
}
return nil
}
I set up a code (also in UIPageViewController):
override func viewWillAppear(animated: Bool) {
if let viewController = viewDetailViewController(currentIndex) {
setViewControllers(
[viewController],
direction: .Forward,
animated: false,
completion: nil)
}
}
Then I setup an bar button item to and in the storyboard I connected it to so it perform segue to UITableViewController. I want to pop a viewContorller on cell click so:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
self.pageViewController.currentIndex = indexPath.row
navigationController?.popViewControllerAnimated(true)
}
When the view is popped the new view of the UIPageViewController is replaced, the pages work well and everything is great except one thing. The whole view is moved down by the height of the navigationbar. What's even more strange is that (just) tapping on the screen sets the scrollView under the navigationbar (where it should be)
I have also noticed that not only the scrollView is moved down, but what is actually moved down is UIView that contains an UIView that contains the scrollView.
What might be causing this?

Presenting a new view controller from selected table row modally

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let memeShowViewController = self.storyboard!.instantiateViewControllerWithIdentifier("ShowMeme") as! MemeShowViewController
memeShowViewController.memeImage = appDelegate.memes[indexPath.row].memeImage
self.navigationController!.presentViewController(memeShowViewController, animated: true, completion: nil)
}
So I have a tableview that has a nav controller embedded in it and when I present the memeShowViewController modally I was wondering why the view of the memeShowViewController has a black background color when I didn't change it to be black.
In storyboard:
In simulator
Right now I'm just adding a navigation bar to the segue-ed view controller, I was wondering if there is a better way to do as the only functionality I need from the navigation bar is for the done button to segue back to the tableView.
The background window has a black background so if your app doesn't cover any part of the window (or alpha = 0) you'll see that black background.

Proper segue flow

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)

Resources