Search code examples
iosswiftpaintcodecgrectintersectsrect

How to access a layer inside UIView custom class generate with Paintcode?


I'm using Paintcode V3 and last Xcode for my project.

In Paintcode I draw a red path, kind of "clock hand" with a radius variable to be able to rotate it.

enter image description here

In my Xcode project, this custom UIView is added to a main view.

When the red path is rotating, I need to know when it intersects with another element of the view.

I tried:

if self.redPathView.frame.intersects(self.anotherView.frame) {       
    //do something...                   
}

but it can't work because redPathView is the entire Paintcode canvas (the square frame) and not only the red path.

I'm searching a way to access to the red path of my view.


Solution

  • Interesting problem.

    I don't think there is a way to do exactly what you are looking for...
    Like you mentioned, when we use PaintCode, our custom drawings become an entire UIView.
    We can't access its specific elements (like your redPathView).

    (I'm favoriting this question in case anyone knows if we actually can. I may be wrong.)

    Anyway, there is a workaround. You could use PaintCode itself to tell you when "collisions" happen. Of course, then you would need to draw everything there... And implement some sort of internal control that would make sense to you.

    For example, in the picture below I created this "clock hand", with functions to detect when the red thing touches other UI elements (key point there is the touchedElementID expression -- observe how it updates itself with the "ID" of the rectangles):

    paintCode

    There are some issues you may find with this approach, for example the need to know the exact position of other elements on the screen and possibly complex ternary constructions like:

    (rotationSanitized <= -352 || rotationSanitized >= -8) ?
    1 :
    (rotationSanitized <= -82 && rotationSanitized >= -98) ?
    2 :
    (rotationSanitized <= -172 && rotationSanitized >= -188) ?
    3 :
    (rotationSanitized <= -262 && rotationSanitized >= -278) ?
    4 : 0
    

    Also, how to "export" and consume this information along with the StyleKit in Xcode?

    The trick I did was to add an empty (no Fill, no Stroke) UI element in PaintCode and associate the touchedElementID expression result to the alpha value of the element.

    This way I could access the expression in my custom view, for example via StyleKit.touchedElementID. But that introduces a new problem since now I have to change the generated StyleKit every time it is exported (two lines of code, but still). That is kind of a fragile solution.

    However, if you are ok with that, then it's just a matter of consuming this new information...
    For that I created a protocol, so my ViewController can act as the delegate of my custom view, and perform whatever it needs to do when the most internal UI elements in PaintCode are "touched".

    Here is the final result:

    iOS

    Finally, check this project in GitHub with all the code and samples.