I made an iOS app with Xcode and Swift.
One ViewController contains two ContainerViews. The user can switch between them with SegmentedControl.
But, how can I switch to the other ContainerView without the SegmentedControl, e.g. with a button?
Actually I have this code:
let vc : AnyObject! = self.storyboard!.instantiateViewControllerWithIdentifier("login")
self.showViewController(vc as! UIViewController, sender: vc)
This opens the other ContainerView, but as single VC, not inside the parent ViewController.
What can I do to reach the other ContainerView shown in the parent VC?
You must have to set the IBoutlets from ContainerViews viewControllers too to call them separately using uibuttons action.
assign same class to both parentViewcontroller and containerView using identity inspector see image.
connect IBOutlet as well like parentViewController see image
Now can access from class using uibutton action.
Iterate through your parent view controllers's child's like
parentViewController.childViewControllers.indexOf(self)
you got the index, means you can get the Controller then you can show it
Related
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)
I have a view1 with all controls created programmatically.
Once i click on a textbook i will go to view2 which has a tableview with search bar. User can select the tableviewcell value and the value should be displayed in the View1 in the textbook control.
I want to use this view2 as user control whenever a dropdown value to be selected. I am doing this right ?
The problem here is i am able to programmatically push the view controller to view2 . But after selecting the value in View2 i am not able to segue back to View1 with the value selected.
Is this scenario possible at all? If not what would be the solution.
NOTE:
I have 2 views view1 to view2.
View1 acts like a data input form.
View2 acts like a dropdown.
On click of button in View1 i am doing this
func ButtonPressed()
{ print("Button Pressed!!")
// This will create the new instance of the view controller.
let vc = UIStoryboard(name:"Main", bundle:nil).instantiateViewController(withIdentifier: "Storage") as! testClass
self.navigationController?.pushViewController(vc, animated:true)
}
Once view 2 is loaded then i am selecting a value in view2 and i want to segue back to the same instance of View1 so that i don't loose the values.
How can i achieve this??
Thanks in advance.
I have a view in a xib file that contains a button and other 2 views and they don't overlap. The view file's owner is a custom class derived from UIViewController. The custom view controller is created programmatically by this code:
let sfvc = SelezioneFascicoloViewController(nibName: "SelezioneFascicoloView", bundle: nil)
viewObject.addSubview(sfvc.view)
sfvc.updateWithAttributes(attrs, inFascicolo: self.fascicolo!)
viewObject is a view contained in a custom UICollectionViewCell.
The button has a handler connected to the touchDown event (but any other event produce the same problem) and it is defined in the custom UIViewController (SelezioneFascicoloViewController)
I have flagged showsTouchOnHighlight for the button just to see if it receive the event.
Well, the view shows up correctly, if I tap the button I can see the glow but the handler isn't called.
All the views in the hierarchy have the UserInteractionEnabled set to true, and their sizes are correct so the button isn't outside the superview frame.
Also I have a UITapGestureRecognizer in the UICollectionViewController derived class that contains the UICollectionViewCell, and its handler is fired if I tap outside the button, but not when I tap inside the button, and this is as it should be.
Can someone give me some advice for this kind of problem?
Edit: added a screenshot
Interface Builder screen shot
Thank beyowulf.
Everything works if I add SelezioneFascicoloViewController as a child view controller, in this way:
let sfvc = SelezioneFascicoloViewController(nibName: "SelezioneFascicoloView", bundle: nil)
self.addChildViewController(sfvc)
viewObject.addSubview(sfvc.view)
sfvc.didMoveToParentViewController(self)
sfvc.updateWithAttributes(attrs, inFascicolo: self.fascicolo!)
I am finishing my career project and I want to make some UI improvements on the application I developed in Swift for iOS.
The application does not have any explicit explanation of how it works and I'd like to detail it in a pop-up View called from an information button in the Navigation Bar. I'd like some kind of View similar to the Notification Alerts, which pop-up in front of the current view and they disappear by pressing another button. I give you an example image:
I want this button to be available from any Tab View (I've got three views). Any idea of how to manage that?
Thank you very much!
First, go to IB and create a new View Controller. In the Attributes Inspector, click on the dropdown next to Size and click Freeform. Set the size to what you want. Then click Use Preferred Explicit size.
Control-drag from your info button to the new VC you created. Click on the segue, then go to the attributes inspector and change the segue type to 'Present As Popover.' Change the segue identifier to whatever you want. I named it popover.
Create a new class for your popover view and assign it to the VC you created. It doesn't need any code at the moment.
In your presenting VC (Tab Bar), add UIPopoverPresentationControllerDelegate to your class definition. Then add this function:
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
return UIModalPresentationStyle.None
}
Next, in your Tab Bar VC, add this code to your prepareForSegue method:
if segue.identifier == "popover" {
let controller = segue.destinationViewController as! PopoverVC // whatever you named the class
controller.modalPresentationStyle = UIModalPresentationStyle.Popover
controller.popoverPresentationController!.delegate = self
}
That should do it.
I have TabBar with 2 tabs. At some point, from either of the 2 tabs, I want to add a view that is visible on both tab views but behind the TabBar.
So I thought, insert a subview into the TabBarController but below the TabBar.
This works fine in principle and I have the view behind the TabBar but now covering my 2 tabs as I wanted. However, it doesn't actually load. Just its background loads and only viewDidLoad() is called, not viewWillAppear() or any others.
I have also tried calling addChildViewController(myVC) on the TabBarController which has no effect, and also manually calling viewWillAppear() on the view controller I add which also has no effect (and I'm also dubious about whether manually calling viewWillAppear() is permitted or not?).
Is what I'm trying to do possible? What am I missing? Or should I be attempting this some other way?
For some reason, when inserting a subview into a UITabBarController behind it's UITabBar, although the view is visible to the user, the system itself seems to think it is not and so although viewDidLoad() is called, viewDidAppear() and subsequent methods are not.
However, adding a subview above the UITabBar seems to work fine. So I solved this by adding my own new UITabBar as a subview to the UITabBarController (set up basically exactly as the default one would be) and then removing the UITabBarController's default UITabBar.
Then when later inserting my view into the UITabBarController, I insert it as I was doing originally but instead below/behind my custom UITabBar and it seems to load fine.
There is no need to remove and recreate the tabBar. What you need to do is after you insert your custom view, you can then bring the tabBar to the front again.
//bring the tabBar to the front after inserting new view
self.view.bringSubview(toFront: self.tabBar)
This would be a good way:
Add the function below and call it in viewDidLoad of your initial VC. It unwraps your tab bar controller instance (which is optional), and then inserts the view you always want visible just below the tab bar.
private func setupAlwaysVisibleView() {
guard let tabBarController = self.tabBarController else { return }
tabBarController.view.insertSubview(alwaysVisibleView, belowSubview: tabBarController.tabBar)
}
Avoid using optionals for tabBarController or removing current tabBar. Simple add your view below tabBar view. Swift 5, XCode 11.
class TabBarController: UITabBarController {
#IBOutlet var instructionsView: UIView!
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.view.insertSubview(instructionsView, belowSubview: self.tabBar)
}
}
you can also do this inside the init() method for your UITabViewController:
view.insertSubview(alwaysVisibleView, belowSubview: self.tabBar)
no need to dispatch to another method if you are using a subclass of UITabViewController.