NativeScript에서 드래그 앤 드롭하는 방법

배경

최근에는 사용자가 제스처를 사용하여 항목을 재정렬 할 수 있어야하는 시나리오를 포함하는 멋진 기능이 필요한 모바일 애플리케이션을 개발했습니다. 전체 프로세스는 사용자가 올바른 순서로 설정해야하는 퍼즐을 만드는 것입니다.

애플리케이션은 NativeScript-Vue를 사용하여 빌드됩니다 . 요구 사항을 충족하기 위해 구현을 위해 Nativescript Gesture API 를 사용 했습니다. 많은 제스처를 적용한 후 드래그 앤 드롭 기능을 만드는 패닝 제스처로 끝났습니다.

Vue로 빌드 된 NativeScript를 사용하여 iOS 와 Android에서 드래그 앤 드롭 기능을 만들 것 입니다. 다음은 다음 단계에서 빌드 할 애니메이션 이미지입니다.

여기, GitHub 저장소 https://github.com/rjbhatt110/nativescript-drag-drop-fn 이 구현의.

dropArea (회색 상자)와 무작위로 정렬 된 드래그 가능한 개체 (색상 상자)가 화면에 나타납니다. 사용자는 제스처를 사용하여 개체를 드롭 영역으로 드래그하여 올바른 순서를 설정할 수 있습니다.

시작하기

새 프로젝트 생성

새 프로젝트를 만들기 전에 시스템에 NativeScript 환경을 이미 설정했다고 가정합니다 .

새 프로젝트를 만들어 보겠습니다. 터미널 또는 명령 줄에서 다음 명령을 실행합니다.

vue init nativescript-vue/vue-cli-template <project-name>
cd <project-name>
tns platform add ios
tns platform add android
tns run ios
tns run android

드래그 앤 드롭 기능의 기본 코드부터 시작합니다. app.vue파일을 열고 그 후 @pan이벤트와 참조 가있는 dropArea 이미지를 추가하여 UI 구조로 시작 dropArea0합니다.

UI를 추가 한 후 다음 자바 스크립트 코드를 추가하여 로직을 포함 할 차례입니다.

위 코드에서 우리는 mounted()a 메서드 의 UI 요소를 참조 합니다. 나중에이 참조를 nativeview로 사용하여 onPan()세 가지 패닝 제스처 상태를 처리 하는 이벤트를 사용하여 이미지 속성에 액세스합니다 .

onPan()이벤트 args.states === 2우리는 우리의 지정 deltaXdeltaYtranslateXtranslateY있는 드래그 만듭니다.

더 많은 UI 요소 추가 및 드래그 가능하게 만들기

다음 일은라는 이름의 배열을 가진 네 dropArea (회색 박스)과 네 개의 드래그 객체 (칼라 박스)를 포함 UI 코드에 더 많은 요소를 추가하는 것입니다 boxArray에있는 바인딩 image과 태그 v-for속성.

또한 이벤트, 인덱스 및 dragObject를 onPan()메서드에 인수로 전달하여 논리를 업데이트하고 있습니다. 그 후 루프 boxArray에서 사용한 바인딩 UI 요소를 만들고 메서드에 v-for모든 참조를 추가합니다 mounted().

dropArea 및 dragObject 처리

이제 애니메이션을 재생할 시간입니다. 다음 코드는 개체가 드롭 영역에 도달하면 확장 애니메이션을 구현합니다. 따라서 다른 드롭 영역에 대해서도이 코드를 작성해야합니다.

if (this.$refs[ref][0].nativeView.getLocationOnScreen().x >=
this.dropArea0.getLocationOnScreen().x &&
this.$refs[ref][0].nativeView.getLocationOnScreen().x <=
this.dropArea0.getLocationOnScreen().x + this.dropArea0.width &&
this.$refs[ref][0].nativeView.getLocationOnScreen().y >=
this.dropArea0.getLocationOnScreen().y &&
this.$refs[ref][0].nativeView.getLocationOnScreen().y <=
this.dropArea0.getLocationOnScreen().y + this.dropArea0.height
) {
this.dropArea0.scaleX = 1.1;
this.dropArea0.scaleY = 1.1;
} else {
this.dropArea0.scaleX = 1;
this.dropArea0.scaleY = 1;
}

두 개체 간의 스왑을 처리하기 위해 스위치 케이스를 사용하여 배열 인덱스로 얻는 다른 위치를 관리합니다. 이 조건이 끝나면 boxArray물체의 최종 위치를 얻는 데 도움이되는 접합 입니다.

if (
// <========== Drop Area 0 ===========>
this.$refs[ref][0].nativeView.getLocationOnScreen().x >=
this.dropArea0.getLocationOnScreen().x &&
this.$refs[ref][0].nativeView.getLocationOnScreen().x <=
this.dropArea0.getLocationOnScreen().x + this.dropArea0.width &&
this.$refs[ref][0].nativeView.getLocationOnScreen().y >=
this.dropArea0.getLocationOnScreen().y &&
this.$refs[ref][0].nativeView.getLocationOnScreen().y <=
this.dropArea0.getLocationOnScreen().y + this.dropArea0.height
) {
this.translateX = this.$refs[ref][0].nativeView.translateX;
this.translateY = this.$refs[ref][0].nativeView.translateY;
this.dropArea0.scaleX = 1;
this.dropArea0.scaleY = 1;
if (this.$refs[ref][0].nativeView.translateX >= -30) {
this.$refs[ref][0].nativeView.translateX = 0;
} else {
this.$refs[ref][0].nativeView.translateX = -160;
}
if (this.$refs[ref][0].nativeView.translateY >= -30) {
this.$refs[ref][0].nativeView.translateY = 0;
} else {
this.$refs[ref][0].nativeView.translateY = -140;
}
// Translate Animation Start 0
// Handle Animation for swipe object from different position
switch (ref) {
case 1:
if (this.$refs[this.boxArray.indexOf(this.boxArray[0])][0].nativeView.translateX >= 0) {
this.$refs[this.boxArray.indexOf(this.boxArray[0])]
[0].nativeView.translateX = 160 - this.$refs[this.boxArray.indexOf(this.boxArray[0])][0].nativeView.translateX;
} else {
this.$refs[this.boxArray.indexOf(this.boxArray[0])]
[0].nativeView.translateX = 160 + this.$refs[this.boxArray.indexOf(this.boxArray[0])][0].nativeView.translateX;
}
if (this.$refs[this.boxArray.indexOf(this.boxArray[0])][0].nativeView.translateY >= 0) {
this.$refs[this.boxArray.indexOf(this.boxArray[0])]
[0].nativeView.translateY = 0 - this.$refs[this.boxArray.indexOf(this.boxArray[0])][0].nativeView.translateY;
} else {
this.$refs[this.boxArray.indexOf(this.boxArray[0])]
[0].nativeView.translateY = 0 + this.$refs[this.boxArray.indexOf(this.boxArray[0])][0].nativeView.translateY;
}
break;
case 2:
if (this.$refs[this.boxArray.indexOf(this.boxArray[0])][0].nativeView.translateX >= 0) {
this.$refs[this.boxArray.indexOf(this.boxArray[0])]
[0].nativeView.translateX = 0 - this.$refs[this.boxArray.indexOf(this.boxArray[0])][0].nativeView.translateX;
} else {
this.$refs[this.boxArray.indexOf(this.boxArray[0])]
[0].nativeView.translateX = 0 + this.$refs[this.boxArray.indexOf(this.boxArray[0])][0].nativeView.translateX;
}
if (this.$refs[this.boxArray.indexOf(this.boxArray[0])][0].nativeView.translateY >= 0) {
this.$refs[this.boxArray.indexOf(this.boxArray[0])]
[0].nativeView.translateY =140 - this.$refs[this.boxArray.indexOf(this.boxArray[0])][0].nativeView.translateY;
} else {
this.$refs[this.boxArray.indexOf(this.boxArray[0])]
[0].nativeView.translateY = 140 + this.$refs[this.boxArray.indexOf(this.boxArray[0])][0].nativeView.translateY;
}
break;
case 3:
if (this.$refs[this.boxArray.indexOf(this.boxArray[0])][0].nativeView.translateX >= 0) {
this.$refs[this.boxArray.indexOf(this.boxArray[0])]
[0].nativeView.translateX = 160 -
this.$refs[this.boxArray.indexOf(this.boxArray[0])][0].nativeView.translateX;
} else {
this.$refs[this.boxArray.indexOf(this.boxArray[0])]
[0].nativeView.translateX = 160 + this.$refs[this.boxArray.indexOf(this.boxArray[0])][0].nativeView.translateX;
}
if (this.$refs[this.boxArray.indexOf(this.boxArray[0])][0].nativeView.translateY >= 0) {
this.$refs[this.boxArray.indexOf(this.boxArray[0])]
[0].nativeView.translateY = 140 - 
this.$refs[this.boxArray.indexOf(this.boxArray[0])][0].nativeView.translateY;
} else {
this.$refs[this.boxArray.indexOf(this.boxArray[0])]
[0].nativeView.translateY = 140 + this.$refs[this.boxArray.indexOf(this.boxArray[0])][0]
.nativeView.translateY;
}
break;
}
// Translate Animation End 0
// Array that control Position drag item
this.boxArray.splice(ref, 1, this.boxArray[0]);
this.boxArray.splice(0, 1, box);
}

마지막으로, 모든 요소, 코드 및 애니메이션을 추가하여 예상 된 결과를 얻을 때입니다.

Suggested posts

롤업, Apple은 4/20에 다음 이벤트를 개최합니다.

롤업, Apple은 4/20에 다음 이벤트를 개최합니다.

작년에 중단 된 Apple의 올해 봄 이벤트는 4 월 20 일에 열리는 Apple의 새로운 이벤트에 있으며 연례 봄 이벤트 인 "Spring Loaded"라고합니다. 애플은 COVID-19 대유행이 시작되어 작년에 하나도 개최하지 않았습니다.

iOS 15는 재 설계된 제어 센터를 제공 할 수 있음

iOS 15는 재 설계된 제어 센터를 제공 할 수 있음

다가오는 iOS 15에 대한 새로운 추측 애플은 올해 말에 iOS 15를 출시 할 것이지만, 데뷔 몇 달 전에 애플 OS의 다음 버전에 대해 몇 가지 추측이 나왔다. 최근 iOS 15는 macOS Big Sur에서 영감을 얻은 새로운 Control Center 디자인을 특징으로합니다.

Related posts

성능 최적화 된 A / B 테스트 솔루션

성능 최적화 된 A / B 테스트 솔루션

의제 : 소개 : TL;하지만 읽을 수 있습니다. A / B 테스트, CloudFront 및 Lamba @ edge에 대해 이미 알고있는 경우 AWS Lambda @ edge를 사용한 A / B 테스트로 직접 이동하십시오. A / B 테스트 란 무엇입니까? A / B 테스트는 웹 사이트의 두 가지 버전에 대한 사용자의 참여를 비교하는 데 초점을 맞춘 UX 연구 방법론입니다.

fp-ts (Typescript)에서 Option 및 둘 중 하나 사용

저는 함수형 프로그래밍을 좋아합니다. 몇 년 동안 실수를하거나 토끼 구멍을 뚫는 것으로부터 저를 몇 번 구해 주었기 때문입니다. 동일한 입력이 주어지면 출력이 항상 동일하다는 것을 알면 안심입니다.

Syncfusion Blazor 파일 업로드 구성 요소에서 이미지를 미리 보는 방법

Syncfusion Blazor 파일 업로드 구성 요소에서 이미지를 미리 보는 방법

Syncfusion Blazor 파일 업로드는 하나 이상의 파일, 이미지, 문서, 오디오, 비디오 및 기타 파일을 서버에 업로드하기위한 구성 요소입니다. 여러 파일 선택, 진행률 표시 줄, 자동 업로드, 끌어서 놓기, 폴더 (디렉터리) 업로드, 파일을 포함하는 다양한 기능을 갖춘 HTML5 업로드 구성 요소 (<input type =”file”>)의 확장 버전입니다. 검증 등.

6 React 개발자로서 후회

내가 일찍했으면하는 것

6 React 개발자로서 후회

React는 배울 수있는 훌륭한 도구입니다. 그것은 우리가 우리 자신의 방식으로 일을 할 수있게합니다.