Skip to content

Commit 22e2ce3

Browse files
Fix: OnSlidingComplete is launched at the end of tap event (#336)
* Fire the onSlidingStart on tap handler for iOS * Send a lastValue instead of value when firing onSlidingStart The Start event of Slider for Android sends the lastValue which acts as a point where the thumb was when slider was clicked. This value should also be sent on iOS platform to keep the behavior consisent. * Use a state machine for drag and tap events on Windows The state machine for handling the Start->Update->Complete events is used to avoid multiplication of events when flags for sending status are used. This solution was implemented because there's no clear way to override the default drag/tap events on the slider. So to avoid reimplementing the whole architecture the flags and state machines has been used. * Remove unused LaunchEvents() method * Remove redundant EventType enum The `EventType` enum has been previously used to recognize the action performed on the Slider. But due to using flags for a state machine this enum is no longer required and can be safely removed.
1 parent 2a9b73f commit 22e2ce3

File tree

3 files changed

+64
-24
lines changed

3 files changed

+64
-24
lines changed

src/ios/RNCSliderManager.m

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,18 @@ - (void)tapHandler:(UITapGestureRecognizer *)gesture {
5858
CGPoint touchPoint = [gesture locationInView:slider];
5959
float rangeWidth = slider.maximumValue - slider.minimumValue;
6060
float sliderPercent = touchPoint.x / slider.bounds.size.width;
61+
slider.lastValue = slider.value;
6162
float value = slider.minimumValue + (rangeWidth * sliderPercent);
6263

6364
[slider setValue:discreteValue(slider, value) animated: YES];
64-
65+
66+
67+
if (slider.onRNCSliderSlidingStart) {
68+
slider.onRNCSliderSlidingStart(@{
69+
@"value": @(slider.lastValue),
70+
});
71+
}
72+
6573
// Trigger onValueChange to address https://github.com/react-native-community/react-native-slider/issues/212
6674
if (slider.onRNCSliderValueChange) {
6775
slider.onRNCSliderValueChange(@{

src/windows/SliderWindows/SliderView.cpp

Lines changed: 50 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -183,56 +183,86 @@ namespace winrt::SliderWindows::implementation {
183183
m_updating = false;
184184
}
185185

186-
void SliderView::OnValueChangedHandler(winrt::IInspectable const& /*sender*/,
187-
xaml::Controls::Primitives::RangeBaseValueChangedEventArgs const& args){
188-
189-
if (!m_updating) {
186+
void SliderView::OnValueChangedHandler( winrt::IInspectable const& /*sender*/,
187+
xaml::Controls::Primitives::RangeBaseValueChangedEventArgs const& args )
188+
{
189+
if( !m_updating )
190+
{
190191
m_reactContext.DispatchEvent(
191192
*this,
192193
L"topChange",
193-
[&](winrt::Microsoft::ReactNative::IJSValueWriter const& eventDataWriter) noexcept {
194+
[&]( winrt::Microsoft::ReactNative::IJSValueWriter const& eventDataWriter ) noexcept
195+
{
194196
eventDataWriter.WriteObjectBegin();
195197
{
196-
WriteProperty(eventDataWriter, L"value", args.NewValue());
198+
WriteProperty( eventDataWriter, L"value", args.NewValue() );
197199
}
198200
eventDataWriter.WriteObjectEnd();
199-
});
201+
} );
202+
onValueChangeSent = true;
200203
}
201204
}
202205

203-
void SliderView::OnManipulationStartingHandler(winrt::IInspectable const& sender,
204-
xaml::Input::ManipulationStartingRoutedEventArgs const& args) {
205-
if (!m_updating) {
206+
void SliderView::OnManipulationStartingHandler( winrt::IInspectable const& sender,
207+
xaml::Input::ManipulationStartingRoutedEventArgs const& args )
208+
{
209+
if( !m_updating )
210+
{
206211
auto self = sender.try_as<xaml::Controls::Slider>();
207212

208213
m_reactContext.DispatchEvent(
209214
*this,
210215
L"topSlidingStart",
211-
[&](winrt::Microsoft::ReactNative::IJSValueWriter const& eventDataWriter) noexcept {
216+
[&]( winrt::Microsoft::ReactNative::IJSValueWriter const& eventDataWriter ) noexcept
217+
{
212218
eventDataWriter.WriteObjectBegin();
213219
{
214-
WriteProperty(eventDataWriter, L"value", self.Value());
220+
WriteProperty( eventDataWriter, L"value", self.Value() );
215221
}
216222
eventDataWriter.WriteObjectEnd();
217-
});
223+
} );
224+
225+
if( onValueChangeSent )
226+
{
227+
m_reactContext.DispatchEvent(
228+
*this,
229+
L"topSlidingComplete",
230+
[&]( winrt::Microsoft::ReactNative::IJSValueWriter const& eventDataWriter ) noexcept
231+
{
232+
eventDataWriter.WriteObjectBegin();
233+
{
234+
WriteProperty( eventDataWriter, L"value", self.Value() );
235+
}
236+
eventDataWriter.WriteObjectEnd();
237+
} );
238+
onSlidingCompleteSent = true;
239+
}
240+
onValueChangeSent = false;
241+
onSlidingStartSent = true;
242+
onSlidingCompleteSent = false;
218243
}
219244
}
220-
221-
void SliderView::OnManipulationCompletedHandler(winrt::IInspectable const& sender,
222-
xaml::Input::ManipulationCompletedRoutedEventArgs const& args) {
223-
if (!m_updating) {
245+
246+
void SliderView::OnManipulationCompletedHandler( winrt::IInspectable const& sender,
247+
xaml::Input::ManipulationCompletedRoutedEventArgs const& args )
248+
{
249+
if( !m_updating && onSlidingCompleteSent == false )
250+
{
224251
auto self = sender.try_as<xaml::Controls::Slider>();
225252

226253
m_reactContext.DispatchEvent(
227254
*this,
228255
L"topSlidingComplete",
229-
[&](winrt::Microsoft::ReactNative::IJSValueWriter const& eventDataWriter) noexcept {
256+
[&]( winrt::Microsoft::ReactNative::IJSValueWriter const& eventDataWriter ) noexcept
257+
{
230258
eventDataWriter.WriteObjectBegin();
231259
{
232-
WriteProperty(eventDataWriter, L"value", self.Value());
260+
WriteProperty( eventDataWriter, L"value", self.Value() );
233261
}
234262
eventDataWriter.WriteObjectEnd();
235-
});
263+
} );
264+
onSlidingCompleteSent = true;
265+
onValueChangeSent = false;
236266
}
237267
}
238268

src/windows/SliderWindows/SliderView.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
#include "NativeModules.h"
99

1010
namespace winrt::SliderWindows::implementation {
11-
11+
1212
namespace xaml = winrt::Windows::UI::Xaml;
13-
13+
1414
class SliderView : public SliderViewT<SliderView> {
1515
public:
1616
SliderView(Microsoft::ReactNative::IReactContext const& reactContext);
@@ -39,9 +39,11 @@ namespace winrt::SliderWindows::implementation {
3939

4040
double m_maxValue, m_minValue;
4141
double m_value;
42+
43+
bool onValueChangeSent, onSlidingStartSent, onSlidingCompleteSent;
4244
};
4345
}
4446

4547
namespace winrt::SliderWindows::factory_implementation {
4648
struct SliderView : SliderViewT<SliderView, implementation::SliderView> {};
47-
}
49+
}

0 commit comments

Comments
 (0)