Skip to content

Commit

Permalink
feat(ios/android): be able to drag and drop without explicit editing …
Browse files Browse the repository at this point in the history
…mode (#13472)

* feat(ios): be able to drag and drop without explicit editing mode

* fix: fix format

* fix(cli): fix swiftlint warning

* fix(ios): fix item provider config and proxy setup

* fix(ios): fix linting

* feat(android): don’t require editing mode to drag and drop cells

* fix: fix selection issue

* Update ListView.yml

* Update ListView.yml

* fix: fix setter

* fix(ios): fix setter call
  • Loading branch information
hansemannn committed Jul 11, 2022
1 parent d60baec commit a742403
Show file tree
Hide file tree
Showing 12 changed files with 70 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -948,7 +948,7 @@ private void processProperty(String name, Object value)
if (name.equals(TiC.PROPERTY_DATA) || name.equals(TiC.PROPERTY_SECTIONS)) {
setData((Object[]) value);

} else if (name.equals(TiC.PROPERTY_EDITING)) {
} else if (name.equals(TiC.PROPERTY_EDITING) || name.equals(TiC.PROPERTY_REQUIRES_EDITING_TO_MOVE)) {
final TiViewProxy parent = getParent();

if (parent != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,11 @@ public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull Recycle
*/
private boolean isEditing()
{
return this.recyclerViewProxy.getProperties().optBoolean(TiC.PROPERTY_EDITING, false);
boolean isEditing = this.recyclerViewProxy.getProperties().optBoolean(TiC.PROPERTY_EDITING, false);
boolean requiresEditingToMove =
this.recyclerViewProxy.getProperties().optBoolean(TiC.PROPERTY_REQUIRES_EDITING_TO_MOVE, true);

return isEditing || !requiresEditingToMove;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,12 @@ public void bind(final ListItemProxy proxy, final boolean selected)
final int minHeight = TiConvert.toTiDimension(rawMinHeight, TiDimension.TYPE_HEIGHT).getAsPixels(itemView);
this.content.setMinimumHeight(minHeight);

boolean canEdit = listViewProperties.optBoolean(TiC.PROPERTY_EDITING, false)
|| !listViewProperties.optBoolean(TiC.PROPERTY_REQUIRES_EDITING_TO_MOVE, true);

// Handle selection checkmark.
if (listViewProperties.optBoolean(TiC.PROPERTY_SHOW_SELECTION_CHECK, false)
&& listViewProperties.optBoolean(TiC.PROPERTY_EDITING, false)
&& canEdit
&& listViewProperties.optBoolean(TiC.PROPERTY_ALLOWS_SELECTION_DURING_EDITING, false)
&& listViewProperties.optBoolean(TiC.PROPERTY_ALLOWS_MULTIPLE_SELECTION_DURING_EDITING, false)
&& !proxy.isPlaceholder()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
TiC.PROPERTY_HEADER_TITLE,
TiC.PROPERTY_HEADER_VIEW,
TiC.PROPERTY_REFRESH_CONTROL,
TiC.PROPERTY_REQUIRES_EDITING_TO_MOVE,
TiC.PROPERTY_SEARCH_TEXT,
TiC.PROPERTY_SEARCH_VIEW,
TiC.PROPERTY_SEPARATOR_COLOR,
Expand Down Expand Up @@ -524,7 +525,8 @@ private void processProperty(String name, Object value)
// Set list sections.
setSections((Object[]) value);

} else if (name.equals(TiC.PROPERTY_EDITING) || name.equals(TiC.PROPERTY_VISIBLE)) {
} else if (name.equals(TiC.PROPERTY_EDITING) || name.equals(TiC.PROPERTY_REQUIRES_EDITING_TO_MOVE)
|| name.equals(TiC.PROPERTY_VISIBLE)) {
final TiViewProxy parent = getParent();

if (parent != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,14 +264,15 @@ public boolean inSelectionHotspot(@NonNull MotionEvent e)

final KrollDict properties = proxy.getProperties();
final boolean editing = properties.optBoolean(TiC.PROPERTY_EDITING, false);
final boolean requiresEditingToMove = properties.optBoolean(TiC.PROPERTY_REQUIRES_EDITING_TO_MOVE, true);
final boolean allowsSelection = properties.optBoolean(TiC.PROPERTY_ALLOWS_SELECTION_DURING_EDITING, false);
final boolean allowsMultipleSelection
= properties.optBoolean(TiC.PROPERTY_ALLOWS_MULTIPLE_SELECTION_DURING_EDITING, false);

if (properties.optBoolean(TiC.PROPERTY_FIXED_SIZE, false)) {
this.recyclerView.setHasFixedSize(true);
}
if (editing && allowsSelection) {
if ((editing || !requiresEditingToMove) && allowsSelection) {
if (allowsMultipleSelection) {
this.tracker = trackerBuilder.withSelectionPredicate(SelectionPredicates.createSelectAnything())
.build();
Expand Down Expand Up @@ -767,13 +768,15 @@ public void run()

if (firstUpdate && tracker != null) {
final boolean editing = properties.optBoolean(TiC.PROPERTY_EDITING, false);
final boolean requiresEditingToMove =
properties.optBoolean(TiC.PROPERTY_REQUIRES_EDITING_TO_MOVE, true);

for (final ListItemProxy item : items) {

// Re-select previously selected items.
// This can occur when the theme is changed.
if (item.isSelected()) {
if (!editing) {
if (!editing || requiresEditingToMove) {
item.setSelected(false);
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,7 @@ public class TiC
public static final String PROPERTY_REPEAT_COUNT = "repeatCount";
public static final String PROPERTY_REPEAT_MODE = "repeatMode";
public static final String PROPERTY_REQUEST_HEADERS = "requestHeaders";
public static final String PROPERTY_REQUIRES_EDITING_TO_MOVE = "requiresEditingToMove";
public static final String PROPERTY_RETURN_KEY_TYPE = "returnKeyType";
public static final String PROPERTY_REVERSE = "reverse";
public static final String PROPERTY_RIGHT = "right";
Expand Down
12 changes: 12 additions & 0 deletions apidoc/Titanium/UI/ListView.yml
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,9 @@ description: |
- [editing](Titanium.UI.ListView.editing) - Determines if the List View is in a state where items can
be deleted or reordered.
- [requiresEditingToMove](Titanium.UI.ListView.requiresEditingToMove) - Determines if the ListView
should be able to drag-and-drop without explicitely enabling editing support (like drag bars).
- [pruneSectionsOnEdit](Titanium.UI.ListView.pruneSectionsOnEdit) - When this property is set to true and the
user action results in a section having no other items, the section is deleted from the List View. Please note
Expand Down Expand Up @@ -675,6 +678,15 @@ properties:
since: {android: "9.3.0", iphone: "3.2.0", ipad: "3.2.0", macos: "9.2.0"}
platforms: [android, iphone, ipad, macos]

- name: requiresEditingToMove
summary: Determines if the list view should allow drag-and-drop even without going into the editing mode
description: |
For more information see the "Editing Support" section of <Titanium.UI.ListView>.
type: Boolean
default: true
since: "11.1.0"
platforms: [android, iphone, ipad, macos]

- name: fastScroll
summary: Sets the fastScroll mode on Android ListViews.
description: |
Expand Down
2 changes: 1 addition & 1 deletion iphone/Classes/TiUIListView.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#import "TiUIListViewProxy.h"
#import <TitaniumKit/TiUIView.h>

@interface TiUIListView : TiUIView <UITableViewDelegate, UITableViewDataSource, UITableViewDataSourcePrefetching, UIScrollViewDelegate, UIGestureRecognizerDelegate, UISearchBarDelegate, UISearchResultsUpdating, UISearchControllerDelegate, TiScrolling, TiProxyObserver, TiUIListViewDelegateView>
@interface TiUIListView : TiUIView <UITableViewDelegate, UITableViewDataSource, UITableViewDataSourcePrefetching, UIScrollViewDelegate, UIGestureRecognizerDelegate, UISearchBarDelegate, UISearchResultsUpdating, UISearchControllerDelegate, TiScrolling, TiProxyObserver, TiUIListViewDelegateView, UITableViewDragDelegate, UITableViewDropDelegate>

#pragma mark - Private APIs

Expand Down
35 changes: 35 additions & 0 deletions iphone/Classes/TiUIListView.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#ifdef USE_TI_UIREFRESHCONTROL
#import "TiUIRefreshControlProxy.h"
#endif
#import <MobileCoreServices/MobileCoreServices.h>
#import <TitaniumKit/ImageLoader.h>

@interface TiUIListView ()
Expand Down Expand Up @@ -203,12 +204,19 @@ - (UITableView *)tableView
{
if (_tableView == nil) {
UITableViewStyle style = [TiUtils intValue:[self.proxy valueForKey:@"style"] def:UITableViewStylePlain];
BOOL requiresEditingToMove = [TiUtils boolValue:[self.proxy valueForKey:@"requiresEditingToMove"] def:YES];

_tableView = [[UITableView alloc] initWithFrame:self.bounds style:style];
_tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
_tableView.delegate = self;
_tableView.dataSource = self;

if (!requiresEditingToMove) {
_tableView.dragDelegate = self;
_tableView.dropDelegate = self;
_tableView.dragInteractionEnabled = YES;
}

// Fixes incorrect heights in iOS 11 as we calculate them internally already
_tableView.estimatedRowHeight = 0;
_tableView.estimatedSectionFooterHeight = 0;
Expand Down Expand Up @@ -2553,6 +2561,33 @@ + (UITableViewRowAnimation)animationStyleForProperties:(NSDictionary *)propertie
return animate ? UITableViewRowAnimationFade : UITableViewRowAnimationNone;
}

- (nonnull NSArray<UIDragItem *> *)tableView:(nonnull UITableView *)tableView itemsForBeginningDragSession:(nonnull id<UIDragSession>)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<UITableViewDropCoordinator>)coordinator
{
// NO-OP right now
}

- (BOOL)tableView:(UITableView *)tableView canHandleDropSession:(id<UIDropSession>)session
{
return [session canLoadObjectsOfClass:[NSString class]];
}

@end

static TiViewProxy *FindViewProxyWithBindIdContainingPoint(UIView *view, CGPoint point)
Expand Down
2 changes: 1 addition & 1 deletion iphone/Classes/TiUIListViewProxy.m
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ - (NSArray *)keySequence
static dispatch_once_t onceToken;
static NSArray *keySequence = nil;
dispatch_once(&onceToken, ^{
keySequence = [[NSArray alloc] initWithObjects:@"style", @"showSearchBarInNavBar", @"templates", @"defaultItemTemplate", @"sections", @"backgroundColor", nil];
keySequence = [[NSArray alloc] initWithObjects:@"style", @"requiresEditingToMove", @"showSearchBarInNavBar", @"templates", @"defaultItemTemplate", @"sections", @"backgroundColor", nil];
});
return keySequence;
}
Expand Down
2 changes: 1 addition & 1 deletion lint-staged.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ module.exports = {
'npx clang-format -style=file -i'
],
'iphone/Classes/**/*.swift': [
'swiftlint autocorrect'
'swiftlint --fix'
],
'iphone/TitaniumKit/TitaniumKit/Sources/API/TopTiModule.m': [
'npm run ios-sanity-check --'
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"format:android": "echo Formatting Android code is not supported.",
"format:ios": "npm-run-all --parallel format:objc format:swift",
"format:objc": "npm run lint:objc -- --fix",
"format:swift": "npm run lint:swift -- autocorrect",
"format:swift": "npm run lint:swift",
"format:js": "npm run lint:js -- --fix",
"ios": "node ./build/scons cleanbuild ios",
"ios-sanity-check": "node ./build/scons check-ios-toplevel",
Expand Down

0 comments on commit a742403

Please sign in to comment.