Swift ContainerView UI gesture not working - ios

I have a View including a Container View which renders ViewControllers (Based on selected tab in TabBar)
When I try to click on the button (Which has a gesture/target event) it does not output anything in the console. UI Interaction is enabled on all views.
That's how I include the ViewController into the ViewContainer
let windowView = view.viewWithTag(1)
let contentView = view.viewWithTag(2)
let loginView = storyboard!.instantiateViewController(withIdentifier: "loginView")
currentView = loginView.view
contentView?.addSubview(loginView.view)
Is there anything I'm missing?

I got it working, I created two container views with their child views, and now show them based on the selected tab.

Related

Embed view controller inside container view based on selection from tableview

I'm trying to change the content of my container view based on what has been chosen from TableViewController and I'm out of an idea.
The structure in my storyboard looks like this:
Currently, my container view has embed segue with Table View and that's working great. Now after select something from Table View for example Map I want to display MapViewController inside container view and keep my header and footer. How can I do this?
First disable the segue form your container view to a DestinationViewController in your storyboard.
Now load your viewController object based on your previous tableViewController selection.
//this controller will be change on tableView selection make your own logic here.
let controller = storyboard!.instantiateViewController(withIdentifier: "Second")
addChildViewController(controller)
//Set this value false if you want to set Autolayout programmatically or set it true if you want to handle it with `frame`
controller.view.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(controller.view)
controller.didMove(toParentViewController: self)

How can I change the color/put things behind my ViewControlller's view (swift)?

First, an image:
I made it so you can drag the view controller view with your finger (which I have already done), but I want to know:
How to change the black color to another color
How I can put an image behind the view (I want to make it so if you drag the view you'll see a picture).
How do I do this? I figure I'll need to place another view directly behind this one maybe and then make make current view controlller a sub view?
You can set an image as the background of your ViewController by either changing the class of your ViewController's main view from UIView to UIImageView in Storyboard and setting the image to that ImageView's image property or by adding a UIImageView to the ViewController that has the same size as view.
By "background color", I think you mean the black color that shows when you drag the VC away, right?
That is the color of the UIWindow that you VC is running in. It's kind of the superview of every view.
To change the windows color, simply go to your AppDelegate.swift and change change it:
window?.backgroundColor = .red
To add a background image, you just need to add a UIImageView as a subview of window.
if let window = self.window
let imageView = UIImageView(frame: window.frame)
imageView.image = ...
window.addSubview(imageView)
}
If you don't want to deal with subviews and only use viewcontrollers, you can try to present a draggable viewcontroller over a normal (fixed position) viewcontroller. You can do it like this (call this code from the normal view controller to present the draggable view controller over itself):
let storyboard = UIStoryboard(name: "Main", bundle: nil)
// Set the draggable controller's identifier in Main.storyboard
let dragController = storyboard.instantiateViewController(withIdentifier: "DragController")
// Present the draggable view controller over the current one
dragController.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
dragController.modalTransitionStyle = UIModalTransitionStyle.coverVertical
self.present(dragController, animated: true, completion: nil)
Use this code, and then set the background image of the normal view controller. Hope this helps :)

Presenting child view controller inside UIPageController's current page

I have a page view controller that transitions between view controllers using the normal UIPageViewController methods. Inside one of the presented view controllers (let's say the current view controller), I add a child view controller into a subview called containerView like so:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let child = storyboard.instantiateViewController(withIdentifier: "child")
self.addChildViewController(child)
child.view.frame = self.containerView.bounds
self.containerView.addSubview(child.view)
child.didMove(toParentViewController: self)
The view controller is presented inside the containerView, however it is only semi-interactive. For example, let's say the child view controller has a slider that updates a label with the slider's value. When sliding the slider, the slider will move visually inside the containerView, but won't update the label (the IBAction connected to the slider doesn't run). This behavior worked correctly when the view controller was presented normally (full screen using normal segueing).
Any ideas?
Seems as though something was going on with the storyboard view controllers, as I was able to remove the slider and add a new slider in and the functionality worked correctly inside the UIPageViewController page.
Maybe it is because you don't set constraints to child subview.
And when container view size changed - your child view is out of bounds.
You can check it is with View Debug feature in Xcode (when your app is in problem screen, you can capture all views (menu Debug->View debugging->Capture view hierarchy) and investigate what happens
child.view.frame = self.containerView.bounds
self.containerView.addSubview(child.view)
// need to add constraint, because if container view resized, child view frame not changed
child.view.autoresizinkMask = [.flexibleHeight, .flexibleWidth]
child.view.translatesAutoresizingMaskIntoConstraints = true
child.didMove(toParentViewController: self)

Presentviewcontroller behind a view

I have a view setup where the my main view has a thin draggable view in it's hierarchy that resides at the bottom of the view.
Tapping on a particular button will present a view:
let productDetailsViewController: FMProductDetailsViewController = (UIStoryboard(name: "Catalogue", bundle: nil).instantiateViewControllerWithIdentifier("FMProductDetailsViewController") as? FMProductDetailsViewController)!
productDetailsViewController.selectedProduct = product
productDetailsViewController.delegate = self
productDetailsViewController.modalPresentationStyle = .OverCurrentContext
Is it possible to preset the view behind this bottom draggable view without having to manually present it by animating it myself?

iOS dim background View full screen

My question should be simple but I couldn't find solution.
I am displaying modal VC and I want to append dim background view.
Modal VC is added as a child to the parent VC. Parent VC is placed at top of Navigation Controller (topViewController)
Dim view is added to the UIScreen.windows.first! window. But the dim view doesn't fill the whole screen. I do set frame for it with CGPointZero for origin, I tried negative y value it didn't help. It just look like this.
Also I added set of auto layout constraints, set to false/true translatesAutoresizingMaskIntoConstraints property, changed clipToBounds.
Nothing helps, the dim view doesn't cover entire screen.
I can display the dim view in full screen, if I don't add modal VC as a child, i.e. I directly utilize modal VC's view, and add it to the window. It looks fine, but there is another bug. That's why I am adding modal VC, as a child VC.
How to force dim view display the whole screen.
In the app there might be several modal VC displayed simultaneously, that's why seques, (i.e presentation of VCs) is not the best choice.
P.S. Here is description of the bug :
. In case of adding modal VC (UITableVC placed into Nav. Controller)'s view directly to the window , view displays shifted table, after returning back from BG, i.e. in case of being in BG and starting to display modal VC from BG, after that switching back to Foreground, part of table's header (Question is revealed part) is shifted up and modal VC's navigation bar is expanded, i.e. they intersect, header of the table isn't display completely. I couldn't fix that.
Swift 4 Update
let dimView = UIView(frame: UIScreen.main.bounds)
dimView.backgroundColor = UIColor(white: 0.4, alpha: 0.5)
self.navigationController!.view.addSubview(dimView)
self.navigationController!.view.bringSubviewToFront(dimView)
Put your view under navigation controller's view:
UIView *dimView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
dimView.backgroundColor = [UIColor colorWithWhite:.4f alpha:.5f];
[self.navigationController.view addSubview:dimView];
[self.navigationController.view bringSubviewToFront:dimView];
You can add the view and make it dim as well and add it as a sub view to UINavigationController , status Bar as below :
// Dim navigation bar
let navDimView = UIView(frame: (self.navigationController?.navigationBar.bounds)!)
navDimView.restorationIdentifier = "navDimView"
navDimView.backgroundColor = UIColor.black.withAlphaComponent(0.6)
self.navigationController?.navigationBar.addSubview(navDimView)
// Dim status bar
let window = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
let wFrame = window?.windowScene?.statusBarManager?.statusBarFrame
let statusBarView = UIView(frame: wFrame!)
statusBarView.restorationIdentifier = "statusBarView"
statusBarView.backgroundColor = UIColor.black.withAlphaComponent(0.6)
window?.addSubview(statusBarView)
If you want to revert it back you can do as below:
// Revert navigation bar back to normal
for subview in self.navigationController!.navigationBar.subviews {
if subview.restorationIdentifier == "navDimView" {
subview.removeFromSuperview()
}
}
// Revert status bar back to normal
let window = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
for subview in window!.subviews {
if subview.restorationIdentifier == "statusBarView" {
subview.removeFromSuperview()
}
}

Resources