Skip to content

Commit ce054c1

Browse files
committed
Add support for DisableSwipeDetection, SwipeUpActionEnabled and SwipeUpCommand (#10)
1 parent 57225f4 commit ce054c1

File tree

7 files changed

+142
-31
lines changed

7 files changed

+142
-31
lines changed

src/Calendar.Plugin.Sample/SampleApp/MainPage.xaml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@
3737
</controls:Calendar.EventTemplate>
3838
</controls:Calendar>
3939

40-
<!--<ContentPage.Resources>
40+
<!-- Styling
41+
42+
<ContentPage.Resources>
4143
<ResourceDictionary>
4244
<Style x:Key="daysLabelStyle" TargetType="Label">
4345
<Setter Property="FontAttributes" Value="Italic" />
@@ -51,7 +53,15 @@
5153
</ResourceDictionary>
5254
</ContentPage.Resources>-->
5355

54-
<!--
56+
57+
<!-- Swipe handling
58+
59+
DisableSwipeDetection="False"
60+
SwipeUpActionEnabled="False"
61+
SwipeUpCommand="{Binding SwipeUpCommand}"-->
62+
63+
<!-- Customizations
64+
5565
DaysLabelStyle="{StaticResource daysLabelStyle}"
5666
DaysTitleLabelStyle="{StaticResource daysTitleLabelStyle}"
5767
MonthLabelColor="Red"

src/Calendar.Plugin/Android/SwipeAwareContainerRenderer.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public class SwipeAwareContainerRenderer : ViewRenderer, GestureDetector.IOnGest
1313
{
1414
private const int SwipeDistanceThreshold = 50;
1515
private const int SwipeVelocityThreshold = 20;
16-
private readonly GestureDetector _gestureDetector;
16+
private readonly GestureDetector _gestureDetector;
1717

1818
public SwipeAwareContainerRenderer(Context context) : base(context)
1919
{
@@ -22,7 +22,9 @@ public SwipeAwareContainerRenderer(Context context) : base(context)
2222

2323
public override bool OnInterceptTouchEvent(MotionEvent ev)
2424
{
25-
_gestureDetector.OnTouchEvent(ev);
25+
if (Element is SwipeAwareContainer element && !element.SwipeDetectionDisabled)
26+
_gestureDetector.OnTouchEvent(ev);
27+
2628
return base.OnInterceptTouchEvent(ev);
2729
}
2830

src/Calendar.Plugin/CalendarPlugin.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
<LangVersion>latest</LangVersion>
2727
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
2828

29-
<!--<GenerateDocumentationFile Condition=" '$(Configuration)' == 'Release' ">true</GenerateDocumentationFile>-->
29+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
3030
<DefineConstants>$(DefineConstants);</DefineConstants>
3131
<RepositoryType>git</RepositoryType>
3232
<PackageLicenseExpression>MIT</PackageLicenseExpression>

src/Calendar.Plugin/Shared/Controls/Calendar.xaml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@
2626
<controls:SwipeAwareContainer
2727
VerticalOptions="FillAndExpand"
2828
HorizontalOptions="FillAndExpand"
29-
SwipedLeft="NextMonthClicked"
30-
SwipedRight="PrevMonthClicked"
31-
SwipedUp="OnShowHideTapped">
29+
SwipeDetectionDisabled="{Binding DisableSwipeDetection, Source={x:Reference calendar}}"
30+
SwipedLeft="OnSwipedLeft"
31+
SwipedRight="OnSwipedRight"
32+
SwipedUp="OnSwipedUp">
3233
<controls:MonthDaysView
3334
x:Name="monthDaysView"
3435
Month="{Binding Month, Source={x:Reference calendar}}"

src/Calendar.Plugin/Shared/Controls/Calendar.xaml.cs

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,43 @@ public Style DaysTitleLabelStyle
312312
set => SetValue(DaysTitleLabelStyleProperty, value);
313313
}
314314

315+
/// <summary> Bindable propety for DisableSwipeDetection </summary>
316+
public static readonly BindableProperty DisableSwipeDetectionProperty =
317+
BindableProperty.Create(nameof(DisableSwipeDetection), typeof(bool), typeof(Calendar), false);
318+
319+
/// <summary>
320+
/// <para> Disables the swipe detection (needs testing on iOS) </para>
321+
/// Could be useful if your superview has its own swipe-detection logic.
322+
/// Also see if <seealso cref="SwipeUpCommand"/>, <seealso cref="SwipeUpActionEnabled"/> is useful to you.
323+
/// </summary>
324+
public bool DisableSwipeDetection
325+
{
326+
get => (bool)GetValue(DisableSwipeDetectionProperty);
327+
set => SetValue(DisableSwipeDetectionProperty, value);
328+
}
329+
330+
/// <summary> Bindable property for SwipeUpCommand </summary>
331+
public static readonly BindableProperty SwipeUpCommandProperty =
332+
BindableProperty.Create(nameof(SwipeUpCommand), typeof(ICommand), typeof(Calendar), null);
333+
334+
/// <summary> Activated when user swipes-up over days view </summary>
335+
public ICommand SwipeUpCommand
336+
{
337+
get => (ICommand)GetValue(SwipeUpCommandProperty);
338+
set => SetValue(SwipeUpCommandProperty, value);
339+
}
340+
341+
/// <summary> Bindable property for SwipeUpActionEnabled </summary>
342+
public static readonly BindableProperty SwipeUpActionEnabledProperty =
343+
BindableProperty.Create(nameof(SwipeUpActionEnabled), typeof(bool), typeof(Calendar), true);
344+
345+
/// <summary> Enable/disable default swipe-up action for showing/hiding calendar </summary>
346+
public bool SwipeUpActionEnabled
347+
{
348+
get => (bool)GetValue(SwipeUpActionEnabledProperty);
349+
set => SetValue(SwipeUpActionEnabledProperty, value);
350+
}
351+
315352
#endregion
316353

317354
private const uint CalendarSectionAnimationRate = 16;
@@ -322,6 +359,9 @@ public Style DaysTitleLabelStyle
322359
private bool _calendarSectionAnimating;
323360
private double _calendarSectionHeight;
324361

362+
/// <summary>
363+
/// Calendar plugin for Xamarin.Forms
364+
/// </summary>
325365
public Calendar()
326366
{
327367
PrevMonthCommand = new Command(PrevMonth);
@@ -457,20 +497,19 @@ private void OnCalendarContainerSizeChanged(object sender, EventArgs e)
457497
UpdateCalendarSectionHeight();
458498
}
459499

460-
private void PrevMonthClicked(object sender, EventArgs e)
500+
private void OnSwipedRight(object sender, EventArgs e)
461501
=> PrevMonth();
462502

463-
private void NextMonthClicked(object sender, EventArgs e)
503+
private void OnSwipedLeft(object sender, EventArgs e)
464504
=> NextMonth();
465505

466-
private void PrevYearClicked(object sender, EventArgs e)
467-
=> PrevYear();
468-
469-
private void NextYearClicked(object sender, EventArgs e)
470-
=> NextYear();
506+
private void OnSwipedUp(object sender, EventArgs e)
507+
{
508+
SwipeUpCommand?.Execute(null);
471509

472-
private void OnShowHideTapped(object sender, EventArgs e)
473-
=> ToggleCalendarSectionVisibility();
510+
if (SwipeUpActionEnabled)
511+
ToggleCalendarSectionVisibility();
512+
}
474513

475514
#endregion
476515

src/Calendar.Plugin/Shared/Controls/SwipeAwareContainer.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,17 @@
33

44
namespace Xamarin.Plugin.Calendar.Controls
55
{
6-
public class SwipeAwareContainer: ContentView
6+
public class SwipeAwareContainer : ContentView
77
{
8+
public static readonly BindableProperty SwipeDetectionDisabledProperty =
9+
BindableProperty.Create(nameof(SwipeDetectionDisabled), typeof(bool), typeof(SwipeAwareContainer), false);
10+
11+
public bool SwipeDetectionDisabled
12+
{
13+
get => (bool)GetValue(SwipeDetectionDisabledProperty);
14+
set => SetValue(SwipeDetectionDisabledProperty, value);
15+
}
16+
817
public SwipeAwareContainer() : base()
918
{ }
1019

src/Calendar.Plugin/iOS/SwipeAwareContainerRenderer.cs

Lines changed: 63 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
using UIKit;
1+
using System;
2+
using System.ComponentModel;
3+
using System.Linq;
4+
using UIKit;
25
using Xamarin.Forms;
36
using Xamarin.Forms.Platform.iOS;
47
using Xamarin.Plugin.Calendar.Controls;
@@ -22,30 +25,77 @@ public SwipeAwareContainerRenderer()
2225
_downGestureRecognizer = new UISwipeGestureRecognizer(() => (Element as SwipeAwareContainer)?.OnSwipeDown()) { Direction = UISwipeGestureRecognizerDirection.Down};
2326
}
2427

28+
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
29+
{
30+
base.OnElementPropertyChanged(sender, e);
31+
32+
if (!(Element is SwipeAwareContainer element))
33+
return;
34+
35+
switch (e.PropertyName)
36+
{
37+
case nameof(SwipeAwareContainer.SwipeDetectionDisabled):
38+
if (element.SwipeDetectionDisabled)
39+
RemoveGestureRecognizers();
40+
else
41+
AddGestureRecognizers();
42+
break;
43+
}
44+
}
45+
2546
protected override void OnElementChanged(ElementChangedEventArgs<ContentView> e)
2647
{
2748
base.OnElementChanged(e);
2849

29-
var control = NativeView;
30-
31-
if (control == null)
50+
if (NativeView == null)
3251
return;
3352

3453
if (e.NewElement != null)
54+
AddGestureRecognizers();
55+
56+
if (e.OldElement != null)
57+
RemoveGestureRecognizers();
58+
}
59+
60+
private void AddGestureRecognizers()
61+
{
62+
try
3563
{
36-
control.AddGestureRecognizer(_rightGestureRecognizer);
37-
control.AddGestureRecognizer(_leftGestureRecognizer);
38-
control.AddGestureRecognizer(_upGestureRecognizer);
39-
control.AddGestureRecognizer(_downGestureRecognizer);
64+
if (!NativeView.GestureRecognizers.Contains(_rightGestureRecognizer))
65+
NativeView.AddGestureRecognizer(_rightGestureRecognizer);
66+
67+
if (!NativeView.GestureRecognizers.Contains(_leftGestureRecognizer))
68+
NativeView.AddGestureRecognizer(_leftGestureRecognizer);
69+
70+
if (!NativeView.GestureRecognizers.Contains(_upGestureRecognizer))
71+
NativeView.AddGestureRecognizer(_upGestureRecognizer);
72+
73+
if (!NativeView.GestureRecognizers.Contains(_downGestureRecognizer))
74+
NativeView.AddGestureRecognizer(_downGestureRecognizer);
4075
}
76+
catch (Exception)
77+
{ }
78+
}
4179

42-
if (e.OldElement != null)
80+
private void RemoveGestureRecognizers()
81+
{
82+
try
4383
{
44-
control.RemoveGestureRecognizer(_rightGestureRecognizer);
45-
control.RemoveGestureRecognizer(_leftGestureRecognizer);
46-
control.RemoveGestureRecognizer(_upGestureRecognizer);
47-
control.RemoveGestureRecognizer(_downGestureRecognizer);
84+
if (NativeView.GestureRecognizers.Contains(_rightGestureRecognizer))
85+
NativeView.RemoveGestureRecognizer(_rightGestureRecognizer);
86+
87+
if (NativeView.GestureRecognizers.Contains(_leftGestureRecognizer))
88+
NativeView.RemoveGestureRecognizer(_leftGestureRecognizer);
89+
90+
if (NativeView.GestureRecognizers.Contains(_upGestureRecognizer))
91+
NativeView.RemoveGestureRecognizer(_upGestureRecognizer);
92+
93+
if (NativeView.GestureRecognizers.Contains(_downGestureRecognizer))
94+
NativeView.RemoveGestureRecognizer(_downGestureRecognizer);
4895
}
96+
catch (Exception)
97+
{ }
4998
}
99+
50100
}
51101
}

0 commit comments

Comments
 (0)