I have different UIViews one on top of the other; each of them plays a video using AVPlayer
I need each video to be replayed at the end and in order to do so I use this code:
NotificationCenter.default.addObserver(self, selector: #selector(playerDidReachEnd), name: .AVPlayerItemDidPlayToEndTime, object: self.player.currentItem)
#objc fileprivate func playerDidReachEnd(){
self.player.seek(to: .zero)
self.player.play()
}
I noticed that when the selector is called, all the other players in the other UIViews start playing as well...
This is strange to me because I've set the object of the observer to be only the self.player.currentItem
How can I make only this AVPlayer play?
The problem is that that code is in every one of those views. So when the notification is posted, all of those views are observers. So they all start playing.
Related
I'm working on a simple notes app for macOS. I have a home page which is has a NSTableView that displays all your notes, when you click the new note button a new View appears where you can create a new note. Once you click the note it adds the new note to the database and should reload the table view data, but I need to stop the current run and run the program again to see the changes.
I used this post to achieve the same effect on iOS but it seems to not work on MacOS
So how do I adapt:
override func viewDidLoad() {
super.viewDidLoad
NotificationCenter.default.addObserver(self, selector: #selector(loadList), name: NSNotification.Name(rawValue: "load"), object: nil)
}
In the home page VC
and the line:
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "load"), object: nil)
Inside of the saveNewNote IBAction to work in macOS? also are you even able to use the NotificationCenter in macOS apps or is it only on iOS?
NSNotificationCenter is part of Foundation framework, so it's definitely available on macOS.
You should be able to use it the same way you've been using it on iOS.
If you have an IBAction called saveNewNote, inside that method you can posy the notification the way you wrote.
In the view controller which owns the table, add the observer like you wrote, and reload the table...
If it doesn't work, we might need some code example of how you set it up on the Mac app the better understand what isn't working.
My tableView uses prefetching to cache images and works perfectly when I start the app but once I close out of the app, sending it to the background (not fully shutting it down) and click the app again, the cached images are gone but because the tableView already prefetched these images prior to closing, the prefetch method is not being called on the indexPaths that were previously loaded.
Im looking for a method or logic I can code that would call the prefetching method again based off the current indexPath allowing the indexPaths that were previously loaded and then lost to be reloaded. any help would be great?
When your app enters from background to foreground, in appDelegate file inside method
func applicationDidBecomeActive(_ application: UIApplication) {
NotificationCenter.default.post(Notification.init(name: Notification.Name(rawValue: "appDidEnterForeground")))
}
Now you can set up listeners in your UIViewControllers setup code :
override func viewDidLoad() {
NotificationCenter.default.addObserver(self,
selector: #selector(self.YOUR_METHOD_NAME),
name: NSNotification.Name(rawValue: "appDidEnterForeground"),
object: nil)
}
inside your UIViewController create your custom method and check if thats get called implement your logic inside that method.
#objc func YOUR_METHOD_NAME() {
print("notification method called")
}
For analytics purposes, I would like to detect whenever the top UIViewController is modified.
I don't want to use inheritance, but rather delegate some event that I can use.
I see that Firebase have some type of mechanism for that but I couldn't figure how exactly.
Something like the following will be great:
NotificationCenter.default.addObserver(self, selector: #selector(topViewModified), name: .TopViewModified, object: nil)
Thanks.
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.
I currently use postNotification multiple times with NSTimer, but the observer is receiving it only once.
What's the way to receive the same notification multiple times without adding multiple observers?
My timer is created like this:
timer = NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: #selector(update) , userInfo: nil, repeats: true)
And inside the update method is:
let testNotification: NSNotification = NSNotification(name: "testNotification", object: self, userInfo: nil)
NSNotificationCenter.defaultCenter().postNotification(testNotification)
This is how I register the observer in one of the viewcontrollers:
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(testNot), name: "testNotification", object: nil)
updateView()
}
I add the observers in a viewcontroller as one normally would.
I can confirm the timer works, because update() is being called at the regular interval, and the observer does receive the notification for the first time, but it does not recur.
Please let me know if you need to see more of the code.
I don't know how is your situation, but if is a screen for example and this screen is deallocated or dismiss and you don't set to remove all observers, most like is that is generating multiple observers for the same name, looks you receive the first one, after, another is allocated and you don't receive because they lost reference. That should help
Try recreating new object of NSNotification.
So, my testNot() function presented a modal view, and that somehow disabled further notifications from posting. Now I have to figure out how I can present a view and still keep receiving notifications. Alert views still work correctly. It throws an error in the debug console about the alert view still present when further notifications are received, but once the alert view is dismissed, everything goes back to normal.