Linking an SKScene to a UIViewController - uiviewcontroller

When you create a new game file in swift, by default you are given a GameScene.swift file, a GameViewController.swift file, and a UIViewController on your main.storyboard. In my code I have created another SKScene (similar to the GameScene already present), and I am having trouble linking it to another UIViewController that I have on my main.storyboard. I want to do this because i need to segue from my GameScene to this new scene and then to my Main ViewController / Initial Viewcontroller
How do I link the SKScene and ViewController correctly?
Below is the EndSceneViewController.swift file, and then the EndScene.swift file i want to link it to.
import UIKit
import SpriteKit
class EndSceneVC: UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
if let scene = EndScene(fileNamed:"EndScene") {
// Configure the view.
let skView = self.view as! SKView
skView.showsFPS = true
skView.showsNodeCount = true
/* Sprite Kit applies additional optimizations to improve rendering performance */
skView.ignoresSiblingOrder = true
/* Set the scale mode to scale to fit the window */
scene.scaleMode = .AspectFill
scene.viewController = self
skView.presentScene(scene)
}
}
override func shouldAutorotate() -> Bool {
return true
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
if UIDevice.currentDevice().userInterfaceIdiom == .Phone {
return .AllButUpsideDown
} else {
return .All
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Release any cached data, images, etc that aren't in use.
}
override func prefersStatusBarHidden() -> Bool {
return true
}
}
import SpriteKit
class EndScene : SKScene {
var viewController : UIViewController?
override func didMoveToView(view: SKView) {
print("hello")
}
}

You want to move from scene to scene by switching controllers?
Root ViewController can be targeted from the currently displayed SKScene - you don't have to add another property to your scene.
class GameScene: SKScene {
override func didMoveToView(view: SKView) {
let viewController = self.view?.window?.rootViewController
}
}

Related

Getting black screen except navigation Bar SWIFT

My all previous projects works fine with this simulator but now whenever i'm creating new ViewController in previous projects or in new project, then ViewController looks black except Nav Bar. I don't know what's the problem even i reset my simulator but nothing solve my problem,
i think this problem seem to be so complicated.
import UIKit
class ViewController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Currently View Controller looks here
ScreenShot attached here 1 and 2
I will be very glad if any of them help me.
Thanks
This is a UINavigationController, not a UIViewController So you need to embed UIViewController with this UINavigationController.
That's why you are getting the black screen.
You need to embed UIViewController with this navigation controller.
It's because you are using UINavigationController as superclass of your ViewController. You can change superclass to UIViewController and embed your ViewController in UINavigationController.
Updated code:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Image that shows how you can embed your ViewController:

Xamarin iOS - Refresh View coming back from another view

I have a View 1 (UIViewController) which has a button to navigate to a new view - View 2 (UIViewController).
I would like to refresh View 1 when user clicks back button from View 2. UIViewController does not have ViewWillAppear to know the control is back on the view.
How to determine the control is passed on that view
You can override ViewDidAppear to detect that View 1 is visible again and refresh the view. Do not forget to call the base method too.
public override void ViewDidAppear(bool animated)
{
base.ViewDidAppear (animated);
//Refresh view here.
}
UIViewController does not have ViewWillAppear
You don't have the method ViewWillAppear on an UIViewController?
You could try to use the UINavigationControllerDelegate and specifically WillShowViewController
1)We can set it with a bool Value.
bool viewLoadedAgain = false;
2)Bool value gets 'true' when segue triggers:
public override void PrepareForSegue (UIStoryboardSegue segue, Foundation.NSObject sender)
{
base.PrepareForSegue (segue, sender);
if(segue.Identifier == "segueToSecondVC")
{
viewLoadedAgain = true;
}
}
3) Perform Refreshing ViewController View.
public override void ViewWillAppear (bool animated)
{
base.ViewWillAppear (animated);
this.PerformSegue ("segueToSecondVC",this);
if(viewLoadedAgain == true)
{
//Use any code as per requirement
this.View.SetNeedsLayout ();
this.View.SetNeedsUpdateConstraints ();
this.View.ReloadInputViews ();
this.View.SetNeedsDisplay ();
}
}

Static vs class functions/variables in Swift classes?

The following code compiles in Swift 1.2:
class myClass {
static func myMethod1() {
}
class func myMethod2() {
}
static var myVar1 = ""
}
func doSomething() {
myClass.myMethod1()
myClass.myMethod2()
myClass.myVar1 = "abc"
}
What is the difference between a static function and a class function? Which one should I use, and when?
If I try to define another variable class var myVar2 = "", it says:
Class stored properties not yet supported in classes; did you mean 'static'?
When this feature is supported, what will the difference be between a static variable and a class variable (i.e. when both are defined in a class)? Which one should I use, and when?
(Xcode 6.3)
static and class both associate a method with a class, rather than an instance of a class. The difference is that subclasses can override class methods; they cannot override static methods.
class properties function in the same way (subclasses can override them).
I tried mipadi's answer and comments on playground. And thought of sharing it. Here you go. I think mipadi's answer should be mark as accepted.
class A{
class func classFunction(){
}
static func staticFunction(){
}
class func classFunctionToBeMakeFinalInImmediateSubclass(){
}
}
class B: A {
override class func classFunction(){
}
//Compile Error. Class method overrides a 'final' class method
override static func staticFunction(){
}
//Let's avoid the function called 'classFunctionToBeMakeFinalInImmediateSubclass' being overriden by subclasses
/* First way of doing it
override static func classFunctionToBeMakeFinalInImmediateSubclass(){
}
*/
// Second way of doing the same
override final class func classFunctionToBeMakeFinalInImmediateSubclass(){
}
//To use static or final class is choice of style.
//As mipadi suggests I would use. static at super class. and final class to cut off further overrides by a subclass
}
class C: B{
//Compile Error. Class method overrides a 'final' class method
override static func classFunctionToBeMakeFinalInImmediateSubclass(){
}
}
Regarding to OOP, the answer is too simple:
The subclasses can override class methods, but cannot override static methods.
In addition to your post, if you want to declare a class variable (like you did class var myVar2 = ""), you should do it as follow:
class var myVar2: String {
return "whatever you want"
}
Testing in Swift 4 shows performance difference in simulator. I made a class with "class func" and struct with "static func" and ran them in test.
static func is:
20% faster without compiler optimization
38% faster when optimization -whole-module-optimization is enabled.
However, running the same code on iPhone 7 under iOS 10.3 shows exactly the same performance.
Here is sample project in Swift 4 for Xcode 9 if you like to test yourself
https://github.com/protyagov/StructVsClassPerformance
I got this confusion in one of my project as well and found this post, very helpful. Tried the same in my playground and here is the summary. Hope this helps someone with stored properties and functions of type static, final,class, overriding class vars etc.
class Simple {
init() {print("init method called in base")}
class func one() {print("class - one()")}
class func two() {print("class - two()")}
static func staticOne() {print("staticOne()")}
static func staticTwo() {print("staticTwo()")}
final func yesFinal() {print("yesFinal()")}
static var myStaticVar = "static var in base"
//Class stored properties not yet supported in classes; did you mean 'static'?
class var myClassVar1 = "class var1"
//This works fine
class var myClassVar: String {
return "class var in base"
}
}
class SubSimple: Simple {
//Successful override
override class func one() {
print("subClass - one()")
}
//Successful override
override class func two () {
print("subClass - two()")
}
//Error: Class method overrides a 'final' class method
override static func staticOne() {
}
//error: Instance method overrides a 'final' instance method
override final func yesFinal() {
}
//Works fine
override class var myClassVar: String {
return "class var in subclass"
}
}
And here is the testing samples:
print(Simple.one())
print(Simple.two())
print(Simple.staticOne())
print(Simple.staticTwo())
print(Simple.yesFinal(Simple()))
print(SubSimple.one())
print(Simple.myStaticVar)
print(Simple.myClassVar)
print(SubSimple.myClassVar)
//Output
class - one()
class - two()
staticOne()
staticTwo()
init method called in base
(Function)
subClass - one()
static var in base
class var in base
class var in subclass
Swift class vs static
[Reference vs Value Type]
class is used inside Reference Type(class, function):
computed property
method
can be overridden by subclass
static is used inside Reference Type(class, function) and Value Type(struct, enum, tuple):
computed property and stored property
method
cannot be changed by subclass
protocol MyProtocol {
// class var protocolClassVariable : Int { get }//ERROR: Class properties are only allowed within classes
static var protocolStaticVariable : Int { get }
// class func protocolClassFunc()//ERROR: Class methods are only allowed within classes
static func protocolStaticFunc()
}
struct ValueTypeStruct: MyProtocol {
//MyProtocol implementation begin
static var protocolStaticVariable: Int = 1
static func protocolStaticFunc() {
}
//MyProtocol implementation end
// class var classVariable = "classVariable"//ERROR: Class properties are only allowed within classes
static var staticVariable = "staticVariable"
// class func classFunc() {} //ERROR: Class methods are only allowed within classes
static func staticFunc() {}
}
class ReferenceTypeClass: MyProtocol {
//MyProtocol implementation begin
static var protocolStaticVariable: Int = 2
static func protocolStaticFunc() {
}
//MyProtocol implementation end
var variable = "variable"
// class var classStoredPropertyVariable = "classVariable"//ERROR: Class stored properties not supported in classes
class var classComputedPropertyVariable: Int {
get {
return 1
}
}
static var staticStoredPropertyVariable = "staticVariable"
static var staticComputedPropertyVariable: Int {
get {
return 1
}
}
class func classFunc() {}
static func staticFunc() {}
}
final class FinalSubReferenceTypeClass: ReferenceTypeClass {
override class var classComputedPropertyVariable: Int {
get {
return 2
}
}
override class func classFunc() {}
}
//class SubFinalSubReferenceTypeClass: FinalSubReferenceTypeClass {}// ERROR: Inheritance from a final class
There's one more difference: class can be used to define type properties of computed type only. If you need a stored type property use static instead.
You define type properties with the static keyword. For computed type properties for class types, you can use the class keyword instead to allow subclasses to override the superclass’s implementation.
https://docs.swift.org/swift-book/LanguageGuide/Properties.html
Adding to above answers static methods are static dispatch means the compiler know which method will be executed at runtime as the static method can not be overridden while the class method can be a dynamic dispatch as subclass can override these.

Using Swift, how to create a UIViewController over another one using StoryBoards

I have a viewcontroller that hold a button for now, and I want to create a new viewcontroller and add his view over the current one
So far I did this:
class ViewController : UIViewController
{
var myController: MyController = MyController.controller()
init(coder aDecoder: NSCoder!)
{
super.init(coder: aDecoder)
}
init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!)
{
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
override func viewDidLoad()
{
super.viewDidLoad()
self.view.addSubview(self.myController.view)
}
#IBAction func buttonPressed(sender : AnyObject)
{
}
}
in MyController I did a singleton (I hope I did it right)
class MyController : UIViewController
{
init(coder aDecoder: NSCoder!)
{
super.init(coder: aDecoder)
}
init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!)
{
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
class func controller() -> MyController
{
var once : dispatch_once_t = 0
var sharedInstance: MyController?
dispatch_once(&once, { sharedInstance = MyController()})
return sharedInstance!
}
}
the behavior I got is this, if I DON'T call the
self.view.addSubview(self.myController.view)
everything works fine, if I did, the button in the center is not anymore recognizing the touches, it is like it has something over that intercept the touch, what is wrong here? what I'm missing?
in MyController I did a singleton (I hope I did it right)
You did it wrong. Singleton is not required here. If you are using storyboard, the below line
var myController: MyController = MyController.controller()
could be
var myController: MyController = self.storyboard.instantiateViewControllerWithIdentifier("MyViewController")
Then before adding sub view set the frame of the self.myController.view
self.myController.view.frame = CGRectMake(0, 0, 320, 200); // or what ever frame you want

How to refresh my UIVIewController using SetNeedsDisplay

I have a simple UIViewController (in monotouch), with a button on the UI. Now, my use case is simple - I want to reload the UIViewController whenever the button is clicked. On some threads i read that i just need to call SetNeedsDisplay for the UIView, but that doesn't seem to work for me. Here is my code snippet -
public partial class AbcScreen : UIViewController
{
....
public override void ViewDidLoad()
{
base.ViewDidLoad();
// Declare and Add a button
Add(myBtn);
myBtn.TouchUpInside += (sender, ea) =>
{
Console.WriteLine("Touched the button");
View.SetNeedsDisplay();
};
}
}
I read some other threads, but nothing seems to help. Please help! Thanks!
Try with
this.ReloadInputViews();