diff --git a/android/modules/ui/src/java/ti/modules/titanium/ui/TableViewProxy.java b/android/modules/ui/src/java/ti/modules/titanium/ui/TableViewProxy.java index 0a9e46ecceb..9ea2a668027 100644 --- a/android/modules/ui/src/java/ti/modules/titanium/ui/TableViewProxy.java +++ b/android/modules/ui/src/java/ti/modules/titanium/ui/TableViewProxy.java @@ -325,6 +325,21 @@ public void onMoveItemEnded(int adapterIndex) } } } + /** + * Called when starting a drag-and-drop gesture (touch start) + */ + public void onMoveGestureStarted() + { + fireEvent(TiC.EVENT_MOVE_START, null); + } + + /** + * Called when starting a drag-and-drop gesture (touch end) + */ + public void onMoveGestureEnded() + { + fireEvent(TiC.EVENT_MOVE_END, null); + } /** * Delete row from table. diff --git a/android/modules/ui/src/java/ti/modules/titanium/ui/widget/listview/ItemTouchHandler.java b/android/modules/ui/src/java/ti/modules/titanium/ui/widget/listview/ItemTouchHandler.java index 0dcea547049..3f2a2de4404 100644 --- a/android/modules/ui/src/java/ti/modules/titanium/ui/widget/listview/ItemTouchHandler.java +++ b/android/modules/ui/src/java/ti/modules/titanium/ui/widget/listview/ItemTouchHandler.java @@ -39,6 +39,7 @@ public class ItemTouchHandler extends ItemTouchHelper.SimpleCallback private int moveEndIndex = -1; private Drawable icon; private final ColorDrawable background; + private boolean hasMoveStarted = false; @SuppressLint("ClickableViewAccessibility") public ItemTouchHandler(@NonNull TiRecyclerViewAdapter adapter, @@ -56,7 +57,13 @@ public ItemTouchHandler(@NonNull TiRecyclerViewAdapter adapter, @Override public boolean onTouch(View v, MotionEvent event) { - if (event.getAction() == MotionEvent.ACTION_UP) { + if (event.getAction() == MotionEvent.ACTION_MOVE && !hasMoveStarted) { + recyclerViewProxy.onMoveGestureStarted(); + hasMoveStarted = true; + } else if (event.getAction() == MotionEvent.ACTION_UP) { + recyclerViewProxy.onMoveGestureEnded(); + hasMoveStarted = false; + if (moveEndIndex >= 0) { // Notify owner that item movement has ended. Will fire a "move" event. recyclerViewProxy.onMoveItemEnded(moveEndIndex); diff --git a/android/modules/ui/src/java/ti/modules/titanium/ui/widget/listview/ListViewProxy.java b/android/modules/ui/src/java/ti/modules/titanium/ui/widget/listview/ListViewProxy.java index 98badc567ab..ca309ce8fcd 100644 --- a/android/modules/ui/src/java/ti/modules/titanium/ui/widget/listview/ListViewProxy.java +++ b/android/modules/ui/src/java/ti/modules/titanium/ui/widget/listview/ListViewProxy.java @@ -274,6 +274,22 @@ public void onMoveItemEnded(int adapterIndex) this.moveEventInfo.clear(); } + /** + * Called when starting a drag-and-drop gesture (touch start) + */ + public void onMoveGestureStarted() + { + fireEvent(TiC.EVENT_MOVE_START, null); + } + + /** + * Called when starting a drag-and-drop gesture (touch end) + */ + public void onMoveGestureEnded() + { + fireEvent(TiC.EVENT_MOVE_END, null); + } + /** * Remove section from list at specified index. * diff --git a/android/modules/ui/src/java/ti/modules/titanium/ui/widget/listview/RecyclerViewProxy.java b/android/modules/ui/src/java/ti/modules/titanium/ui/widget/listview/RecyclerViewProxy.java index fb0e88cda5e..2739ef161be 100644 --- a/android/modules/ui/src/java/ti/modules/titanium/ui/widget/listview/RecyclerViewProxy.java +++ b/android/modules/ui/src/java/ti/modules/titanium/ui/widget/listview/RecyclerViewProxy.java @@ -19,4 +19,8 @@ public abstract class RecyclerViewProxy extends TiViewProxy public abstract boolean onMoveItemStarting(int index); public abstract void onMoveItemEnded(int index); + + public abstract void onMoveGestureStarted(); + + public abstract void onMoveGestureEnded(); } diff --git a/android/titanium/src/java/org/appcelerator/titanium/TiC.java b/android/titanium/src/java/org/appcelerator/titanium/TiC.java index 0383567645a..05d05ea5bd5 100644 --- a/android/titanium/src/java/org/appcelerator/titanium/TiC.java +++ b/android/titanium/src/java/org/appcelerator/titanium/TiC.java @@ -147,6 +147,8 @@ public class TiC public static final String EVENT_PROPERTY_FORCE = "force"; public static final String EVENT_PROPERTY_SIZE = "size"; public static final String EVENT_MOVE = "move"; + public static final String EVENT_MOVE_START = "movestart"; + public static final String EVENT_MOVE_END = "moveend"; public static final String EVENT_REFRESH_END = "refreshend"; public static final String EVENT_REFRESH_START = "refreshstart"; public static final String EVENT_REGION_CHANGED = "regionchanged"; diff --git a/apidoc/Titanium/UI/ListView.yml b/apidoc/Titanium/UI/ListView.yml index fe6d82ed924..e300ac1c2a5 100644 --- a/apidoc/Titanium/UI/ListView.yml +++ b/apidoc/Titanium/UI/ListView.yml @@ -384,6 +384,20 @@ events: summary: section item index of the reference item. type: Number + - name: movestart + summary: Fired when a list row has started moving. + description: | + This property can be used to change the UI once a new drag-and-drop interaction starts. + since: "11.1.0" + platforms: [android, iphone, ipad, macos] + + - name: moveend + summary: Fired when a list row has ended moving. + description: | + This property can be used to change the UI once a drag-and-drop interaction ends. + since: "11.1.0" + platforms: [android, iphone, ipad, macos] + - name: move summary: Fired when a list row is moved to a different location by the user. description: | diff --git a/iphone/Classes/TiUIListView.m b/iphone/Classes/TiUIListView.m index fb5db53c2aa..aa8c1708c89 100644 --- a/iphone/Classes/TiUIListView.m +++ b/iphone/Classes/TiUIListView.m @@ -1079,17 +1079,52 @@ - (BOOL)canEditRowAtIndexPath:(NSIndexPath *)indexPath - (BOOL)canInsertRowAtIndexPath:(NSIndexPath *)indexPath { id insertValue = [self valueWithKey:@"canInsert" atIndexPath:indexPath]; - //canInsert if undefined is false return [TiUtils boolValue:insertValue def:NO]; } - (BOOL)canMoveRowAtIndexPath:(NSIndexPath *)indexPath { id moveValue = [self valueWithKey:@"canMove" atIndexPath:indexPath]; - //canMove if undefined is false return [TiUtils boolValue:moveValue def:NO]; } +- (nonnull NSArray *)tableView:(nonnull UITableView *)tableView itemsForBeginningDragSession:(nonnull id)session atIndexPath:(nonnull NSIndexPath *)indexPath +{ + NSItemProvider *itemProvider = [NSItemProvider new]; + NSString *identifier = [NSString stringWithFormat:@"%lu_%lu", indexPath.section, indexPath.row]; + + [itemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypePlainText + visibility:NSItemProviderRepresentationVisibilityAll + loadHandler:^NSProgress *_Nullable(void (^_Nonnull completionHandler)(NSData *_Nullable, NSError *_Nullable)) { + return nil; + }]; + + UIDragItem *dragItem = [[UIDragItem alloc] initWithItemProvider:itemProvider]; + dragItem.localObject = identifier; + + return @[ dragItem ]; +} + +- (void)tableView:(UITableView *)tableView dropSessionDidEnter:(id)session +{ + [[self proxy] fireEvent:@"movestart"]; +} + +- (void)tableView:(UITableView *)tableView dropSessionDidEnd:(id)session +{ + [[self proxy] fireEvent:@"moveend"]; +} + +- (void)tableView:(UITableView *)tableView performDropWithCoordinator:(id)coordinator +{ + // NO-OP right now +} + +- (BOOL)tableView:(UITableView *)tableView canHandleDropSession:(id)session +{ + return [session canLoadObjectsOfClass:[NSString class]]; +} + - (NSArray *)editActionsFromValue:(id)value { ENSURE_ARRAY(value); @@ -2561,33 +2596,6 @@ + (UITableViewRowAnimation)animationStyleForProperties:(NSDictionary *)propertie return animate ? UITableViewRowAnimationFade : UITableViewRowAnimationNone; } -- (nonnull NSArray *)tableView:(nonnull UITableView *)tableView itemsForBeginningDragSession:(nonnull id)session atIndexPath:(nonnull NSIndexPath *)indexPath -{ - NSItemProvider *itemProvider = [NSItemProvider new]; - NSString *identifier = [NSString stringWithFormat:@"%lu_%lu", indexPath.section, indexPath.row]; - - [itemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypePlainText - visibility:NSItemProviderRepresentationVisibilityAll - loadHandler:^NSProgress *_Nullable(void (^_Nonnull completionHandler)(NSData *_Nullable, NSError *_Nullable)) { - return nil; - }]; - - UIDragItem *dragItem = [[UIDragItem alloc] initWithItemProvider:itemProvider]; - dragItem.localObject = identifier; - - return @[ dragItem ]; -} - -- (void)tableView:(UITableView *)tableView performDropWithCoordinator:(id)coordinator -{ - // NO-OP right now -} - -- (BOOL)tableView:(UITableView *)tableView canHandleDropSession:(id)session -{ - return [session canLoadObjectsOfClass:[NSString class]]; -} - @end static TiViewProxy *FindViewProxyWithBindIdContainingPoint(UIView *view, CGPoint point)