Implementing Drag Gestures in SwiftUI

    A dragging motion that invokes an action as the drag-event sequence changes.

    Apple Documentation

    Trong hướng dẫn này, chúng ta sẽ tìm hiểu Drag Gesture trong SwiftUI là gì:

  • .onChanged.
  • .updating.
  • .onEnded.
  • limit scrolling.

Điều kiện tiên quyết

    Để làm theo hướng dẫn này, bạn sẽ cần một số kiến thức cơ bản về:

  • Cơ bản với Swift.
  • Xcode 11 trở lên

.onChanged

    onChanged thay đổi giá trị của vị trí khi bạn kéo.

    Đầu tiên, tạo một biến để lưu kích thước. Với biến bên dưới, đối tượng được đặt ở tọa độ với x, y là 50

@State private var rectPosition = CGPoint(x: 50, y: 50)

    Khi hình chữ nhật di chuyển, bạn sẽ thay đổi rectPosition

VStack {
    RoundedRectangle(cornerRadius: 4.0)
        .fill(Color.green)
        .frame(width: 100, height: 100)
        .position(rectPosition)
        .gesture(DragGesture().onChanged({ value in
            self.rectPosition = value.location
        }))
}

    Kết quả là bạn có một hình chữ nhật chuyển động như dưới.

    

.updating

    Bạn có thể biết người dùng có đang kéo hay không bằng cách lấy state. Đầu tiên, tạo GestureState để giữ trạng thái drag.

@GestureState private var isDragging = false

    Tại đây, bạn không thể cập nhật isDragging vì nó ở chế độ chỉ đọc. Tuy nhiên, bạn có thể cập nhật state sau đó nó sẽ cập nhật isDragging.

.gesture(DragGesture().onChanged({ value in
    self.rectPosition = value.location
}).updating($isDragging, body: { (value, state, trans) in
    state = true
}))

    

.onEnded

    Nhiều trường hợp bạn chỉ muốn lấy hành động sau khi người dùng kéo xong đối tượng. Đầu tiên, tạo một biến để biết người dùng kết thúc kéo hay chưa.

@State private var isEnded = false

    Sử dụng cùng mã như trên và chỉnh sửa một chút, cho màu thay đổi nếu x nhỏ hơn 120.

VStack {
    RoundedRectangle(cornerRadius: 4.0)
        .fill(isEnded ? Color.red : Color.green)
        .frame(width: 100, height: 100)
        .position(rectPosition)
        .gesture(DragGesture().onChanged({ value in
            self.rectPosition = value.location
        }).onEnded({ value in
            self.isEnded = value.location.x < 120
        }))
}

    Kết quả:

    

Hạn chế cuộn ngang

.gesture(DragGesture().onChanged({ value in
    self.rectPosition = CGPoint(x: value.location.x, y: 50)
}))

    

    Còn nếu bạn chỉ muốn nó cuộn theo chiều dọc, thì bạn chỉ việc thay đổi giá trị y.

Nguồn: Viblo

Bình luận
Vui lòng đăng nhập để bình luận
Một số bài viết liên quan