Game controller layout detection - swift - swift

How do I detect the game controllers layout from apple tv? I want to change the controls if the layout is different for the controller which will make the game easier to play. .For example, the apple recommended Nimbus Controller is shaped like a play station controller with two joysticks at the bottom, but I have seem other types of controllers which have a xbox like design with a d-pad and a joystick at the bottom instead, if I can detect which is which, to change to controls for different controllers, it will make the game easier to play
Any help would be appreciated

You should use controller profiles to map physical controls to game inputs.
Controllers are automatically discovered, a physical controller is represented by a GCController object, which ‘profiles’ the controllers controls such as GCGamepad, extendedGamepad etc. You should check which controls are registered to each controller. From the documentation on Discovering And Connecting Controllers:
“After your app has finished launching, the operating system
automatically creates a list of connected controllers. Call
the controllers class method to retrieve an array
of GCController objects for all connected controllers.”
In apples sample code they register for .GCControllerDidConnect Notifications and cast the notification object as a GCController instance to a function that set’s up the controls if they exist, parse the controller and assign the corresponding handler method:
NotificationCenter.default.addObserver(self, selector: #selector(GameViewController.handleControllerDidConnectNotification(_:)), name: .GCControllerDidConnect, object: nil)
#objc func handleControllerDidConnectNotification(_ notification: NSNotification) {
let gameController = notification.object as! GCController
registerCharacterMovementEvents(gameController)
}
private func registerCharacterMovementEvents(_ gameController: GCController) {
//…
// Gamepad D-pad
if let gamepad = gameController.gamepad {
gamepad.dpad.valueChangedHandler = movementHandler
}
// Extended gamepad left thumbstick
if let extendedGamepad = gameController.extendedGamepad {
extendedGamepad.leftThumbstick.valueChangedHandler = movementHandler
}
//…
}

I ended up just simply asking the user for their game controller layout. The answer from Ercell0 is a nice way to connect and use the game controllers, but doesn't really answer my question.

Related

How to override Copy and Paste NSMenuItems for one View Controller Swift macOS

I am writing a macOS application with multiple view controllers, using Storyboards.
In my main View Controller I would like to be able to copy and paste data to the NSPasteboard. The data is related to buttons displayed to the user, and the exact data to be copied varies depending on which button has most recently been pressed/selected.
I would like to be able to override the standard behaviour of the Copy and Paste NSMenuItems when my main View Controller is the front most (key) window, but revert to back to standard behaviour when other windows are in the foreground, as they all contain NSTextFields which can be copied/pasted into.
I have done a lot of googling, and overriding this behaviour is not very well documented. I can achieve it globally by adding an IBAction into the App Delegate, which I could use to call a function in whichever View Controller is key, but this doesn't feel like a very elegant solution.
Currently my IBAction in the App Delegate looks like this:
#IBAction func copy(_ sender: Any) {
if let window = NSApplication.shared.keyWindow {
if let splitView = window.contentViewController as? SplitViewController {
if let controlVC = splitView.controlItem.viewController as? ControlViewController {
controlVC.copyAction(self)
}
}
}
}
Am I missing a neater solution?
Thanks,
Dan

How to synchronize multiple controls?

I am looking for pattern in swift to synchronize the state of multiple controls. Say I have NSSegmentedControl in the view, NSMenuItems with checkmarks and NSSegmentedControl in touch bar. Each of them is sending change to model. But how to synchronize with other two? I can use delegates but it looks like the complexity will grow with number of synchronizable items. Is there a common pattern to approach this problem? I would think of something like subscription to change, so all 3 controls can subscribe to it and receive notification when a change occurs, then use it's own transformation of data to pass to the control. Wonder if there is some mechanism for that.
There is a mechanism for that, it's the notification model. I imagine you want the view controller to listen for changes and update its controls--not have each control listen for changes and update itself (which is also possible). The basic approach would be to add a notification observer to the view controller (or whatever object you want to be the observer)...
NotificationCenter.default.addObserver(self, selector: #selector(nHandler(_:)), name: NSNotification.Name(rawValue: "someControlDidChange"), object: segmentedControl)
...and a handler to take action on that notification...
#objc func nHandler(_ notification: Notification) {
guard let control = notification.object as? UISegmentedControl else {
return
}
// determine which control posted the notification
// read the control's new value
// update the other controls
}
Then as a control updates its values, it posts notifications...
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "someControlDidChange"), object: self)
The object here can be self if this notification is posted from within the control (i.e. it's subclassed) or the instance of the control itself (i.e. someSegmentedControl).
The notification observer and the notification poster allow you to include an optional object, as you see in my examples. You should be passing some data within these notifications to allow the observer to determine what object is posting the notification and what value that object has been updated to. Then in the handler of the notification observer, you unwrap that object to get that data.
I have yet to benchmark the costs of posting notifications; I really have no idea how expensive it is. If the delegate approach is too messy and you've written off property observers, the notification model is likely the way to go.

Examples of Delegates in Swift [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I have been trying to learn how delegation with protocols work. I understood everything, but I can't think of when to use delegation other than when using table views and possibly scroll views.
In general, when is delegation used?
What is Delegation?
First of all, you should know that Delegation Pattern is not exclusive for iOS world:
In software engineering, the delegation pattern is a design pattern in
object-oriented programming that allows object composition to achieve
the same code reuse as inheritance.
But working with delegation in the iOS world is so common, I assume that you can see many of classes that provide a delegation/datasource for giving the ability to provide properties or behaviors for the used instance. It is one of main mechanisms of how objects talk to each other in CocoaTouch.
Alternatives:
However, delegation is not the only way to let objects talk to each other in iOS, you might want to know that there are:
NotificationCenter.
KVO (Key-Value Observing).
Completion handlers/Callbacks (using closures).
Target-Action.
Remark: in case if you are interested in comparing between them, you might want to check the following articles:
Communication Patterns.
When to Use Delegation, Notification, or Observation in iOS.
Delegates vs Observers.
When to use Delegation?
So, the question is: "So why should I use delegation instead of those options?"
I will try to make it simple; I would suggest the use of delegation when you have one to one relationship between two objects. Just to make it clearer, the goal of talking a little bit about the NotificationCenter is to try to make sense when delegations are used:
NotificationCenter represents one to many relationship; Simply, it works as: posting (notifying) a notification on a specific event and observing (get notified about) this notification -- it could be observed anywhere else; Logically, that's what one to many relationship means. It is a representation of the Observer Pattern.
How to Apply Delegation?
For the purpose of simplifying, I would mention it as steps:
Knowing the requirements: Each delegate has its own rules, listed in the delegate protocol which is a set of method signatures that you should implement for conforming this delegation.
Conforming for the delegation: it is simply letting your class to be a delegate, by marking it. For instance: class ViewController: UIViewController, UITableViewDelegate {}.
Connecting the delegate object: Marking your class to be a delegate is not enough, you need to make sure that the object you want to be confirmed by your class to give the required job to your class.
Implementing the requirements: Finally, your class have to implement all required methods listed in the delegate protocol.
For Example
Does it sounds a little confusing? What about a real-world example?
Consider the following scenario:
Imagine that you are building an application related to playing audios. Some of the viewControllers should have a view of an audio player. In the simplest case, we assume that it should have a play/pause button and another button for, let's say, showing a playlist somehow, regardless of how it may look like.
So far so good, the audio player view has its separated UIView class and .xib file; it should be added as a subview in any desired viewController.
Now, how can you add functionality to both of the buttons for each viewController? You might think: "Simply, I will add an IBAction in the view class and that's it", at first look, it might sound ok, but after re-thinking a little bit, you will realize that it will not be applicable if you are trying to handle the event of tapping the button at the controller layer; To make it clear, what if each viewController implemented different functionality when tapping the buttons in the audio player view? For example: tapping the playlist in "A" viewController will display a tableView, but tapping it in the "B" viewController will display a picker.
Well, let's apply Delegation to this issue:
The "#" comments represents the steps of "How to Apply Delegation?" section.
Audio Player View:
// # 1: here is the protocol for creating the delegation
protocol AudioPlayerDelegate: class {
func playPauseDidTap()
func playlistDidTap()
}
class AudioPlayerView: UIView {
//MARK:- IBOutlets
#IBOutlet weak private var btnPlayPause: UIButton!
#IBOutlet weak private var btnPlaylist: UIButton!
// MARK:- Delegate
weak var delegate: AudioPlayerDelegate?
// IBActions
#IBAction private func playPauseTapped(_ sender: AnyObject) {
delegate?.playPauseDidTap()
}
#IBAction private func playlistTapped(_ sender: AnyObject) {
delegate?.playlistDidTap()
}
}
View Controller:
class ViewController: UIViewController {
var audioPlayer: AudioPlayerView?
// MARK:- Life Cycle
override func viewDidLoad() {
super.viewDidLoad()
audioPlayer = AudioPlayerView()
// # 3: the "AudioPlayerView" instance delegate will implemented by my class "ViewController"
audioPlayer?.delegate = self
}
}
// # 2: "ViewController" will implement "AudioPlayerDelegate":
extension ViewController: AudioPlayerDelegate {
// # 4: "ViewController" implements "AudioPlayerDelegate" requirments:
func playPauseDidTap() {
print("play/pause tapped!!")
}
func playlistDidTap() {
// note that is should do a different behavior in each viewController...
print("list tapped!!")
}
}
Quick Tip:
As one of the most popular examples of using delegation is Passing Data Back between View Controllers.
Delegation is used when you want to pass some information or state of object A to another object B. Usually object B is the object that created object A.
I will list some situations where you would use delegation.
Yes you're right. table views and scroll views use delegates because they want to tell whoever is interested (usuall your view controller) that "someone selected a row!" or "someone scrolled the scroll view!". Not only do scroll views and table views use delegates, UITextField and UIDatePicker and a lot of other views use delegates too!
View Controllers also have delegates. For example, UIImagePickerController. The reason why is roughly the same as above - because the UIImagePickerController wants to tell you messages like "an image has been selected!". Another example would be UIPopoverControllerDelegate. This delegate tells you things like "the popover has been dismissed!"
Other classes that use delegates include CLLocationManager. This delegate tells you things like "the user's location has been detected" or "failed to detect the user's location".
You can use delegation in your code when a certain view controller of yours wants to send messages to other view controllers. If it is a settings view controller, it might send messages like "the font size setting has been changed!" and the view controller that cares about the font size setting changing will know and change the font size of a label or something.
Delegate Method to Selectionimages
Create baseClass And Insert the following code
Create Another class then insert code
Delegation in IOS world and mostly in MVC (Model View Controller)
is a way for the View to talk to the Controller and it's called "blind communication"
and delegation means to give the " leading stick " to another object ( doesn't really care who is taking over but usually the Controller) to control over components that the view can not control on it's own (remember it's only a view) or doesn't own
to make it more simple ....
the controller can talk to a view but the view can not talk to the controller without Delegation

Difference between GameViewController and SKScenes

I've been developing a game using SpriteKit and Swift but I seem to be having trouble determining what the real differences are between the GameViewController and any one of my SKScenes. I'm trying to understand the differences because I want to implement a GameCenter or local leaderboard into my game but in all the tutorials I find (like this one:Game Center Leaderboards! (Swift 2 in Xcode) ) they have all the logic in GameViewController as they are working with single view apps. I'm having trouble understanding the relation when I read the docs, so any help would be great. Ultimately, I want to be able to display and push data to and from GameCenter in one of my scenes such as GameOverScene. Thanks for any help!
Here is some good info to start with:
Diagram of what happens each frame in SK:
So you see, the SKScene is the class with all of the fun stuff like Nodes and Actions, and is where everything (important to you) happens. You can generate these scenes through the Editor, but then you probably need to make a new .swift file to go with it (as each scene can have its own logic).
The editor is just a 'shortcut' to initializing a bunch of stuff, and honestly, you can make complete games with little code (but you very quickly find out that you want more)
So in this code, where you declare GameScene or PauseScreen (which are basically just class declarations, that inherit from SKScene), you quickly find this line talking about something that ISNT a scene:
override func didMoveToView(view: SKView)
.. it's calling a SKView... what is that, and where did it come from?
(Read about SKView here, and look at its inheritance):
https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SKView/index.html#//apple_ref/occ/cl/SKView
We find this SKView declaration in the GameViewController file, (which is just a class), notice that it's the same as the regular iOS apps mostly, as it inherits UIViewController:
override func viewDidLoad() {
super.viewDidLoad()
if let scene = GameScene(fileNamed:"GameScene") {
// 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
skView.presentScene(scene)
}
Again, that method is declared in GameViewController.swift, which is basically just this:
class GameViewController: UIViewController
So how does all of this relate to iOS apps and SpriteKit? Well, they are all mashed on top of each other:
IOS app anatomy:
Basically, from right to left, you have the Window, which is (correct me if wrong) the AppDelegate, then the ViewController, then your View, which has all of the cool stuff in it (Storyboards sit inside of the View, just as SKScenes sit inside of the View.... Labels, Nodes, or Buttons, all sit inside of their respective classes ((the view)))
It's all a big sandwich of inheritance.
Check out the Apple websites for more info.
https://developer.apple.com/library/safari/documentation/UserExperience/Conceptual/MobileHIG/ContentViews.html#//apple_ref/doc/uid/TP40006556-CH13-SW1
https://developer.apple.com/spritekit/
https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SpriteKitFramework_Ref/
https://developer.apple.com/library/safari/documentation/UserExperience/Conceptual/MobileHIG/Anatomy.html
Basically, everything is an Class inherited from a class inherited from a class and so on, so on... It can get messy. You can also see these inheritances in Xcode by CMD+clicking on them, which will jump you to the source file.
Goodluck with your studies and adventures in SpriteKit :)
You should only have a single GameViewController in your game. SKScenes are the scenes that the game transitions in between an to.
For example, the home menu screen? That's an SKScene. The main gameplay? That's an SKScene. The gameover screen? That's an SKScene.
The GameViewController initializes the entire view that the game will be maintained in, so the view. The SKScenes are just scenes that are placed on top of the view. You should be looking at a tutorial that uses SKScenes.
Here's how to make game center work as of the latest Swift 2.2.
Add this function anywhere inside the GameViewController class, and then just call it right after super.viewDidLoad().
func authenticateLocalPlayer() {
let localPlayer = GKLocalPlayer.localPlayer()
localPlayer.authenticateHandler = {(viewController, error) -> Void in
if (viewController != nil) {
self.presentViewController(viewController!, animated: true, completion: nil)
}
else {
print((GKLocalPlayer.localPlayer().authenticated))
}
}
}
Add the following functions in your SKScene class file. Don't forget to import GameKit. Just call showLeader() whenever you want the leaderboard to be displayed.
func showLeader() {
let viewControllerVar = self.view?.window?.rootViewController
let gKGCViewController = GKGameCenterViewController()
gKGCViewController.gameCenterDelegate = self
viewControllerVar?.presentViewController(gKGCViewController, animated: true, completion: nil)
}
func gameCenterViewControllerDidFinish(gameCenterViewController: GKGameCenterViewController) {
gameCenterViewController.dismissViewControllerAnimated(true, completion: nil)
}
And this is a sample I have of how the score is saved to game center.
func saveHighscore(gameScore: Int) {
print("Player has been authenticated.")
if GKLocalPlayer.localPlayer().authenticated {
let scoreReporter = GKScore(leaderboardIdentifier: "YOUR_LEADERBOARD_ID")
scoreReporter.value = Int64(gameScore)
let scoreArray: [GKScore] = [scoreReporter]
GKScore.reportScores(scoreArray, withCompletionHandler: {error -> Void in
if error != nil {
print("An error has occured: \(error)")
}
})
}
}
It all depends about how you are designing your app, and what technologies you want to use.
If you are looking to build an app in 100% Sprite Kit, then you treat your UIViewController as a shell that holds your Sprite Kit app. The only time you should be touching this is when you need to do things that the SpriteKit scene shouldn't be doing, like creating gesture controls and what not.
However, there are uses to having multiple view controllers with sprite kit elements. Perhaps you are making a business application, and decide to include a little game to go with it.
IMO the best way to think about it in terms of web design is think of your View controller as your HTML page, and think of your Scene as your flash/silverlight/unity/etc game player that you embed in the website. Sometimes you want that player to be full screen, some times you do not, it comes down to the design of the application. When in full screen, we do not need any other components, so the player can do all the work. But what if we attach a how to guide link on the page. We wouldn't want this in game, we want this outside of it. This link will then open up a new page, not associated with the old page, and has no use for the game player components.
Now for your situation with Game Center, it gets more complicated. Game Center was built before Sprite Kit came to existence, so all of its functionality is built on UIKit. But Game Center also allows for customization, so you do not have to use the UIKit features of it. Of course, you will have to do all of the work then in displaying the information inside of your scene with Sprite Kit objects.
To make life easiest for you, you would include all of the built in code needed into your View Controller, then what you do is create a delegate that the scene knows about, and assign your view controller to this delegate. Now Game Scene can access any element of that view controller that you allow, like presenting leader boards or passing up leader boards. Check out this tutorial in its entirety, it will help you learn all you will need to achieve what you want.
https://www.raywenderlich.com/115300/swift-2-tutorial-part-3-tuples-protocols-delegates-and-table-views
In MVC the controller acts as a coordinator, a bit like the conductor in an orchestra. My preference is that scenes just do the one thing they were designed for i.e. implement game play. When a scene is completed, the final task is to notify the controller (using delegate pattern) that the scene is complete. It is then up to the controller to decide what happens next i.e. transition to next scene or game over.

swift - call code from another view controller

I'm using a library that manages the swiping between view controllers.
It seems like the only way that I can use a button in one of my view controller to navigate to the other is by calling a specific method from the view controller that manages the swiping feature.
It there any way to call a method in a different view controller?
Thank you
There are many ways to communicate between view controllers. One of the most common patterns for doing so on iOS is the delegate pattern. One view controller holds a reference to the other and the delegate conforms to a protocol. The protocol is a set of methods that the first view controller can call when specific events happen. I would try setting up a protocol and have one of your view controllers be a delegate to the other
If you take a look at the code that is hosted on GitHub you can see that the page controller is exposed from the EZSwipeController class. So given that you subclass EZSwipeController (or maintain a reference somewhere), you can now access the pageViewController property of it and scroll to a given page.
If you subclass:
class MyVC : EZSwipeController{
func buttonTapped(){ /* use self.pageViewController to "page" */ }
}
Weirdly, I have never personally worked with UIPageViewController, and as far as I can tell there is no easy way to scroll to a page in an easy fashion.
I haven't personally tried it (I usually validate my answers before posting), but you should be able to pull it off. If you don't have a reference to the view controller you need to get it (let me know if that is the core issue).
There is a question on SO that seems to enjoy some popularity regarding UIPageViewController paging:
UIPageViewController, how do I correctly jump to a specific page without messing up the order specified by the data source?
And from Apple docs:
I would also encourage you to look at the code inside of the EZSwipeController repo, where you can find a non-exposed method that does the scrolling:
#objc private func clickedLeftButton() {
let currentIndex = stackPageVC.indexOf(currentStackVC)!
datasource?.clickedLeftButtonFromPageIndex?(currentIndex)
let shouldDisableSwipe = datasource?.disableSwipingForLeftButtonAtPageIndex?(currentIndex) ?? false
if shouldDisableSwipe {
return
}
if currentStackVC == stackPageVC.first {
return
}
currentStackVC = stackPageVC[currentIndex - 1]
pageViewController.setViewControllers([currentStackVC], direction: UIPageViewControllerNavigationDirection.Reverse, animated: true, completion: nil)
}
The "key" line is this one:
pageViewController.setViewControllers([currentStackVC], direction: UIPageViewControllerNavigationDirection.Reverse, animated: true, completion: nil)
I think EZSwipeController also exposes the view controllers contained in the pageViewController which is a property called stackVC, which is an array of the view controllers contained in the page view controller.
I assume with this knowledge you should be able to page to a given page, despite seeming a little "hacky" (IMHO the developers should have exposed paging logic from the get-go).
My advice for you after all this is simple:
Try to roll it yourself. This is not a huge undertaking and you maintain full control over what's accessible and how you want to work with it. The EZSwipeController class is quite small, so there is not a whole lot of code you'd have to write for your own solution. You could also go ahead and fork the repo and modify/use it to your liking.
I hope that helps. If you have any further questions or if something is unclear, I'd be ready to help you out.