0

I wish to draw ShapeViews which are initially, wholly or partly outside screen bounds and which have an .onTapGesture modifier. The ShapeViews may be brought into screen bounds by .scaleEffect.

However, any part of the ShapeView which was initially outside the screen bounds does not respond to .onTapGesture even when brought into screen bounds by .scaleEffect.

The code below was run with XCode Version 14.0.1 (14A400) and Simulator iPadPro (12.9) (2nd generation) and IOS 16.0

import SwiftUI

struct TestTapArea{
    let x = 300.0
    let y = 700.0
    let oX = 400.0
    let oY = -200.0
   
    func path(_ choice: String) -> some View {
        var corners: [CGPoint] = []
        var color: Color = .black
        if choice == "red" {
            corners = [CGPoint(x: 100.0, y: 100.0), CGPoint(x: x, y: 100.0),  CGPoint(x: x, y: y)  ]
            color = Color.red
        }
        if choice == "green" {
            corners = [CGPoint(x: oX , y: oY), CGPoint(x: oX + x, y: oY),  CGPoint(x: oX + x, y: oY + y) ]
            color = Color.green
        }
        return
            myPath(corners, color)
                .onTapGesture {
                    print(choice)
                }
                    
        func myPath(_ corners: [CGPoint], _ color: Color)
           -> _ShapeView<Path, Color> {
               return
                   Path { path in
                       path.move(to: corners[0])
                       path.addLine(to: corners[1])
                       path.addLine(to: corners[2])
                       path.closeSubpath()
                   }
                   .fill(color) as! _ShapeView<Path, Color>
           }
    }
}

struct ContentView: View {
    let testTapArea = TestTapArea()
    var body: some View {
        ZStack {
            testTapArea.path("red")
            testTapArea.path("green")
        }
        .border(.black, width: 1)
        .scaleEffect(0.5)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

The border is just to indicate the boundary between the areas which respond to .onTapGesture.

A position modifier to the border or ShapeViews has no effect.

If I create the ShapeViews initially inside the screen bounds then there is no problem.

However, I would like advice: is it a better approach to coding to ensure all ShapeViews are initially within screen bounds or is there a better way to implement such code so that ShapeViews can initially be outside of screen bounds?

1 Answers1

0

I am a novice and offer this conclusion and work around to my own question based on trial and error so others may have more informed insights than this

If I create a closed filled path then any parts outside of screen bounds do not respond to onTap, as exampled in the question

However, if I make a scaled and repositioned copy of that filled path such that it remains in screen bounds and if, and only if, I also modify the path with a frame which is also in screen bounds, the path responds to .onTap. The .onTap response remains no matter how much dragging and scaling is applied

The application is this: multiple closed filled paths can represent, for example, the parts of a machine where each part has a meaningful size and position irrespective of screen bounds. These can then be dragged and scaled and still respond to .onTap