undecimal
undecimal

Reputation: 33

SwiftUI: fix .onHover for overlapping views in custom radial layout

I am currently building an app for macos which will have a view with a varying amount of trapezoids arranged in a radial layout. The individual trapezoids have some information and behaviour attached to them, so they are their own view. These trapezoidViews are created with a foreach loop and then rotated with a custom rotation modifier that recalculates the bounding box of the view so it more closely matches where the objects in the view are actually drawn after rotation. Roughly:

@State var displayList = [itemModel]

RadialLayout {
    ForEach(0 ..< displayList.count, id: \.self) { i in
        TrapezoidView(/* ... */)
            .rotated(360/appList.count)*i)
            .onHover { isHovered in
                 // logic to handle onHover                 
            }
            
    }
}

The problem I am facing is that the bounding box which is used for the .onHover modifier is significantly bigger than the trapezoids which leads to overlapping bounding boxes (especially when there are many items to display), which in turn leads to buggy hovering behaviour: overlapping bounding boxes on the radial layout

Do bounding boxes of views in SwiftUI have to be a rectangle where each side is parallel to one of the axes, or can they also be rotated? And if they can't, how do I tackle this problem. I thought about whether there is a way to tell SwiftUI to only apply .onHover based on the trapezoid shapes themselves, not the whole view (kind of like .contentShape() does for touch gestures if I understand that modifier correctly), but I haven't found anything to that end.

Or am I better off just pushing the TrapezoidViews out further from the center, avoiding this problem altogether (but compromising on usability)?

Upvotes: 1

Views: 121

Answers (0)

Related Questions