Tap手势在SwiftUI中无法识别视图上的偏移更改。

huangapple go评论61阅读模式
英文:

Tap gestures don't recognise offset change on a View in SwiftUI

问题

I have a "button" that I need to offset to a different position using the .offset(y: someVal).

I have the layout of the View as I like it but the hit area seems to be at the area before the offset was applied.

This is my code:

var body: some View {
    ZStack {
        ZStack {
            Circle()
                .foregroundColor(.white)
            Image(systemName: "someIcon")
                .foregroundColor(myColor)
        }
        .frame(width: centerBtnRadius * 2, height: centerBtnRadius * 2)
        .overlay(
            RoundedRectangle(cornerRadius: centerBtnRadius)
                .stroke(myColor, lineWidth: 1)
        )
        .onTapGesture {
            //...
        }
        .onLongPressGesture(perform: {
            //...
        })
        .offset(y: centerBtnOffsetY)
        
        VStack {
            Spacer()
            Text(labelText)
                .scaledToFit()
        }

    }
    .frame(width: Constants.tbItemWidth, height: Constants.tbItemHeight)
}

Now I've tried placing the modifier before others on the nested ZStack without success. It also must be after the .overlay modifier that positions my border around the Circle(). (I'm also open for ideas to make border different if it needs to be a part of the solution!)

My question is:

How can I make sure that my press gestures are caught by the whole Circle element after I've re-positioned it with the .offset modifier? 🤔

英文:

I have a "button" that I need to offset to a different position using the .offset(y: someVal).

I have the layout of the View as I like it but the hit area seems to be at the area before the offset was applied.

This is my code:

    var body: some View {
        ZStack {
            ZStack {
                Circle()
                    .foregroundColor(.white)
                Image(systemName: "someIcon")
                    .foregroundColor(myColor)
            }
            .frame(width: centerBtnRadius * 2, height: centerBtnRadius * 2)
            .overlay(
                RoundedRectangle(cornerRadius: centerBtnRadius)
                    .stroke(myColor, lineWidth: 1)
            )
            .onTapGesture {
                //...
            }
            .onLongPressGesture(perform: {
                //...
            })
            .offset(y: centerBtnOffsetY)
            
            VStack {
                Spacer()
                Text(labelText)
                    .scaledToFit()
            }

        }
        .frame(width: Constants.tbItemWidth, height: Constants.tbItemHeight)
    }

Now I've tried placing the modifier before others on the nested ZStack without success. It also must be after the .overlay modifier that positions my border around the Circle(). (I'm also open for ideas to make border different if it needs to be a part of the solution!)

My question is:

How can I make sure that my press gestures are catched by the whole Circle element after I've re-positioned it with the .offset modifier? 🙏

答案1

得分: 1

将偏移修饰符从点击手势修饰符之后移到之前。通过这样做,点击手势修饰符将考虑偏移量以确定“点击区域”。

var body: some View {
    ZStack {
        ZStack {
            Circle()
                .foregroundColor(.white)
            Image(systemName: "someIcon")
                .foregroundColor(myColor)
        }
        .frame(width: centerBtnRadius * 2, height: centerBtnRadius * 2)
        .overlay(
            RoundedRectangle(cornerRadius: centerBtnRadius)
                .stroke(myColor, lineWidth: 1)
        )
        .onTapGesture {
            //...
        }
        .onLongPressGesture(perform: {
            //...
        })
        .offset(y: centerBtnOffsetY) // 已更改的行
        
        VStack {
            Spacer()
            Text(labelText)
                .scaledToFit()
        }
    }
    .frame(width: Constants.tbItemWidth, height: Constants.tbItemHeight)
}
英文:

You need to move the offset modifier from after the tap gestures modifiers to before. By doing this, the tap gestures modifiers will take the offset into account for the "tap area".

var body: some View {
    ZStack {
        ZStack {
            Circle()
                .foregroundColor(.white)
            Image(systemName: "someIcon")
                .foregroundColor(myColor)
        }
        .frame(width: centerBtnRadius * 2, height: centerBtnRadius * 2)
        .overlay(
            RoundedRectangle(cornerRadius: centerBtnRadius)
                .stroke(myColor, lineWidth: 1)
        )
        .offset(y: centerBtnOffsetY) // Changed line
        .onTapGesture {
            //...
        }
        .onLongPressGesture(perform: {
            //...
        })
        
        VStack {
            Spacer()
            Text(labelText)
                .scaledToFit()
        }

    }
    .frame(width: Constants.tbItemWidth, height: Constants.tbItemHeight)
}

huangapple
  • 本文由 发表于 2023年6月14日 23:58:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/76475472.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定