如何将可拖拽文本限制在SwiftUI红色矩形框范围内?
实现SwiftUI拖拽文本在矩形框内的范围限制
要让文本只能在红色矩形框内拖拽,核心是先获取文本的实际尺寸,再计算出它在容器内的可移动边界,最后在拖拽过程中约束偏移量。直接看修改后的代码:
private struct TextSizeKey: PreferenceKey { static var defaultValue: CGSize = .zero static func reduce(value: inout CGSize, nextValue: () -> CGSize) { value = nextValue() } } struct DraginContainerView: View { @State var viewState = CGSize.zero @State private var textSize = CGSize.zero // 把容器尺寸抽成常量,方便后续调整 private let containerSize = CGSize(width: 200, height: 200) var body: some View { // 把原VStack改成ZStack,让文本叠加在矩形上方 ZStack { Rectangle() .fill(.red) .frame(width: containerSize.width, height: containerSize.height) Text("My Text") .foregroundColor(.black) .offset(x: viewState.width, y: viewState.height) // 通过GeometryReader获取文本的实际尺寸 .background( GeometryReader { proxy in Color.clear .preference(key: TextSizeKey.self, value: proxy.size) } ) .gesture( DragGesture() .onChanged { value in // 计算X方向的可移动边界:容器半宽减去文本半宽 let maxXOffset = (containerSize.width - textSize.width) / 2 let minXOffset = -maxXOffset // 约束X偏移,不让文本超出容器 let clampedX = min(max(value.translation.width, minXOffset), maxXOffset) // Y方向同理 let maxYOffset = (containerSize.height - textSize.height) / 2 let minYOffset = -maxYOffset let clampedY = min(max(value.translation.height, minYOffset), maxYOffset) viewState = CGSize(width: clampedX, height: clampedY) } .onEnded { value in // 拖拽结束时也要做一次约束,防止手势收尾时超出范围 let maxXOffset = (containerSize.width - textSize.width) / 2 let minXOffset = -maxXOffset let clampedX = min(max(value.translation.width, minXOffset), maxXOffset) let maxYOffset = (containerSize.height - textSize.height) / 2 let minYOffset = -maxYOffset let clampedY = min(max(value.translation.height, minYOffset), maxYOffset) viewState = CGSize(width: clampedX, height: clampedY) } ) } // 接收文本尺寸的更新 .onPreferenceChange(TextSizeKey.self) { newValue in textSize = newValue } } }
关键修改点说明
- 容器布局调整:把原代码的
VStack换成ZStack,让文本和矩形重叠,确保拖拽区域在矩形内部。 - 获取文本尺寸:用
GeometryReader+自定义PreferenceKey拿到文本的实际宽高,这是计算拖拽边界的基础——毕竟要保证文本的边缘不超出矩形框。 - 约束拖拽偏移:在拖拽的
onChanged和onEnded阶段,用min和max函数把偏移量限制在允许范围内,确保文本始终在矩形内部移动。
内容的提问来源于stack exchange,提问作者user1591668
相关产品推荐
相关产品推荐

