Function not called with selector action - swift

I'm trying to handle tap gesture in an external UIViewController's class but my function was never called. Here is my
code:
import SceneKit
import UIKit
class SceneManager
{
private let assetFolder: String
private let mainCamera: SCNNode
private let view: SCNView
private let scene: SCNScene
init(view: SCNView, assetFolder: String, sceneFile: String, mainCameraName: String, backgroundColor: UIColor) {
self.assetFolder = assetFolder
self.scene = SCNScene(named: (self.assetFolder + "/scene/" + sceneFile))!
self.mainCamera = self.scene.rootNode.childNodeWithName(mainCameraName, recursively: true)!
self.view = view
self.view.backgroundColor = backgroundColor
self.view.allowsCameraControl = false
self.view.pointOfView = self.mainCamera
self.view.scene = self.scene
//PROBLEM BELOW
let gesture = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))
self.view.addGestureRecognizer(gesture)
}
#objc func handleTap(sender: UITapGestureRecognizer) {
print("hello")
}
}
Here is my ViewController Class :
import UIKit
import QuartzCore
import SceneKit
class ViewController: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
let view = self.view as! SCNView
view.showsStatistics = true
_ = SceneManager(view: view, assetFolder: "art.scnassets", sceneFile: "EURO_COPTER.dae", mainCameraName: "camera", backgroundColor: UIColor.blackColor())
}
}
If someone has an idea. Thanks in advance.

Try following code it may help
let gesture = UITapGestureRecognizer(target: self, action: #selector(SceneManager.handleTap(_:)))

Try to this way:-
When you declare your class, add UIGestureRecognizerDelegate after the class it subclasses. Here's what that looks like in my case:
let gesture = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))
self.view.userInteractionEnabled = true;
gesture.delegate = self
self.view.addGestureRecognizer(gesture)

Related

Gesture recognizer is not working on UIView

I'm trying to get a few gesture recognisers to work on a UIView. The UIview is in this case a retrieved SVG image, the library that I use is SwiftSVG.
But the actual added image is a UIView, so I think that is not the problem?
override func viewDidLoad() {
super.viewDidLoad()
let svgURL = URL(string: "https://openclipart.org/download/181651/manhammock.svg")!
let hammock = UIView(SVGURL: svgURL) { (svgLayer) in
svgLayer.fillColor = UIColor(red:0.8, green:0.16, blue:0.32, alpha:1.00).cgColor
svgLayer.resizeToFit(self.v2imageview.bounds)
}
hammock.isUserInteractionEnabled = true
let tap = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))
hammock.isUserInteractionEnabled = true;
hammock.addGestureRecognizer(tap)
self.view.addSubview(hammock)
}
// function which is triggered when handleTap is called
#objc func handleTap(_ sender: UITapGestureRecognizer) {
print("Hello World")
}
How can I make the recognizer work?
Thanks
You need to set a frame
hammock.frame = ///
or constraints

why is bringSubviewToFront() only working for panning, not tapping?

view.bringSubviewToFront(tappedView)
is working when I drag (pan) views but not when I tap them. My issue is that when I have one view layered over the other, I want the bottom view to come to the front when tapped. Currently it will only come to the front when dragged. Do I need some additional code to do this? Thanks.
Here's an excerpt from my code for more context:
#objc func didPan(_ recognizer: UIPanGestureRecognizer) {
let location = recognizer.location(in: self.view)
switch recognizer.state {
case .began:
currentTappedView = moviePieceView.filter { pieceView -> Bool in
let convertedLocation = view.convert(location, to: pieceView)
return pieceView.point(inside: convertedLocation, with: nil)
}.first
currentTargetView = movieTargetView.filter { $0.pieceView == currentTappedView }.first
case .changed:
guard let tappedView = currentTappedView else { return }
let translation = recognizer.translation(in: self.view)
tappedView.center = CGPoint(x: tappedView.center.x + translation.x, y: tappedView.center.y + translation.y)
recognizer.setTranslation(.zero, in: view)
view.bringSubviewToFront(tappedView)
```
I had this same problem, I managed to solve it this way:
Add a gestureRecognizer to your view and put this in your code. Don't forget to set the delegate as well when attaching this to the code!
#IBAction func tappedView1(recognizer: UITapGestureRecognizer) {
view.bringSubviewToFront(myView)
}
Put this in your viewDidLoad:
let tap = UITapGestureRecognizer(target: self, action: #selector(tappedView1))
tap.cancelsTouchesInView = false
self.view.addGestureRecognizer(tap)
If you want to do that from your panGesture check my question.
Thank you all. It worked when I wrote a second function in addition to didPan().
This is the additional code:
override func viewDidLoad() {
super.viewDidLoad()
configureLabel()
let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(didPan(_:)))
view.addGestureRecognizer(panGestureRecognizer)
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(didTap(_:)))
view.addGestureRecognizer(tapGestureRecognizer)
}
#objc func didTap(_ recognizer: UITapGestureRecognizer) {
let location = recognizer.location(in: self.view)
currentTappedView = moviePieceView.filter { pieceView -> Bool in
let convertedLocation = view.convert(location, to: pieceView)
return pieceView.point(inside: convertedLocation, with: nil)
}.first
guard let tappedView = currentTappedView else { return }
view.bringSubviewToFront(tappedView)
}
HOWEVER, I found out you can also just tick the "User Interaction Enabled" box in the Image View if you don't want to do it programmatically.

Unable to add swipe recognizer to SKScene in Swift playground?

Ok, Im still a little new to how swift playgrounds work but I am trying to add a swipe gesture recognizer in Swift 3 to my swift playground. Following this http://www.spritekitlessons.com/gesture-recognizer-with-sprite-kit-and-swift/ I now have:
func swipedRight(sender:UISwipeGestureRecognizer){
print("swiped right")
}
func swipedLeft(sender:UISwipeGestureRecognizer){
print("swiped left")
}
func swipedUp(sender:UISwipeGestureRecognizer){
print("swiped up")
}
func swipedDown(sender:UISwipeGestureRecognizer){
print("swiped down")
}
let degree = CGFloat(M_PI_2) / 90
class GameScene: SKScene {
var selectedNode: SKNode?
var shakeAction: SKAction?
override func didMove(to view: SKView) {
/* Setup your scene here */
let swipeRight:UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: Selector(("swipedRight:")))
swipeRight.direction = .right
view.addGestureRecognizer(swipeRight)
let swipeLeft:UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: Selector(("swipedLeft:")))
swipeLeft.direction = .left
view.addGestureRecognizer(swipeLeft)
let swipeUp:UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: Selector(("swipedUp:")))
swipeUp.direction = .up
view.addGestureRecognizer(swipeUp)
let swipeDown:UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: Selector(("swipedDown:")))
swipeDown.direction = .down
view.addGestureRecognizer(swipeDown)
}
let frame = CGRect(x: 0, y: 0, width: 1000, height: 600) //view size
let view = SKView(frame: frame)
let scene = GameScene(size: frame.size)
view.presentScene(scene)
PlaygroundPage.current.liveView = view
This compiles, however when I swipe I get an unrecognized selector error even though I did include the functions with the selector:
I have tried placing the functions within the class as well. How can I add a swipe recognizer to a Swift playground SKScene?
You have selectors passed as strings, something is definitely wrong with them as said in error log
Try to use new selector syntax - #selector(methodName).
Example:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
/* Swift 3 */
let swipe = UISwipeGestureRecognizer(target: self, action:#selector(handleSwipe))
view.addGestureRecognizer(swipe)
}
func handleSwipe() {
print("Swiped!")
}
}
Using strings for selectors has been deprecated.
Using new selector syntax if the methodName() method doesn't exist, you'll get a compile error – your app won't crash because of "unrecognized selector".

Trouble with object recognition in UITapGestureRecognizer

I am trying to call the handleTap() function as shown below and let result: AnyObject look for objects in another class that extends to SCNScene
override func viewDidLoad()
{
super.viewDidLoad()
...
// add a tap gesture recognizer
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
self.sceneView.addGestureRecognizer(tapGesture)
}
//(HANDLES A TAP BY THE USER) NOT WORKING
func handleTap(_ gestureRecognize: UIGestureRecognizer)
{
print("tap")
//retrieve the SCNView
let scnView = self.view as! SCNView
//check what nodes are tapped
let p = gestureRecognize.location(in: scnView)
let hitResults = scnView.hitTest(p, options: [:])
//check that we clicked on at least one object
if hitResults.count > 0
{
//retrieved the first clicked object
let result: AnyObject = hitResults[0]
//get its material
let material = result.node!.geometry!.firstMaterial!
//highlight it
SCNTransaction.begin()
SCNTransaction.animationDuration = 0.2
}
The function works however it is supposed to highlight a node which is located in another class AppScene that extends to SCNScene
class AppScene: SCNScene
{
//objects are located in here
}
I am trying to find a way to make the handleTap() function to search for objects that are children of AppScene() as it doesn't work right now.

How to access camera with swiping gesture?

I have added a swipe gesture in my ios application, but somehow I can't access the camera afterward. I am beginner in swift and I would be very glad if you can advice me how to fix it.
So far I have used:
import UIKit
class ViewController: UIViewController, UIImagePickerControllerDelegate,UINavigationControllerDelegate{
let imagePicker: UIImagePickerController! = UIImagePickerController()
let reachability = Reachability()!
override func viewDidLoad() {
super.viewDidLoad()
imagePicker.delegate = self
self.view.backgroundColor = UIColor.flatBlackColorDark()
let upSwipe = UISwipeGestureRecognizer(target: self, action: Selector(("handleSwipes")))
upSwipe.direction = .up
view.addGestureRecognizer(upSwipe)
}
and for the function:
func handleSwipes(sender:UISwipeGestureRecognizer) {
if (sender.direction == .up){
if ( UIImagePickerController.isSourceTypeAvailable(.camera)){
if UIImagePickerController.availableCaptureModes(for: .rear) != nil {
imagePicker.allowsEditing = false
imagePicker.sourceType = .camera
imagePicker.cameraCaptureMode = .photo
present(imagePicker,animated: true, completion: {})
}
}
Where you have:
action: Selector(("handleSwipes"))
put this:
action: #selector(handleSwipes)
The reason is that "handleSwipes" is not the selector for your handleSwipes function, and you do not know how to form the selector correctly. But the compiler does know, and using #selector syntax tells it to do so.