Transition from Modal View to Next VC in a TabBar and NavBar - ios

I'm using Swift 2 and xcode 7.1.1.
My app is a tabbar + navigationbar based application.
What I'd like to do:
From my first viewcontroller (CollectionVC) I have a collectionview of images(tabbar at bottom and navbar at top). When you select an image, I transition programmatically to a modalviewcontroller (ImageZoomVC) that allows them to zoom on the image (no tabbar or navbar). From the ImageZoomVC I want to transition programmatically to the UserProfileVC. The UserProfileVC should have the tabbar and navbar like the first view. The navbars back button should also take us back to the ImageZoomVC.
This workflow is similar to facebook. When you select an image, you go to a black screen with just that image and some more info. You can click on anyone tagged in the image and it will push their profile onscreen with the tabbar and navbar back in place.
The Problem:
Once in the ImageZoomVC, I can't transition to the UserProfileVC without losing the tabbar and navbar. I've been able to add a navbar programmatically but there is no back button, and setting a back button hasn't worked. Also, there is no tabbar.
Code:
From my CollectionVC, I transition to the ImageZoomVC from my collectioncell like this:
#IBAction func PhotoButtonPressed(sender: UIButton) {
let imageZoom = ImageZoomVC()
imageZoom.showFrom(self.parentView!)
}
Here is the showFrom function that presents the ImageZoomVC modally. This code is inside the ImageZoomVC:
public func showFrom(viewController: UIViewController) {
//Some stuff here, edited for length
viewController.presentViewController(self, animated: false) {
UIView.animateWithDuration(ImageZoomVC.TransitionAnimationDuration,
delay: 0,
options: [.BeginFromCurrentState, .CurveEaseInOut],
animations: {
[weak self] in
self?.collectionView.alpha = 1
self?.collectionView.transform = CGAffineTransformIdentity
},
completion: {
[weak self] finished in
self?.view.userInteractionEnabled = finished
}
)
}
}
This is the code I'm attempting to use to transition to the UserProfileVC with navbar and tabbar. This doesn't work. It will present the VC, but there is no tabbar or back button.
func userSelected (sender: UIButton) {
let vc = self.presentingViewController?.storyboard?.instantiateViewControllerWithIdentifier("User Profile") as! UserProfileVC
let newNav = UINavigationController(rootViewController: vc)
newNav.navigationBar.barTintColor = UIColor().specialPurple()
newNav.navigationBar.translucent = false
self.presentViewController(newNav, animated: true, completion: nil)
}
A couple notes: The ImageZoomVC doesn't exist in storyboard. It is called and instantiated programmatically.
The ImageZoomVC is based off Agrume from Github found here:
https://github.com/JanGorman/Agrume
I'd like to push the UserProfileVC like facebook does. This current code presents it from the bottom. The code pushViewController is not recognized here in xCode.
Let me know what you think. All thoughts are welcome. Thanks.

Related

Cannot Dismiss EKEventViewController in Landscape View

When I open a calendar event in my app using EKEventViewController using the code below it correctly displays my event in a modal view.
let eventModalVC = EKEventViewController()
eventModalVC.event = myEvent
eventModalVC.allowsEditing = true
present(eventModalVC, animated: true, completion: nil)
In portrait mode (using iOS 15) I can dismiss the modal using a swipe-down gesture. However, when I change to landscape orientation, the gesture does not work, and there is no back or cancel button either (like there is for the EKEventEditViewController). I could not find any property of the view controller that would enable me to dismiss it.
So the user is either stuck or has to turn the device into portrait mode. How can I fix this?
I was hoping that the EKEventViewController offers a similar convenient and intuitive way to dismiss it in landscape view as it does in portrait view but have not had any luck.
To get the back button I now enclosed my modal view in its own navigation controller. That reveals a "Done" button (as well as a delete button). Neither button dismisses the view. That can be done by implementing EKEventViewDelegate in the parent view controller.
let eventModalVC = EKEventViewController()
eventModalVC.event = myEvent
eventModalVC.allowsEditing = true
let nc = UINavigationController(rootViewController: eventModalVC)
eventModalVC.delegate = self
present(nc, animated: true, completion: nil)
...
// EKEventViewDelegate
func eventViewController(_ controller: EKEventViewController, didCompleteWith action: EKEventViewAction) {
if action == .done {
controller.dismiss(animated: true)
}
// handle deletion as well if needed
}

Keep Tabbar when click on central button

I am using following layout design
but when i click on central circular button it's cover the whole screen ... i want to make tabbar visible on every click ...
I try to open ViewController as a sub view with following code
guard let StoreVC = self.storyboard?.instantiateViewController(withIdentifier: "StoreVC") else { return }
StoreVC.view.frame = self.view.bounds
self.addChild(StoreVC)
self.view.addSubview(StoreVC.view)
StoreVC.didMove(toParent: self)
but its cover the entire screen including tabbar ..
i try following code but still does't work as expected ...
guard let StoreVC = self.storyboard?.instantiateViewController(withIdentifier: "StoreVC") else { return }
self.definesPresentationContext = true
StoreVC.modalPresentationStyle = .overCurrentContext
self.present(StoreVC,animated: true, completion: nil)
Embedding it in a navigation controller also does't work ...
This circular button is not the part of Tabbar but i want it to act like a tabBarItem ...
if i make it part of tabbar it upper part not click able ...
just like explain in this question TabBarController adding custom button not clickable issue

questions about segue to a viewcontroller

From the iphone system APP “Contacts”, in the “All Contacts” GUI and click “Add”, it will segue to “New Contact” GUI. Then from the “New Contact” GUI and add “new” item then click “Done”, it will seuge to the contact detail GUI(screenshot image 3). The issue is that: I used “Show(push)” to segue to image 3 from “Done” button,
but the NavagationItem in the left corner displayed as “ back to New Contact “ rather than “back to All Contact”.
I attached the screenshot to describe the issue as bleow:
screenshot
I tried two ways:
way 1: pop the vc which matches the image2. The isssue is that New Record page will jump to image1 first, then jump to image3.
if let nav = self.parentViewController as? UINavigationController {
if let vc0 = nav.childViewControllers.last as? AddRecordTableViewController {
nav.popViewControllerAnimated(true)
}
}
performSegueWithIdentifier(Constants.SegueAddRecordVCToViewRecordVC, sender: nil)
way 2:
used the removeFromParentViewController to discard the vc matches image2. The issue is that the Navagation bar button in the left corner still displayed as “
if let nav = self.parentViewController as? UINavigationController {
if let vc0 = nav.childViewControllers.last as? AddRecordTableViewController {
vc0.removeFromParentViewController()
}
}
performSegueWithIdentifier(Constants.SegueAddRecordVCToViewRecordVC, sender: nil)
Why dont you try using self.dismissViewControllerAnimated(true, completion: {}); when "Done" is pressed.

conditional showing of uitoolbar

I have a UIViewController that is presented in two ways, either modally or pushed on top of a navigation controller stack. The UIViewController contains a UITableView and a UIToolbar. When presented modally, i needed a way of showing a title for the ViewController, so I added in another UIToolbar, topToolbar. My problem is, whenever I push the UIViewController, I don't need topToolbar anymore, since the navigation tabbar already shows the title. When I set topToolbar's hidden property to true, however, my UITableView is not bound to the bottom of the navigation tab bar and there's space between the UITableView and the navigation tabbar, which doesn't look so good. I tried to call removeFromSuperview() on topToolbar instead of setting its hidden property to true, but that didn't work out, and topToolbar appeared under the navigation bar, and now i have two titles instead of one. Any idea on how this can be done? I can't add pictures, but here's my code for manipulating the appearance of the UIViewController based on whether it's presented modally or pushed on top of the navigation stack:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
if itemBought != nil {
cart.items.append(itemBought!)
}
totalView.layer.borderColor = UIColor.grayColor().CGColor
totalView.layer.borderWidth = 0.5
totalLabel.text = "$" + String(format: "%.2f", cart.getTotal())
if let navBar = self.navigationController?.navigationBar {
//hide toolbar and tabbar
topToolbar.removeFromSuperview()
self.tabBarController?.tabBar.hidden = true
//hide shop button
var bottomItems: [UIBarButtonItem] = bottomToolbar.items as! [UIBarButtonItem]
if let index = find(bottomItems, shopToolbarButton) {
bottomItems.removeAtIndex(index)
}
bottomToolbar.items = bottomItems
}
}
I should also mention that i have a constraint on the UITableView that's basically: distance between UItableView.top and Top Layout Guide.Bottom is <= to the height of topToolbar, which is 44.
Any ideas?
When you present the View Controller modally, why not put it in a UINavigation Controller?
let navigationController = UINavigationController(rootViewController: myViewControllerInstance)
self.navigationController?.presentViewController(navigationController, animated: true, completion: { () -> Void in
//do something here when animation is complete if you want
})

MMDrawerController can't close drawer

I'm trying to use MMDrawerController in my application, but I can't get the side drawer to close with gestures on the center view. I've used MMDrawerController somewhere else in my app with great success, but can't figure out why its not working in this case.
The top-level View Controller is a UINavigationController, whose default view controller is the MasterViewController (source below). This class extends MMDrawerController and configures the view for what I want (center and right, close gestures, max width). The center view has a button that opens the drawer. Once the drawer is open I can't close it with gestures on the center view. I added a button to the drawer and it can close the drawer programmatically, but I need to be able to tab/pan on the center view.
class MasterViewController: MMDrawerController {
override func viewDidLoad() {
let centerView = storyboard!.instantiateViewControllerWithIdentifier("CenterControllerName") as? CenterControllerType
super.setCenterViewController(centerView, withCloseAnimation: false, completion: nil)
let drawer = storyboard!.instantiateViewControllerWithIdentifier("Drawer") as? DrawerType
super.rightDrawerViewController = drawer
super.setMaximumRightDrawerWidth(200, animated: true, completion: nil)
super.closeDrawerGestureModeMask = MMCloseDrawerGestureMode.PanningCenterView | MMCloseDrawerGestureMode.TapCenterView
}
}
The function to open the drawer:
#IBAction func drawerButtonPressed(sender: AnyObject) {
drawer?.openDrawerSide(MMDrawerSide.Right, animated: true, completion: nil)
}
I was able to work around this by placing a ContainerView as the only object in my view and then configuring the MMDrawerContainer from my ViewController. It doesn't seem like the right answer but everything looks and functions right from the user's perspective.
Ok so I run into the same issue, and I am almost sure that it comes from this:
Ok, the VC1 (with the star) is our application Home, the VC2 is the left drawer, and the VC3 is the DrawerController.
During a long time I tried to put gesture functions in the VC1 and VC2, but only opening in the VC1, and closing in the VC2 would work.
The functions I used in VC1:
let rightSwipe = UISwipeGestureRecognizer(target: self, action: Selector("showDrawer:"))
rightSwipe.direction = .Right
view.addGestureRecognizer(rightSwipe)
...
func showDrawer(sender: UISwipeGestureRecognizer) {
if let m = mmdc {
if !m.isLeftDrawerOpen() {
m.toggleDrawerSide(MMDrawerSide.Left, animated: true, completion: nil)
}
}
}
And the same one in VC2 but with the LeftSwipe and closeDrawer.
The solution is tu put both of these functions and gestures recognizer in the VC3 (DrawerController).
The problem is coming from the fact that your gestures are defined for a given VC, but when you open the drawer, it changes the current VC by a new one, and the previous VC is just displayed but can't be interactif with. By putting things in the parentVC of VC1/VC2 it solves the problem.

Resources