Button을 사용 할 때는 이런 문제가 없었던 것 같습니다.
Tap Gesture를 사용하니 이러한 경우에서 문제가 발생합니다.
Tap Gesture의 경우 탭을 여러번 할 경우 전부 커맨드를 통해 들어오게 됩니다.
짧은 시간 안에 많은 입력이 들어와서 앱이 죽는 경우가 생깁니다.
타이머를 이용하여 일정 시간동안 들어오는 입력을 처리해서 한번 만 동작하게 한다던가,
Event를 활용하여 구독해지를 통해 여러번 입력이 들어와도 한번만 동작하게하는 방법 등등…
여러가지 방법이 있는 것 같습니다.
이러한 디자인 패턴 이름이 있는 것 같은데;;; 검색 키워드를 잘 모르는 상황입니다.
이러한 문제를 해결하기위해 주로 사용하는 방법은 무엇인가요?
Tap Gesture를 사용하고 짧은 시간 안에 입력이 여러번 들어오면 문제가 생긴다. 여러 번 들어오는 입력을 하나의 입력으로 처리하고 싶습니다.
@dimohy 재현 가능한 샘플을 제가 제공 해드려야하는건데… 죄송합니다.
(Shell Navigation 페이지에서 Modal 페이지를 열고 await Navigation.PushAsync(new DetailsPage());)
Modal 페이지에서 tap을하면 pop되서 닫히는 구조입니다. (await Navigation.PopAsync();)
이 때 tap이 여러번 들어오면 에러가 발생합니다. ( pop할 stack이 없다라는 느낌이였습니다.)
이런 에러는 Stack이 있을 때 pop해라 라고 해도 되긴 합니다…
Xamarin.Form 뿐만 아니라 WInform, WPF, Blazor, Javascript에서도 마찬가지로 사용자가 버튼을 여러 번 누를 수 있기에 저는 다음 방법 중 하나를 사용합니다.
MVVM을 사용할 경우에는 ViewModel에 IsBusy라는 상태 속성을 추가하고 버튼 클릭 커맨드 실행 시 IsBusy를 true로 지정하고 기능이 다 실행된 후 IsBusy를 false로 바꿉니다.
버튼쪽에서는 IsBusy를 Enabled 속성에 바인딩해놓으면 버튼 커맨드가 끝나기 전 까지는 사용자가 버튼을 연속적으로 누를 수 없습니다.
MVVM을 사용하지 않고 CodeBehind로 할 경우에는 버튼 클릭 이벤트(Full MVVM이 아닌 Command만 사용하는 경우도 마찬가지)에서 버튼의 Enabled 속성을 false로 했다가 다 끝나고 True로 바꿉니다.
각 버튼 클릭 이벤트 또는 커맨드마다 이렇게 하기 싫으면 해당 화면 최상단 컨테이너의 Enabled 속성에 IsBusy를 바인딩해놓으면 한 화면의 모든 버튼마다 IsBusy를 바인당하지 않아도 되고 어차피 사용자가 버튼을 누를 때 다른 입력도 하면 안되는 경우가 대부분이므로 이런 방법이 더 좋을 수 있습니다.
버튼 클릭 이벤트에서 시간이 좀 걸리는 작업을 하는 경우에 화면 전체가 Disable되면 보기 좋지 않을 수 있는데, 이런 경우에는 화면 전체를 가리는 Full Loading Splash 같은 것을 올려서 IsBusy=true일 때 Full Loading Splash를 보여주고, IsBusy=false일 때 숨겨주면 됩니다. 예전 WPF/Silverlight 시절에 BusyIndicator라는 컨트롤이 이런 기능을 제공해서 잘 써먹었었네요.