AndrewHartAR / ARKit-CoreLocation

Combines the high accuracy of AR with the scale of GPS data.
MIT License
5.48k stars 741 forks source link

Click event on annotation node #161

Closed yogendragirase55 closed 5 years ago

yogendragirase55 commented 5 years ago

I am using following code to render annotations node -

    public init(location: CLLocation?, view: UIView) {

    UIGraphicsBeginImageContextWithOptions(view.frame.size, false, UIScreen.main.scale);
    view.layer.render(in: UIGraphicsGetCurrentContext()!)
    let screenShot = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    let plane = SCNPlane(width: view.frame.size.width / 100, height: view.frame.size.height/100)
    plane.firstMaterial!.diffuse.contents = screenShot
    plane.firstMaterial!.lightingModel = .constant

    annotationNode = AnnotationNode(view: view, image: nil)
    annotationNode.geometry = plane
    super.init(location: location)
    let billboardConstraint = SCNBillboardConstraint()
    billboardConstraint.freeAxes = SCNBillboardAxis.Y
    constraints = [billboardConstraint]
    addChildNode(annotationNode)
}

But the problem is its rendering image as annotation and I want some click events for particular portion on image. (My requirement is something like I am rendering a view and view contains buttons. I can tap on buttons to get the event) But in this case 'plane.firstMaterial!.diffuse.contents' does not accept the view so I have to convert a view into image. Now when a view converts into image then I loose the button events as its an image now.

Example:

I want to like this and how we can get button events methods

screenshot 2019-02-21 at 7 48 11 pm

developerark commented 5 years ago

@yogendragirase55 Would it help if:

func locationNodeTouched(node: AnnotationNode) {
        // Do stuffs with the node instance

        // node could have either node.view or node.image
        if let nodeView = node.view{
            // Do stuffs with the nodeView
            // ...
        }
        if let nodeImage = node.image{
            // Do stuffs with the nodeImage
            // ...
        }
    }

also provided the location of touch in the sceneLocationView? That way you can use the tap location to see if the button was touched? If so, I can add the functionality soon.

developerark commented 5 years ago

But in this case 'plane.firstMaterial!.diffuse.contents' does not accept the view so I have to convert a view into image.

Use this to add a view. No need to convert to an image.

let coordinate = CLLocationCoordinate2D(latitude: 51.504571, longitude: -0.019717)
let location = CLLocation(coordinate: coordinate, altitude: 300)
let view = UIView() // or a custom UIView subclass
view.isOpaque = false // if your view has transparent components
let annotationNode = LocationAnnotationNode(location: location, view: view)
miaozasanynoe commented 5 years ago

i also cannot add view

developerark commented 5 years ago

i also cannot add view

What issues do you get when adding a UIView? We have tested the constructor that takes UIView and it had worked properly.

tz70s commented 5 years ago

I met issue on adding UIView as well by installing ARCL via cocoapods, but resolved this after manual installation. I guess it might be outdated and no relevant constructor for UIView.

developerark commented 5 years ago

@yogendragirase55 & @miaozaswdd Cocoapods installs the latest release which is tagged (1.0.4). Adding UIView was not available back then. If you want to use the functionality install it by source for right now as @tz70s mentioned. I will open another issue for creating a new release so it is available with Cocoapods.

developerark commented 5 years ago

@aaronbrethorst need to update Cocoapods. Will open a new issue(#163). This is resolved

yogendragirase55 commented 5 years ago

Add multiple LocationAnnotationNode UIView:

func buildDemoData() -> [LocationAnnotationNode] {
        var nodes: [LocationAnnotationNode] = []

        let spaceNeedle = buildViewNode(latitude: 22.6802, longitude: 75.8698, altitude: 225, text: "pin")
        nodes.append(spaceNeedle)

        let empireStateBuilding = buildViewNode(latitude: 22.6865, longitude: 75.8519, altitude: 14.3, text: "pin")
        nodes.append(empireStateBuilding)

        let canaryWharf = buildViewNode(latitude: 22.7571, longitude: 75.8822, altitude: 236, text: "pin")
        nodes.append(canaryWharf)

        let applePark = buildViewNode(latitude: 22.7571, longitude: 75.8822, altitude: 100, text: "Apple Park")
        nodes.append(applePark)

        return nodes
    }

When I use below code for show UIView and UIButton :

UIButton selector not working

func buildViewNode(latitude: CLLocationDegrees, longitude: CLLocationDegrees,
                       altitude: CLLocationDistance, text: String) -> LocationAnnotationNode {
        let coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
        let location = CLLocation(coordinate: coordinate, altitude: altitude)

        let uiview = UIView()
        uiview.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
        uiview.backgroundColor = UIColor.red
       let button = UIButton(type: .system)
        button.setTitle("Click here", for: .normal)
        button.tintColor = .white
        button.backgroundColor = .red
        button.addTarget(self, action: #selector(buttonClicked), for: .touchUpInside)
        button.frame = CGRect(x: 10, y: 10, width: 150, height: 150)
        uiview.addSubview(button)
        return LocationAnnotationNode(location: location, view: uiview)
    }

@objc func buttonClicked(sender : UIButton){
        let alert = UIAlertController(title: "Clicked", message: "You have clicked on the button", preferredStyle: .alert)

        self.present(alert, animated: true, completion: nil)
    }

And go to another SecondViewController like that :

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)
        let vc = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "SecondViewController") as? SecondViewController
                self.navigationController?.pushViewController(vc!, animated: true)
}

After push SecondViewController navigation back button not working and also I have added another UIButton click event not is working. It's means everything is freeze . Please check and let me know it is working on your side ? If YES so please let me what is the solution . Thanks

samatzp commented 2 years ago

@yogendragirase55 Hi! any solution for tap?