如何使用SwiftUI实现拖动上层抠图照片下方的背景图片
问题解决方法
核心原因是ZStack中上层的抠图图像默认会接收所有触控事件,拦截了下层背景图层的手势响应,按以下步骤修改即可:
- 给上层的抠图图像添加
allowsHitTesting(false)修饰符,禁用它的触控事件接收能力,触控事件就会透传到下层的背景图层 - 你现有代码里的DragGesture存在冗余逻辑,
updating回调仅用来更新@GestureState属性即可,不要直接修改@State变量,位置更新逻辑放到onChanged里就足够了 - 额外清理了原代码中未使用的冗余
currentPositions变量
修改后的完整代码
struct MaskImage: View { @State var currentPosition = CGPoint.init(x: UIScreen.main.bounds.width/2, y: UIScreen.main.bounds.height/4) @GestureState private var isDragging = false var body: some View { GeometryReader { geo in HStack { VStack { Spacer() ZStack { // 可拖动的背景图 Image("EFFECT-1") .resizable() .frame(width: abs(geo.size.width-32), height: 375, alignment: .center) .position(currentPosition) .gesture( DragGesture() .onChanged { value in self.currentPosition = value.location } .updating($isDragging) { (value, state, transaction) in state = true } ) // 上层抠图前景 Image("SEGMENTED_IMAGE_REMOVE_BACKGROUND") .resizable() .frame(width: abs(geo.size.width - 32), height: abs(round((geo.size.width / 2) * 2.438)), alignment: .center) // 禁用触控事件接收,让手势透传到下层 .allowsHitTesting(false) } Spacer() } } .background(Color.red) } } }
补充说明
如果后续需要给前景抠图也加手势操作(比如调整大小、移动前景),可以不用加allowsHitTesting,改为把拖动手势加到ZStack本身上,再根据当前选中的编辑对象(背景/前景)分别更新对应的位置参数即可。
内容的提问来源于stack exchange,提问作者Ifadak
相关产品推荐
相关产品推荐

