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

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

Related

Creating Camera view as overlay of another view?

I have a QR code scanner viewcontroller, rather than pushing it in a navigation controller i wondered if it was possible to instantiate the view controller to be an overlay on my previous main screen taking up a quarter of the screen, as i dont need it to be a whole separate screen.
It has its own viewcontroller and view, i just need it to overlay at a smaller size.
No code to provide as this is more of a theoretical question
I assume you want to programmatically add a container in which a second UIViewController can be added in in your current UIViewController. See the example on how to achieve this.
import UIKit
class ParentViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Set a yellow background color on the parentViewController
self.view.backgroundColor = .yellow
// Create our detailViewController which will be contained in the parent
let detailViewController = DetailViewController()
// Add this detailViewController as a child in the current ParentViewController
addChildViewController(detailViewController)
// Add the detailViewController view as a subview on the ParentViewController
view.addSubview(detailViewController.view)
// Since we dont use IB we disable this property to allow programmatic constraints
detailViewController.view.translatesAutoresizingMaskIntoConstraints = false
// We create the constraints for our detailViewControllers view
NSLayoutConstraint.activate([
detailViewController.view.centerYAnchor.constraint(equalTo: view.centerYAnchor),
detailViewController.view.centerXAnchor.constraint(equalTo: view.centerXAnchor),
detailViewController.view.heightAnchor.constraint(equalToConstant: 200),
detailViewController.view.widthAnchor.constraint(equalToConstant: 200)
])
}
}
class DetailViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .green
print("DetailViewController loaded!")
}
}
We have a ParentViewController with a simple yellow background. In this controller we add a green DetailViewController as a container. The result is:
When you run this app you'll notice that the console prints the result from the DetailViewController.
If you want to remove the DetailViewController:
// Call this in your ParentViewController
let vc = self.childViewControllers.last
vc?.view.removeFromSuperview()
vc?.removeFromParentViewController()

UIPageViewController in ContainerView Not Swiping (Swift 3)

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

Swift: Default Storyboard background Image for all ViewControllers

Is there a way to set (preferably in storyboard IB) an image, which, will serve as the background image for all ViewControllers in the whole storyboard. I don't want to have to add a background image in every ViewController or replicate that in code.
I would could create a UIViewController subclass (e.g. name it DefaultViewController) that sets a specific background color in one of the initialization methods (e.g. viewDidLoad, but don't forget if you override this in a subclass of this class to call it's super method).
Then, let all your view controllers inherit from DefaultViewController
Example code:
class DefaultViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = = UIColor.redColor()
}
}
class SomeViewController: DefaultViewController {
override func viewDidLoad() {
// this call makes the background red, you can also not override this method and it will work too
super.viewDidLoad()
}
}

UIView created in Interface Builder not rendering as expected

I'm trying to get my head around iOS development (Swift + Xcode 6), and I'm trying to figure out how what I do in the Interface Builder relates to my code.
What I've done is created PageViewController : UIPageViewController which, in its viewDidLoad method, calls setViewControllers to add a single view controller, an instance of Page11ViewController : UIViewController.
Thanks to a helpful answer on a recent question, I now know that PageViewController and Page1ViewController are being created successfully. However, I am trying to design Page1ViewController in IB, and what's being rendered doesn't reflect the work I'm doing in IB. In my storyboard, I have the following:
So "Page 1 View Controller Scene" contains a view that contains a label ("Page 1"). I have made "Page 1 View Controller" an instance of Page1ViewController by setting its class in the Identity Inspector for that view controller:
But when I run the app, I don't see my white view with a "Page 1" label; instead I see a blank red view. Why red? Because I did this:
class Page1ViewController : UIViewController {
#IBOutlet var mainView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.redColor()
println("Page 1 loaded")
println("Subviews: \(view.subviews.count)")
}
}
So I know that code is being executed, and the background is being set there...and the subview count printed out is 0...so I know that the view I'm constructing in my IB Storyboard is not the view that's actually getting drawn.
Here is the code from PageViewController that adds Page1ViewController:
class PageViewController : UIPageViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
println("Page view controller loaded")
let page1vc = Page1ViewController()
setViewControllers([page1vc],
direction: UIPageViewControllerNavigationDirection.Forward,
animated: true, completion: nil)
}
}
How do I attach the view I'm creating in IB to the code?
Your problem is that you are instantiating an empty Page1ViewController, rather than loading it from your storyboard so it isn't connected to any of the objects you defined in the scene.
You should use -
class PageViewController : UIPageViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
println("Page view controller loaded")
let storyboard = UIStoryboard(name:"MainStoryboard" bundle:nil);
let page1vc = storyboard.instantiateViewControllerWithIdentifier("page1ViewController") as Page1ViewController // Check the Storyboard ID for your scene in the storyboard
setViewControllers([page1vc],
direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil)
}
}

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