Skip to content

Commit

Permalink
[iOS] Prevent multiple ListView cells from being swiped simultaneously (
Browse files Browse the repository at this point in the history
xamarin#578)

* disable multiple cell swipe

* add sample code

* refactored

* convert to weakreference

* remove null setting

* change weakreference setting place

* remove if

* revert isopen changes

* add instructions
  • Loading branch information
adrianknight89 authored and rookiejava committed Jan 9, 2017
1 parent fd8f107 commit 649c57f
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System.Collections.Generic;
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;

#if UITEST
using Xamarin.UITest;
using NUnit.Framework;
#endif

namespace Xamarin.Forms.Controls.Issues
{
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Bugzilla, 43735, "Multiple Swipe on ContextActions", PlatformAffected.iOS)]
public class Bugzilla43735 : TestContentPage // or TestMasterDetailPage, etc ...
{
protected override void Init()
{
var stackLayout = new StackLayout();

var l = new Label
{
Text = "Swipe multiple cells at the same time. Only one cell should show its context actions."
};
stackLayout.Children.Add(l);

var list = new List<int>();
for (var i = 0; i < 20; i++)
list.Add(i);

var listView = new ListView
{
ItemsSource = list,
ItemTemplate = new DataTemplate(() =>
{
var label = new Label();
label.SetBinding(Label.TextProperty, new Binding("."));
return new ViewCell
{
View = new ContentView
{
Content = label,
},
ContextActions = { new MenuItem
{
Text = "Action"
},
new MenuItem
{
Text = "Delete",
IsDestructive = true
} }
};
})
};
stackLayout.Children.Add(listView);

Content = stackLayout;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla43469.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla43516.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla43663.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla43735.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla44453.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla44944.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla44166.cs" />
Expand Down
31 changes: 27 additions & 4 deletions Xamarin.Forms.Platform.iOS/ContextScrollViewDelegate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ internal class ContextScrollViewDelegate : UIScrollViewDelegate
GlobalCloseContextGestureRecognizer _globalCloser;

bool _isDisposed;

static WeakReference<UIScrollView> s_scrollViewBeingScrolled;
UITableView _table;

public ContextScrollViewDelegate(UIView container, List<UIButton> buttons, bool isOpen)
Expand All @@ -72,6 +72,11 @@ public ContextScrollViewDelegate(UIView container, List<UIButton> buttons, bool

public override void DraggingStarted(UIScrollView scrollView)
{
if (ShouldIgnoreScrolling(scrollView))
return;

s_scrollViewBeingScrolled = new WeakReference<UIScrollView>(scrollView);

if (!IsOpen)
SetButtonsShowing(true);

Expand All @@ -90,6 +95,9 @@ public void PrepareForDeselect(UIScrollView scrollView)

public override void Scrolled(UIScrollView scrollView)
{
if (ShouldIgnoreScrolling(scrollView))
return;

var width = _finalButtonSize;
var count = _buttons.Count;

Expand All @@ -116,10 +124,9 @@ public override void Scrolled(UIScrollView scrollView)
SetButtonsShowing(false);
RestoreHighlight(scrollView);

s_scrollViewBeingScrolled = null;
ClearCloserRecognizer(scrollView);

if (ClosedCallback != null)
ClosedCallback();
ClosedCallback?.Invoke();
}
}

Expand All @@ -131,6 +138,9 @@ public void Unhook(UIScrollView scrollView)

public override void WillEndDragging(UIScrollView scrollView, PointF velocity, ref PointF targetContentOffset)
{
if (ShouldIgnoreScrolling(scrollView))
return;

var width = ButtonsWidth;
var x = targetContentOffset.X;
var parentThreshold = scrollView.Frame.Width * .4f;
Expand Down Expand Up @@ -187,6 +197,19 @@ public override void WillEndDragging(UIScrollView scrollView, PointF velocity, r
}
}

static bool ShouldIgnoreScrolling(UIScrollView scrollView)
{
if (s_scrollViewBeingScrolled == null)
return false;

UIScrollView scrollViewBeingScrolled;
if (!s_scrollViewBeingScrolled.TryGetTarget(out scrollViewBeingScrolled) || ReferenceEquals(scrollViewBeingScrolled, scrollView))
return false;

scrollView.SetContentOffset(new PointF(0, 0), false);
return true;
}

protected override void Dispose(bool disposing)
{
if (_isDisposed)
Expand Down

0 comments on commit 649c57f

Please sign in to comment.