AppleTv - CustomOverlayViewController force popup at timecode - swift

I'm using the CustomOverlayViewController on an AVPlayerViewController to display movies related to what the user is currently watching. (https://developer.apple.com/documentation/avkit/avplayerviewcontroller/3229856-customoverlayviewcontroller)
I want to bring that up into focus automatically when the credits start playing. I have a timecode in my metadata and can detect when that occurs. But, I can't find a way to force the view to popup without the user swiping to it on the remote. Is there a way to force this view into focus without user input?
P.S. It is fine if it can be accessed at other times manually by the user as well. I just need to be able to also autofocus it at a certain point.

I ran into the same issue and instead of using the customOverlayViewController property of AVPlayerViewController, I just call
vcToPresent = ViewController()
vcToPresent.modalPresentationStyle = .overCurrentContext
self.avPlayerVC?.present(vcToPresent, animated: true, completion: nil)
to present the desired VC on screen at the time you want it to display.

Related

VNDocumentCameraViewController how to disable auto shutter after the first scan?

I'm creating an app that has a live scan feature. I added the following code to present the view controller that shows what the document camera sees when a button is clicked
let documentCameraViewController = VNDocumentCameraViewController()
documentCameraViewController.delegate = self
present(documentCameraViewController, animated: true)
It is working, but the only issue is the auto shutter is by default set to ON, and it keeps taking scans until I click save. I can manually set the auto shutter to Off, but I don't want that. I want that the auto shutter for the first scan to be on, and then it doesn't keep taking any more photos automatically (the auto shutter switches to off). Is there any way I could do that? if not, how can I set the default auto shutter to off?
Thank you!
You can't. Also delegate will receive all the scans at once.
The closest alternative is to dismiss VNDocumentCameraViewController and take the first scan inside documentCameraViewController: didFinishWith, as shown here for example:
func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFinishWith scan: VNDocumentCameraScan) {
documentCameraViewController?.dismiss(animated: true, completion: nil)
documentCameraViewController = nil
// ...
let firstImage = scan.imageOfPage(at: 0)
However VNDocumentCameraViewController is there to provide a basic functionality. So if you need anything more fine-tuned, it's more common to build a custom camera and process frames with the Vision framework

Dismissing SKScene Completely

Okay so I have an app that starts off with a menu view controller that prompts user to press one of 4ish buttons which then loads a viewcontroller which then presents a scene and the user plays the game based on which button was pressed.
I am then having the user being redirected to another viewcontroller which presents another another scene, once a condition is met (they lose the game). Only problem is, the 2nd viewcontroller(and i'm assuming it's scene) is still running. I know this because I have a print statement inside of it's override function update method to see if it's still there.
In addition, I have audio playing in my old gamesene and it's still currently playing. I wouldn't EXACTLY mind that since later on i'm going to just end up passing audio data (mute all) between all 3 viewcontrollers and their presented scenes.
Only problem with what is going on right now is that when I run the app since the old viewiewcontroller an it's scene seem to still be running underneath, it keeps calling the transition which causes a weird look where when the condition meets, the transition loops endlessly to the new viewcontroller then back to the beginning of the transition then to the new viewcontroller again.
I've tried this piece of code:
let theVC = self.viewController?.storyboard?.instantiateViewController(withIdentifier: "TrumpVC") as! TrumpViewController
self.viewController?.navigationController?.pushViewController(theVC, animated: true)
self.viewController?.dismiss(animated: true, completion: {});
But it doesn't seem to help at all :( Essentially I navigate to a new viewcontroller and dismiss the current one (this is all in my scene)
Thanks
Solution:
let theVC = self.viewController?.storyboard?.instantiateViewController(withIdentifier: "TrumpVC") as! TrumpViewController
self.viewController?.navigationController?.pushViewController(theVC, animated: true)
self.viewController?.removeFromParentViewController()
self.viewController?.dismiss(animated: true, completion: nil)
self.view?.presentScene(nil)

Change key to true then show view in swift

OK, so I've added a view onto my Application that asks the user to accept or decline the Terms of Service. I have it so when they click accept, it changes the key "TermsAccepted" to true. If they close the app, and re-open it, it gives them access. However I'd like to be able to give them access without re-opening the app first.
So in my ViewController (Main Screen), in my viewDidLoad I have the following:
if NSUserDefaults.standardUserDefaults().boolForKey("TermsAccepted") {
// They've been accepted, do nothing.
} else {
let termsView = self.storyboard?.instantiateViewControllerWithIdentifier("FirstLaunchTerms") as! FirstLaunchTermsView
self.presentViewController(termsView, animated: true, completion: null
}
In the 'LaunchTermsView' I have the following code for when they accept the terms.
#IBAction func acceptTerms(sender : AnyObject)
{
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "TermsAccepted")
}
And thi works fine, but they have to re-open the application.
I tried to just have it so the button opens the Main View at the same time as those terms are accepted (After the key is updated) but it gives me the following error.
fatal error: unexpectedly found nil while unwrapping an Optional value (lldb)
I assumed this meant that it was wanting to re-open the launch terms view again, so I tried to move all the code from viewDidLoad to viewWillAppear so it checks each time, but it just gives the same error. (it was a long shot try before I posted on here).
I had a look at some posts on here, but a lot of them were in ObjC or just didn't give me a solution or any form of help to trying to find one myself.
As you're presenting your terms view controller you should simply be able to dismiss it when you're done with it. You don't show any other code so I'm assuming that your 'home' view controller is waiting to be revealed underneath (you don't need to try to show it again).

WKInterfaceLabel.setText not reflecting changes following modal viewController dismissal

I am working on a simple video game for the Apple Watch. In awakeWithContext() I call my own method, startNewGame(), and register for it to be called again when receiving a notification from my modal viewController. This all works fine. Then upon determining the game is over, I call self.presentControllerWithName().
When that controller is dismissed by the player I call self.dismissController(). Then I fire a notification that once again calls startNewGame(). This is where things get weird.
self.score = 0
let scoreString = formatScore(0) //"0000"
self.scoreboard.setText(scoreString)
let hiScore = NSUserDefaults.standardUserDefaults().integerForKey("hiScore")
let hiScoreString = formatScore(hiScore)
self.hiScoreboard.setText(hiScoreString)
The above excerpt from startNewGame() shows me resetting the score and updating both "scoreboards" both WKInterfaceLabels that present scores in a skeumorphic old-timey LCD fashion. Because of this, I call formatScore() which returns a string with leading zeros. Anyway, I then set the text on them both and… nothing happens. Both boards show the same score as before the game over view controller was shown. It is only when they are next updated in response to player's actions that they update to reflect the correct values. Because I only have issues with this when the code runs shortly following the dismissal of a modal viewController, I suspect there is some connection. Anyway, I am stumped, some help would be much appreciated.
I ran into the same problem receiving data from the iPhone using sendMessage.
My code was pretty straight forward:
dispatch_async(dispatch_get_main_queue(),{
if let error = error {
NSLog("showing error: \(error)");
self.lblTitle.setText("Error...");
}
});
For me, the message was being logged, but the interface wasn't getting updated.
Ends up I was showing multiple pages using reloadRootControllersWithNames and when I tried to update a label within a page that wasn't being shown, the update was ignored.
I fixed it by listening to willActivate and didDeactivate to see whether to update the label or whether to save the text so I could apply it when the page is shown.
Apparently this is by design.

Segue following a change in criteria from a local notification in Swift

I have created a local notification in Swift which gives the option to end a current game without having to go back in to the app. That's all fine and works as it should. The issue I'm having is that if the user does this, I don't want them to go back to the Game view controller if that happens to be the last view that was open when the app entered the background. I would like them to go back to the app's Home view controller instead.
I expected to be able to add a perform segue to my Game view controller in the following way, should the criteria match. I tried adding it to viewDidAppear(), but it didn't work:
override func viewDidAppear(animated: Bool) {
if isThereACurrentGame() == false {
performSegueWithIdentifier("unwindToHomeScreen", sender: self)
}
}
Is this something to do with viewDidAppear() not being called when the app comes back to the foreground? If so, what might an alternative be?
P.S. My isThereACurrentGame() function works as it should, as does the performSegueWithIdentifier elsewhere in the view controller, so these aren't the cause of the problem.