I found a solution for an issue that I was having to get a SwipeGestureRecognizer to work. And this was the solution:
ViewController1
class ViewController1: ViewController2 {
// This ViewController
// has access to the functionality
// declared in viewDidLoad() method
// from ViewController2.
}
ViewController2
class ViewController2: UIViewController {
override func viewDidLoad() {
let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(respondToSwipeGesture(_:)))
swipeRight.direction = .right
let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(respondToSwipeGesture(_:)))
swipeLeft.direction = .left
let swipeUp = UISwipeGestureRecognizer(target: self, action: #selector(respondToSwipeGesture(_:)))
swipeUp.direction = .up
let swipeDown = UISwipeGestureRecognizer(target: self, action: #selector(respondToSwipeGesture(_:)))
swipeDown.direction = .down
view.addGestureRecognizer(swipeRight)
view.addGestureRecognizer(swipeLeft)
view.addGestureRecognizer(swipeUp)
view.addGestureRecognizer(swipeDown)
}
@objc func respondToSwipeGesture(_ gesture : UIGestureRecognizer) {
if let swipeGesture = gesture as? UISwipeGestureRecognizer {
switch swipeGesture.direction {
case .right:
print("swiped right!")
case .left:
print("swiped left")
case .up:
print("swiped up")
case .down:
print("swiped down")
default:
return
}
}
}
}
The question is... Is this a valid approach?
The way I understand viewDidLoad is as a method that gets called to perform initializations on that particular ViewController.
According to Apple Docs
This method is called after the view controller has loaded its view hierarchy into memory. This method is called regardless of whether the view hierarchy was loaded from a nib file or created programmatically in the loadView() method. You usually override this method to perform additional initialization on views that were loaded from nib files.
That being said, the way I'm wrapping my head around the solution from above, is that when ViewController1 gets pushed onto the stack, it would pretty much be calling two viewDidLoad methods, one from ViewController1 and the other one from ViewController2.
Am I right?
Post
Replies
Boosts
Views
Activity
This is my ViewController1
class ViewController1: UIViewController {
fileprivate lazy var gestureManager: GestureManager = {
return GestureManager(vc: self)
}()
override func viewDidLoad() {
super.viewDidLoad()
}
}
And this is my GestureManager class:
class GestureManager {
var appDelegate = UIApplication.shared.delegate as! AppDelegate
var vc: UIViewController?
init(vc: UIViewController) {
print("init controller")
self.vc = vc
let swipeRight = UISwipeGestureRecognizer(target: vc, action: #selector(respondToSwipeGesture(_:)))
swipeRight.direction = .right
let swipeLeft = UISwipeGestureRecognizer(target: vc, action: #selector(respondToSwipeGesture(_:)))
swipeLeft.direction = .left
let swipeUp = UISwipeGestureRecognizer(target: vc, action: #selector(respondToSwipeGesture(_:)))
swipeUp.direction = .up
let swipeDown = UISwipeGestureRecognizer(target: vc, action: #selector(respondToSwipeGesture(_:)))
swipeDown.direction = .down
vc.view.addGestureRecognizer(swipeRight)
vc.view.addGestureRecognizer(swipeLeft)
vc.view.addGestureRecognizer(swipeUp)
vc.view.addGestureRecognizer(swipeDown)
}
@objc func respondToSwipeGesture(_ gesture : UIGestureRecognizer) {
print("this got fired")
if let swipeGesture = gesture as? UISwipeGestureRecognizer {
switch swipeGesture.direction {
case .right:
print("swiped right!")
case .left:
print("Swiped left")
case .up:
print("Swiped up")
case .down:
print("Swiped down!!!")
default:
return
}
}
}
}
It won't throw any error or warnings, it just does not work.
This is my swipe gesture recognizer. It's working so far, but whenever I try to push a View Controller on Swipe Down it would run the code block and I would get the print in the console. But won't push any view controller.
Also, it doesn't return o throw any error or warning. So not sure how to go about this:
Expected behavior: On swipe down, push UIAlertController
class GestureManager: NSObject, TVDocumentViewControllerDelegate {
var appDelegate = UIApplication.shared.delegate as! AppDelegate
var vc: UIViewController?
init(vc: UIViewController) {
self.vc = vc
let swipeRight = UISwipeGestureRecognizer(target: vc, action: #selector(respondToSwipeGesture(_:)))
swipeRight.direction = .right
let swipeLeft = UISwipeGestureRecognizer(target: vc, action: #selector(respondToSwipeGesture(_:)))
swipeLeft.direction = .left
let swipeUp = UISwipeGestureRecognizer(target: vc, action: #selector(respondToSwipeGesture(_:)))
swipeUp.direction = .up
let swipeDown = UISwipeGestureRecognizer(target: vc, action: #selector(respondToSwipeGesture(_:)))
swipeDown.direction = .down
vc.view.addGestureRecognizer(swipeRight)
vc.view.addGestureRecognizer(swipeLeft)
vc.view.addGestureRecognizer(swipeUp)
vc.view.addGestureRecognizer(swipeDown)
}
@objc func respondToSwipeGesture(_ gesture : UIGestureRecognizer) {
if let swipeGesture = gesture as? UISwipeGestureRecognizer {
switch swipeGesture.direction {
case .right:
print("swiped right!")
case .left:
print("Swiped left")
case .up:
print("Swiped up")
case .down:
print("Swiped down")
let alertController = UIAlertController(title: "Test", message: "Test message", preferredStyle: .alert )
appDelegate.appController?.navigationController.pushViewController(alertController, animated: true)
default:
return
}
}
}
}
I have the following GestureManager class that I want to use to clean up the ViewController where the GestureRecognizer functionality is going to be happening.
class GestureManager {
var vc: UIViewController? leftSwipe.direction = .left
}
But I would get the following errors in the above variables (rightSwipe, leftSwipe)
Cannot find "self" in scope
Consecutive declarations on a line must be separated by ";"
Why is this happening? I'm expecting to pass the ViewController to be used in the "target" attribute, but why self cannot be found in scope? Isn't SELF supposed to be pointing to GestureManager class?
This is probably a basic question, but I'm still on they of learning the basics of swift, classes, the different methods etc.
Thanks in advance!
By calling this function popTemplateFromNavigationStack from Swift
func popTemplateFromNavigationStack() {
appDelegate.appController?.evaluate(inJavaScriptContext: {(evaluation: JSContext) - Void in
let popTemplateFromNavigationStack =
evaluation.objectForKeyedSubscript("popTemplateFromNavigationStack")
let _ = popTemplateFromNavigationStack?.call(withArguments: ["REFRESH"])
}, completion: {(Bool) - Void in
//evaluation block finished running
})
}
I would expect it to call the popTemplateFromNavigationStack function in my app.js file
const popTemplateFromNavigationStack = () = {
console.log("POP TEMPLATE FROM NAV STACK")
}
But instead I get the following error log
[System] IKAppContext (0): 0x6000005f0a80 Error: undefined is not an object - undefined - line:undefined:undefined
If you were to take a look at the sample code that the apple docs offer - https://developer.apple.com/documentation/tvmljs/creating_a_client-server_tvml_app they do something like this in the application.js file:
function pushPage(page, loading) {
var currentDoc = getActiveDocument();
navigationDocument.replaceDocument(page, loading);
}
I printed to the console the value of the variable currentDoc and indeed returns the active document.
I double checked that this function is not being declared anywhere else, and it isn't.
However in the tvOS app that I'm working on getActiveDocument() doesn't exists.
What? Why? How?
How can I access appController: TVApplicationController() in AppDelegate from another ViewController
Hi there.
This is a tvOS app, and I'm wondering if there is a possibility to access the appController variable: var appController: TVApplicationController? in the AppDelegate.swift file from a secondViewController.
<document>
<head>
<style>
.background {
background-color: rgb(33, 33, 33);
}
.info-text {
color: rgba(255, 255, 255, 1.0);
}
</style>
</head>
<stackTemplate class="background">
<banner>
<title class="info-text">Test</title>
</banner>
</stackTemplate>
</document>
The background color works just fine, but the .info-text class won't. I tried with inline-styles
<title style="color:rgb(255,255,255,1.0)"></title>
Tried with HEX colors, won't work.
Checked the documentation and <title> is an element that uses colors.
Also tried deleting the background color and just applying the text color to the title element. Does not work neither.
If I were to apply other kind of styles to the <title> element it would apply. Let's say text-align: left would work.
I don't know what am I missing here...
Hi there,
I just downloaded the Sample Code provided by de developer documentation in order to run a simple Client-Server app with TVML Kit for tvOS. https://developer.apple.com/documentation/tvmljs/creating_a_client-server_tvml_app
I'm following the docs step by step and after running the server in the terminal. I would go and open the project in Xcode and hit the build button. It would lauch the simulator but I get the following error in the simulator:
This operation couldn't be completed (TVMLKitErrorDomain error 3.)
And in my console I would get this:
CreateTVMLApp[82816:2094742] [Image] _TVAssetGroup failed to purge cache path: Shared Asset Group, Error Domain=NSCocoaErrorDomain Code=4 "“SharedImageCache” couldn’t be removed." UserInfo={NSUserStringVariant=(
Remove
), NSFilePath=/Users/aeum3893/Library/Developer/CoreSimulator/Devices/A976E6FD-6B0D-4C24-BB4C-DDA1F31B0F01/data/Containers/Data/Application/9AC60995-C9EB-4051-803B-334E1A06F9DC/Library/Caches/com.example.apple-samplecode.creating-a-basic-tvml-app/SharedImageCache, NSUnderlyingError=0x6000004168e0 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
2021-02-01 09:01:42.238202-0500 CreateTVMLApp[82816:2094742] [Image] _TVAssetGroup failed to purge cache path: LSM Asset Group, Error Domain=NSCocoaErrorDomain Code=4 "“LSMImageCache” couldn’t be removed." UserInfo={NSUserStringVariant=(
Remove
), NSFilePath=/Users/aeum3893/Library/Developer/CoreSimulator/Devices/A976E6FD-6B0D-4C24-BB4C-DDA1F31B0F01/data/Containers/Data/Application/9AC60995-C9EB-4051-803B-334E1A06F9DC/Library/Caches/com.example.apple-samplecode.creating-a-basic-tvml-app/LSMImageCache, NSUnderlyingError=0x60000042c870 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
2021-02-01 09:01:42.238767-0500 CreateTVMLApp[82816:2094742] [Image] _TVAssetGroup failed to purge cache path: Trick Play Asset Group, Error Domain=NSCocoaErrorDomain Code=4 "“TrickPlay” couldn’t be removed." UserInfo={NSUserStringVariant=(
Remove
), NSFilePath=/Users/aeum3893/Library/Developer/CoreSimulator/Devices/A976E6FD-6B0D-4C24-BB4C-DDA1F31B0F01/data/Containers/Data/Application/9AC60995-C9EB-4051-803B-334E1A06F9DC/Library/Caches/com.example.apple-samplecode.creating-a-basic-tvml-app/TrickPlay, NSUnderlyingError=0x600000447450 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
2021-02-01 09:01:42.239321-0500 CreateTVMLApp[82816:2094742] [Image] _TVAssetGroup failed to purge cache path: Photo Stream Asset Group, Error Domain=NSCocoaErrorDomain Code=4 "“PhotostreamImages” couldn’t be removed." UserInfo={NSUserStringVariant=(
Remove
), NSFilePath=/Users/aeum3893/Library/Developer/CoreSimulator/Devices/A976E6FD-6B0D-4C24-BB4C-DDA1F31B0F01/data/Containers/Data/Application/9AC60995-C9EB-4051-803B-334E1A06F9DC/Library/Caches/com.example.apple-samplecode.creating-a-basic-tvml-app/PhotostreamImages, NSUnderlyingError=0x60000042ca20 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
2021-02-01 09:01:42.264212-0500 CreateTVMLApp[82816:2094742] [Image] _TVAssetGroup failed to purge cache path: AR Asset Group, Error Domain=NSCocoaErrorDomain Code=4 "“ARFileCache” couldn’t be removed." UserInfo={NSUserStringVariant=(
Remove
), NSFilePath=/Users/aeum3893/Library/Developer/CoreSimulator/Devices/A976E6FD-6B0D-4C24-BB4C-DDA1F31B0F01/data/Containers/Data/Application/9AC60995-C9EB-4051-803B-334E1A06F9DC/Library/Caches/com.example.apple-samplecode.creating-a-basic-tvml-app/ARFileCache, NSUnderlyingError=0x60000042cc00 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
2021-02-01 09:01:42.383110-0500 CreateTVMLApp[82816:2094742] screen parameters are unexpected: MGScreenClass1920x1080x1x40 SCREEN_TYPE(1920,1080,1, 40)
2021-02-01 09:01:42.415012-0500 CreateTVMLApp[82816:2095237] [] nw_protocol_get_quic_image_block_invoke dlopen libquic failed
2021-02-01 09:01:42.498897-0500 CreateTVMLApp[82816:2095248] [System] <IKAppContext (0): 0x60000337f100> Unable to start script (http://localhost:9001//application.js) because of SyntaxError: Unexpected token '<': {
line = 1;
sourceURL = "http://localhost:9001//application.js";
}
2021-02-01 09:01:42.499296-0500 CreateTVMLApp[82816:2094742] [System] App Context Failed with Error: Error Domain=ITMLKitErrorDomain Code=101 "(null)" UserInfo={line=1, sourceURL=http://localhost:9001//application.js}
appController(_:didFail:) invoked with error: Error Domain=TVMLKitErrorDomain Code=3 "(null)"
Apparently, it cannot find the application.js file, but not sure why and how to go about this