UIPageViewController in ContainerView Not Swiping (Swift 3) - ios

I can make this work on full viewcontroller, but in a container view I can only load the first image from an array of images but it won't recognize a swipe. Do I need to reference the container view or something? Here is what I am doing
I am loading images from Assets and looking to paginate based on NSArray()
override func viewDidLoad() {
super.viewDidLoad()
arrayImages = ["one.png", "two.png", "three.png"]
}
I have VC1, with a container view.
The container view has a segue to VC2 which is UIPageViewController
VC2 has a segue to VC3, which has a UIImageView.
How can I cycle through array of Images or do I need a seperate VC for each 'page'?
Cheers

Related

View Controller (UIViewController) Storyboard with multiple scenes using same background image

I am developing a game where the first View Controller will contain full functionality for the rest of the 30 View Controllers, where the rest of these controllers will be sublass of the first view controller. My plan is to use single storyboard for all 30 view controllers or scenes in my app which will all use the same background image. To give you an idea as to what I'm talking about, I only show 2 scenes in this Drawing.Storyboard image but plan is to have 28 more scenes in this same storyboard.
Drawing.Storyboard
If all 30 scenes in this storyboard will have the same UIView background image, how to handle that. Will I have to add same background image for each view in scene or just add background image to the first scene view and use container view for the rest? Note I have never use container views in the past.
After further research and suggestion by "h44f33z", the following will work without using UIView image in your storyboard.
ViewController A
class ViewControllerA: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// Load background image for all views
let bgImageView = UIImageView(frame: UIScreen.main.bounds)
bgImageView.image = UIImage(named: "bg_image")
self.view.addSubview(bgImageView)
}
}
View Controller B
class ViewControllerB: ViewControllerA {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
}
There is nothing you have to do in ViewController B because it is a subclass of ViewController A. With this setup you can go with as many as possible views as long as view is subclass of the first view controller.
One way to do that, you can just create a parent / base class of UIViewController and add UIImageView to self.view in viewDidLoad()
So, for the all 30 ViewControllers, should extend to that base viewController. It will look similar to this
class StartViewController: BaseViewController
Your base class viewDidLoad will be something like
override func viewDidLoad() {
super.viewDidLoad()
let bgImageView = UIImageView(frame: UIScreen.mainScreen().bounds)
bgImageView.image = UIImage(named: "bg-image")
self.view.addSubview(bgImageView)
}
You can event add more functions or handling in the base class and will be easily used by all 30 child viewControllers

Toggle ViewController Views

I am learning iOS with few sample projects. I have two view controllers in that first VC has few buttons and a mapview and the second VC has tableview showing a set of results. I have embed the both viewcontrollers in navigationViewController.By clicking a button from First VC i am able to show the tableview (using show segue) and able to go back to first VC through navigation. Now my query is I want to display the tableview (second VC) in place of one view object (map view) defined in firstVC rather than padding the tableview entirely in full screen. My problem is when showing another Viewcontroller i still want to see the few viewobjects from firstVC so I am trying to display the secondVC on top of mapview when i click on a button which triggers the segue.I have to use the single interface, so I need to load the tablview results from SecondVC into firstVC by replacing mapView's view with tableview.Please let me know your ideas if it is possible and any other ideas to achieve the same are most welcomed.
Sreekanth Gundlapalli,
All you need to do is to add the TableView controller's view as subview to your view Controller. In order to simplify the process I personally prefer using the ContainerView,
Step 1 : Add a ContainerView to your View Controller and add the auto layout constraints to it, because your tableView will be loaded inside this container view you donate have to apply any auto layout constraint to your tableView to keep it in place :)
ex :
Step 2 : Drag an IBOutlet to the container view.lets call it as containerView :)
Step 3 : Now its up to you to have two view controller 1 for loading map and 1 for loading tableView, or you will have map view as your view controller subview and you will either hide it or remove it and add container view but I personally prefer having code clean n neat so I prefer having two different VCs
so lets create 2 VCs lets call them as viewController1 & viewController2 Savy ??
Step 4 :
lets write a method which actually loads VC and adds its view as subview to your ViewController
func changeEmbededVC(for status : Int) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
if status == 0 {
mehereButton.tag = 1
let vc = storyboard.instantiateViewController(withIdentifier: "viewController1")
vc.willMove(toParentViewController: self)
containerView.addSubview(vc.view)
self.addChildViewController(vc)
vc.didMove(toParentViewController: self)
}
else {
mehereButton.tag = 0
let vc = storyboard.instantiateViewController(withIdentifier: "viewController2")
vc.willMove(toParentViewController: self)
containerView.addSubview(vc.view)
self.addChildViewController(vc)
vc.didMove(toParentViewController: self)
}
}
I believe code is pretty self explanatory :D now what is mehereButton.tag = 1 ?? Simple you want to toggle view on button press don't you :D hence I have created a IBOutlet for mehereButton and changing its tag :)
now finally in IBAction of mehereButton
#IBAction func buttonTapped(_ sender: UIButton) {
self.changeEmbededVC(for: self.mehereButton.tag)
}
but we need to load one of the view by default isn't it :D
so change your viewDidAppear to
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.changeEmbededVC(for: 0)
}
Hope I answered your question In detail :P I know you can't neither up vote or accept answer as you don't have enough reputation :) but hope it will help somebody in future as well :)

UIViewController containing a flow of UIViewControllers

I am building a UIViewController (outer viewController) that contains another UIViewController (inner viewController). To do this I am using a container view. Now I want the inner viewController to push to another UIViewController, so I basically want the inner viewController to be a child of a UINavigationController. I know that you cannot change the content of a container view once it has been initialised (not directly anyways), so I've hit a wall.
Does anyone have any thoughts on how I can nest a UINavigationController inside a UIViewController or do I need to rethink my approach to the problem?
You can simply take a UINavigationController.
Initialise it with your InnerViewController.
Now, add the UINavigationController as (childViewController + addSubview + didMoveToParentViewController) in the OuterViewController.
Now as the InnerViewController is located inside a UINavigationController. You can push whatever you want on the UINavigationController.
Heavily inspired by #7vikram7 I ended up with a container view that embedded a UINavigationController which had my InnerViewController as its root viewController:
In my InnerViewController I am now able to push to any UIViewController, and control my navigation stack, for example:
override func viewDidLoad() {
super.viewDidLoad()
// Hide the navigation bar
self.navigationController?.setNavigationBarHidden(true, animated: false)
// Push to whatever viewController I want to
let viewController = self.storyboard?.instantiateViewControllerWithIdentifier("myAwesomeViewController") as! AwesomeViewController
self.navigationController?.pushViewController(viewController, animated: true)
}

UISplitViewController detail view controller loads in master view window

I had a UISplitViewController with the following layout, consisting of a single master and detail view controller.
This worked fine for a basic split view with single views, but I needed to support multiple segues from the UITableViewController (Master View) and not load the detail views until data is passed; or else the app will crash because of optional errors.
I tried by having a set up like so;
This loads a blank ViewController as the detail view when the UISplitViewController loads, and when a row is selected the I have a detail segue to the other view controllers, which should appear as a detail view in the UISplitViewController.
This unfortunately does not work exactly, all the data is passed and loaded without crashes but the detail segues actually load the view controllers within the master view window of the split view not the detail view.
Kind of like this,
How can I have multiple detail view controllers which are not loaded until initiating a segue from the master view UITableViewController and open in the detail window ?
Here's the code from the MasterViewController
override func viewDidLoad() {
super.viewDidLoad()
self.splitViewController!.delegate = self;
self.splitViewController!.preferredDisplayMode = UISplitViewControllerDisplayMode.AllVisible
self.extendedLayoutIncludesOpaqueBars = true
}
func splitViewController(splitViewController: UISplitViewController, collapseSecondaryViewController secondaryViewController: UIViewController, ontoPrimaryViewController primaryViewController: UIViewController) -> Bool {
return true
}
If the segues were already there then try removing the segues from the master view to the other detail views and recreating them using a detail segue.

Segue instantiated ViewController with instantiateViewControllerWithIdentifier

Is it possible to use segues in Views of ViewControllers instantiated with instantiateViewControllerWithIdentifier?
Here is a minimal example of what I'm trying to do (I need something like that in a biger project):
In the Main Storyboard I have a rootViewController, a secondViewController with the StoryboardID "secondViewControllerID" and a thirdViewController. The secondViewController is connected with the thirdViewController via button through a show-Segue.
In the class of the rootViewController I instantiate the secondViewController and set its view as subview of my rootViewController:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let storyboard = UIStoryboard(name: "Main", bundle: nil);
var vc = storyboard.instantiateViewControllerWithIdentifier("secondViewControllerID") as UIViewController
self.view.addSubview(vc.view)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
When I now execute the programm I see correctly the subview (secondViewController). But now the segue doesn't work anymore (when I click on the button I don't get to the thirdViewController)
Does anyone has an idea why?
(It is not possible in my project just to use the secondViewController without the instantiateViewControllerWithIdentifier because the secondViewController is part of a pageViewController that is managing its viewControllers via instantiateViewControllerWithIdentifier )
You are adding one view controller's view as a subview of another view controller. But by default, taps and gestures are handled by your main view controller and are not passed on to the subsidiary VC - hence your problem. There are some functions you need to call to get this to work. Take a look at the Apple Docs here.
Look at the section on "Creating Custom Container View Controllers". In summary, you need to wrap your addSubview method call with self.addChildViewController(vc) and vc.didMoveToParentViewController(self) function calls.

Resources