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?
Related
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.
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 :)
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)
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()
}
}
I created a page based application which already has several views. RootViewController is responsible for setting up the app layout, and it does everything well except for one thing, the view size.
Here's part of what I have
// Configure the page view controller and add it as a child view controller
self.pageViewController = UIPageViewController(
transitionStyle: .Scroll,
navigationOrientation: .Horizontal,
options: nil
);
self.pageViewController.delegate = self;
// Setup the initial page
let startingViewController = self.modelController.viewControllerWithProfileProvider(
self.profileProviderPreference(),
storyboard: self.storyboard
);
self.pageViewController.setViewControllers(
[startingViewController as BrowsingViewControllerBase] as [AnyObject],
direction: UIPageViewControllerNavigationDirection.Forward,
animated: false,
completion: { done in }
);
self.pageViewController.dataSource = self.modelController;
self.addChildViewController(self.pageViewController);
self.view.addSubview(pageViewController.view);
// Set the page view controller's bounds using an inset rect so that self's view is visible around the edges of the pages
self.pageViewController.view.frame = self.view.bounds;
// Notify the page view controller that we just moved to it. This is a framework imposition. See the docs.
self.pageViewController.didMoveToParentViewController(self);
// Add the page view controller's gesture recognizers to the view controller's view so that the gestures are started more easily.
self.view.gestureRecognizers = self.pageViewController.gestureRecognizers;
All other code in the controllers handles behaviour, not aspect, so I setup everything else using Storyboard. The viewControllerWithProfileProvider: method is returning the proper view, which gets presented on screen, but not correctly. Here's what I have in storyboard:
I then change the colour and label for the button according to the provider given (ie., Facebook, Twitter, LinkedIn...). But I get this:
Notice how the button is off the screen. I would assume that self.pageViewController.view.frame = self.view.bounds; is the key line for this, but I'm not sure what to use. How can I have my views display correctly?
Control Click the box and drag up and leave from the popup select Top space to top layout.
do the same on both right and left side and select leading space and trailing space respectively. Run your app hopefully this helps
I think you need to use , I suffered with the same But Autolayout Rescue me from this.