Clipped Image Calls Tapaction Outside Frame

Clipped Image calls TapAction outside frame

Update

I updated my answer. This is the proper way of doing it. There is a modifier called contentShape() that you can use to define the hit test area:

import SwiftUI

struct ContentView: View {
@State private var tapped = false

var body: some View {
Image(systemName: "circle.fill")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(height: 200, alignment: .center)
.presentation(tapped ? Modal(Image(systemName: "photo")) : nil)
.clipped()
.cornerRadius(10)
.border(Color.black, width: 2, cornerRadius: 10)
.contentShape(TapShape())
.tapAction {
self.tapped.toggle()
}
}

struct TapShape : Shape {
func path(in rect: CGRect) -> Path {
return Path(CGRect(x: 0, y: 0, width: rect.width, height: 200))
}
}
}

iOS15 - SwiftUI WheelPicker scrollable outside frame and clipped area destructing other interfaces

In NumberPicker try adding compositingGroup just before clipped(...) as:

.compositingGroup()
.clipped(antialiased: true)

Why does the frame modifier still affect other views when attached to nil image?

Turns out the problem has nothing to do with nil or the frame modifier.

The image was actually extending invisibly beyond the boundaries of .clipShape(Rectangle()) and was blocking the NavigationLink. The solution is to use a combination of .contentShape() and .clipped.

self.imagesViewModel.allImages[self.post.imageContentURL]?
.resizable()
.scaledToFill()
.frame(width: 343, height: 171)
.contentShape(Rectangle())
.clipped()
.shadow(radius: 1)

I discovered this answer from the post here:
Clipped Image calls TapAction outside frame

Capturing touches on a subview outside the frame of its superview using hitTest:withEvent:

I have modified the accepted answer's code to be more generic - it handles the cases where the view does clip subviews to its bounds, may be hidden, and more importantly : if the subviews are complex view hierarchies, the correct subview will be returned.

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {

if (self.clipsToBounds) {
return nil;
}

if (self.hidden) {
return nil;
}

if (self.alpha == 0) {
return nil;
}

for (UIView *subview in self.subviews.reverseObjectEnumerator) {
CGPoint subPoint = [subview convertPoint:point fromView:self];
UIView *result = [subview hitTest:subPoint withEvent:event];

if (result) {
return result;
}
}

return nil;
}

SWIFT 3

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {

if clipsToBounds || isHidden || alpha == 0 {
return nil
}

for subview in subviews.reversed() {
let subPoint = subview.convert(point, from: self)
if let result = subview.hitTest(subPoint, with: event) {
return result
}
}

return nil
}

I hope this helps anyone trying to use this solution for more complex use cases.

Tap Action not working when Color is clear SwiftUI

The accurate way is to use .contentShape(Rectangle()) on the view.
Described in this tutorial:

control-the-tappable-area-of-a-view by Paul Hudson @twostraws

VStack {
Image("Some Image").resizable().frame(width: 50, height: 50)
Spacer().frame(height: 50)
Text("Some Text")
}
.contentShape(Rectangle())
.onTapGesture {
print("Do Something")
}

how-to-control-the-tappable-area-of-a-view-using-contentshape stackoverflow

On tap some row in List with a button the action is triggered even clicking outside the button area

There is no problem with your code, it is all because of List, List apply action of a Button of a row to all row, for solving the issue use just Text and put action code inside onTapGesture.

    struct NearestCell: View {

var title: String

var body: some View {
VStack(alignment: .leading) {
Text(title)
.font(.title)
.padding(.bottom, 16)

VStack {


Text("Veja restaurantes a sua volta")

Text("Visualizar") // <<: here
.foregroundColor(Color.blue)
.padding(.top, 16)
.onTapGesture { print("Click") } // <<: here


}
.frame(idealWidth: .infinity, maxWidth: .infinity, alignment: .center)
.padding(.vertical, 16)
.overlay(
RoundedRectangle(cornerRadius: 12)
.stroke(Color.black, lineWidth: 1)
)
}
.padding(.all, 16)
.frame(idealWidth: .infinity, maxWidth: .infinity, alignment: .leading)
}
}


Related Topics



Leave a reply



Submit