You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by cx...@apache.org on 2017/03/05 13:22:28 UTC

incubator-weex git commit: * [ios] support delete header in the middle of list dynamicly

Repository: incubator-weex
Updated Branches:
  refs/heads/0.11-dev 8098d7994 -> 21878b0f7


* [ios] support delete header in the middle of list dynamicly


Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/21878b0f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/21878b0f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/21878b0f

Branch: refs/heads/0.11-dev
Commit: 21878b0f7a64b0e8075c65ca925b5a2811e57b40
Parents: 8098d79
Author: cxfeng <cx...@gmail.com>
Authored: Sun Mar 5 21:22:15 2017 +0800
Committer: cxfeng <cx...@gmail.com>
Committed: Sun Mar 5 21:22:15 2017 +0800

----------------------------------------------------------------------
 .../Sources/Component/WXHeaderComponent.h       |   1 +
 .../Sources/Component/WXHeaderComponent.m       |   8 +
 .../WeexSDK/Sources/Component/WXListComponent.m | 148 ++++++++++++-------
 3 files changed, 106 insertions(+), 51 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/21878b0f/ios/sdk/WeexSDK/Sources/Component/WXHeaderComponent.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXHeaderComponent.h b/ios/sdk/WeexSDK/Sources/Component/WXHeaderComponent.h
index 1ac21cc..20245b8 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXHeaderComponent.h
+++ b/ios/sdk/WeexSDK/Sources/Component/WXHeaderComponent.h
@@ -23,5 +23,6 @@
 
 @property (nonatomic, weak) id<WXHeaderRenderDelegate> delegate;
 @property (nonatomic, assign, readonly) BOOL isSticky;
+@property (nonatomic, assign, readonly) BOOL keepScrollPosition;
 
 @end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/21878b0f/ios/sdk/WeexSDK/Sources/Component/WXHeaderComponent.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXHeaderComponent.m b/ios/sdk/WeexSDK/Sources/Component/WXHeaderComponent.m
index 33b3040..a95c645 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXHeaderComponent.m
+++ b/ios/sdk/WeexSDK/Sources/Component/WXHeaderComponent.m
@@ -21,11 +21,19 @@
     if (self) {
         _async = YES;
         _isNeedJoinLayoutSystem = NO;
+        _keepScrollPosition = attributes[@"keepScrollPosition"] ? [WXConvert BOOL:attributes[@"keepScrollPosition"]] : NO;
     }
     
     return self;
 }
 
+- (void)updateAttributes:(NSDictionary *)attributes
+{
+    if (attributes[@"keepScrollPosition"]) {
+        _keepScrollPosition = [WXConvert BOOL:attributes[@"keepScrollPosition"]];
+    }
+}
+
 - (BOOL)isSticky
 {
     return _positionType == WXPositionTypeSticky;

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/21878b0f/ios/sdk/WeexSDK/Sources/Component/WXListComponent.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXListComponent.m b/ios/sdk/WeexSDK/Sources/Component/WXListComponent.m
index 0418ae8..157b68c 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXListComponent.m
+++ b/ios/sdk/WeexSDK/Sources/Component/WXListComponent.m
@@ -224,31 +224,33 @@
         // conditions to insert section: insert a header or insert first cell of table view
         // this will be updated by recycler's update controller in the future
         WXSection *insertSection = [WXSection new];
-        BOOL keepScrollPostion = NO;
+        BOOL keepScrollPosition = NO;
         if ([subcomponent isKindOfClass:[WXHeaderComponent class]]) {
             WXHeaderComponent *header = (WXHeaderComponent*)subcomponent;
             insertSection.header = header;
+            keepScrollPosition = header.keepScrollPosition;
         }
         
         NSUInteger insertIndex = indexPath.section;
         WXSection *reloadSection;
-        if (insertIndex > 0 && insertIndex < _sections.count) {
+        if (insertIndex > 0 && insertIndex <= _sections.count
+            && [subcomponent isKindOfClass:[WXHeaderComponent class]]) {
             // insert a header in the middle, one section may divide into two
             // so the original section need to be reloaded
-            NSArray *rowsToSeparate = reloadSection.rows;
             NSIndexPath *indexPathBeforeHeader = [self indexPathForSubIndex:index - 1];
             if (indexPathBeforeHeader.row != _sections[insertIndex - 1].rows.count - 1) {
                 reloadSection = _sections[insertIndex - 1];
+                NSArray *rowsToSeparate = reloadSection.rows;
                 insertSection.rows = [[rowsToSeparate subarrayWithRange:NSMakeRange(indexPathBeforeHeader.row + 1, rowsToSeparate.count - indexPathBeforeHeader.row - 1)] mutableCopy];
                 reloadSection.rows = [[rowsToSeparate subarrayWithRange:NSMakeRange(0, indexPathBeforeHeader.row + 1)]  mutableCopy];
             }
         }
     
         [_sections insertObject:insertSection atIndex:insertIndex];
-        WXSection *completedInsertSection = [insertSection mutableCopy];
+        WXSection *completedInsertSection = [insertSection copy];
         WXSection *completedReloadSection;
         if (reloadSection) {
-            completedReloadSection = [reloadSection mutableCopy];
+            completedReloadSection = [reloadSection copy];
         }
         
         [self.weexInstance.componentManager _addUITask:^{
@@ -259,16 +261,18 @@
                 _completedSections[insertIndex - 1] = completedReloadSection;
             }
             
-            [_tableView beginUpdates];
-            
             [UIView performWithoutAnimation:^{
-                [self _insertTableViewSectionAtIndex:insertIndex keepScrollPosition:keepScrollPostion animation:UITableViewRowAnimationNone];
+                [_tableView beginUpdates];
+                
+                [self _insertTableViewSectionAtIndex:insertIndex keepScrollPosition:keepScrollPosition animation:UITableViewRowAnimationNone];
+                
                 if (completedReloadSection) {
-                    [_tableView reloadSections:[NSIndexSet indexSetWithIndex:index - 1] withRowAnimation:UITableViewRowAnimationNone];
+                    [_tableView reloadSections:[NSIndexSet indexSetWithIndex:insertIndex - 1] withRowAnimation:UITableViewRowAnimationNone];
                 }
+                
+                [_tableView endUpdates];
             }];
             
-            [_tableView endUpdates];
         }];
     }
 }
@@ -300,7 +304,43 @@
 
 - (void)headerDidRemove:(WXHeaderComponent *)header
 {
+    NSUInteger deleteIndex = [self indexForHeader:header sections:_sections];
+    // this will be updated by recycler's update controller in the future
+    WXSection *deleteSection = _sections[deleteIndex];
+    WXSection *reloadSection;
+    if (deleteIndex > 0 && deleteSection.rows.count > 0) {
+        // delete a header in the middle, two sections merge into one
+        // so the one section need to be reloaded
+        reloadSection = _sections[deleteIndex - 1];
+        reloadSection.rows = [[reloadSection.rows arrayByAddingObjectsFromArray:deleteSection.rows] mutableCopy];
+    }
     
+    [_sections removeObjectAtIndex:deleteIndex];
+    WXSection *completedReloadSection;
+    if (reloadSection) {
+        completedReloadSection = [reloadSection copy];
+    }
+    BOOL keepScrollPosition = header.keepScrollPosition;
+    
+    [self.weexInstance.componentManager _addUITask:^{
+        WXLogDebug(@"delete section:%ld", deleteIndex);
+        [_completedSections removeObjectAtIndex:deleteIndex];
+        if (completedReloadSection) {
+            WXLogDebug(@"Reload section:%ld", deleteIndex - 1);
+            _completedSections[deleteIndex - 1] = completedReloadSection;
+        }
+        
+        [UIView performWithoutAnimation:^{
+            [_tableView beginUpdates];
+            [self _deleteTableViewSectionAtIndex:deleteIndex keepScrollPosition:keepScrollPosition animation:UITableViewRowAnimationNone];
+            if (completedReloadSection) {
+                [_tableView reloadSections:[NSIndexSet indexSetWithIndex:deleteIndex - 1] withRowAnimation:UITableViewRowAnimationNone];
+            }
+            
+            [_tableView endUpdates];
+        }];
+        
+    }];
 }
 
 #pragma mark - WXCellRenderDelegate
@@ -652,71 +692,77 @@
     return [NSIndexPath indexPathForRow:row inSection:section];
 }
 
-- (void)_insertTableViewSectionAtIndex:(NSUInteger)section keepScrollPosition:(BOOL)keepScrollPosition animation:(UITableViewRowAnimation)animation
+- (void)_performUpdates:(void(^)())updates withKeepScrollPosition:(BOOL)keepScrollPosition adjustmentBlock:(CGFloat(^)(NSIndexPath *topVisibleCell))adjustmentBlock
 {
     CGFloat adjustment = 0;
     
-    // keep the scroll position when inserting or deleting cells by adjusting the content offset
+    // keep the scroll position when inserting or deleting sections/rows by adjusting the content offset
     if (keepScrollPosition) {
         NSIndexPath *top = _tableView.indexPathsForVisibleRows.firstObject;
-        if (section <= top.section) {
-            adjustment = [self tableView:_tableView heightForHeaderInSection:section];
-        }
+        adjustment = adjustmentBlock(top);
     }
-
-    [_tableView insertSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:animation];
+    
+    updates();
     
     if (keepScrollPosition) {
         CGPoint afterContentOffset = _tableView.contentOffset;
         CGPoint newContentOffset = CGPointMake(afterContentOffset.x, afterContentOffset.y + adjustment);
         _tableView.contentOffset = newContentOffset;
     }
+    
+    [self handleAppear];
+}
+
+- (void)_insertTableViewSectionAtIndex:(NSUInteger)section keepScrollPosition:(BOOL)keepScrollPosition animation:(UITableViewRowAnimation)animation
+{
+    [self _performUpdates:^{
+        [_tableView insertSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:animation];
+    } withKeepScrollPosition:keepScrollPosition adjustmentBlock:^CGFloat(NSIndexPath *top) {
+        if (section <= top.section) {
+            return [self tableView:_tableView heightForHeaderInSection:section];
+        } else {
+            return 0.0;
+        }
+    }];
+}
+
+- (void)_deleteTableViewSectionAtIndex:(NSUInteger)section keepScrollPosition:(BOOL)keepScrollPosition animation:(UITableViewRowAnimation)animation
+{
+    [self _performUpdates:^{
+        [_tableView deleteSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:animation];
+    } withKeepScrollPosition:keepScrollPosition adjustmentBlock:^CGFloat(NSIndexPath *top) {
+        if (section <= top.section) {
+            return [self tableView:_tableView heightForHeaderInSection:section];
+        } else {
+            return 0.0;
+        }
+    }];
 }
 
 - (void)_insertTableViewCellAtIndexPath:(NSIndexPath *)indexPath keepScrollPosition:(BOOL)keepScrollPosition animation:(UITableViewRowAnimation)animation
 {
-    CGFloat adjustment = 0;
-    
-    // keep the scroll position when inserting or deleting cells by adjusting the content offset
-    if (keepScrollPosition) {
-        NSIndexPath *top = _tableView.indexPathsForVisibleRows.firstObject;
+    [self _performUpdates:^{
+        [_tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:animation];
+    } withKeepScrollPosition:keepScrollPosition adjustmentBlock:^CGFloat(NSIndexPath *top) {
         if ([indexPath compare:top] <= 0) {
-            adjustment = [self tableView:_tableView heightForRowAtIndexPath:indexPath];
+            return [self tableView:_tableView heightForRowAtIndexPath:indexPath];
+        } else {
+            return 0.0;
         }
-    }
-    
-    [_tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:animation];
-    
-    if (keepScrollPosition) {
-        CGPoint afterContentOffset = _tableView.contentOffset;
-        CGPoint newContentOffset = CGPointMake(afterContentOffset.x, afterContentOffset.y + adjustment);
-        _tableView.contentOffset = newContentOffset;
-    }
-    
-    [self handleAppear];
+    }];
 }
 
 - (void)_deleteTableViewCellAtIndexPath:(NSIndexPath *)indexPath keepScrollPosition:(BOOL)keepScrollPosition animation:(UITableViewRowAnimation)animation
 {
-    CGFloat adjustment = 0;
-    
-    // keep the scroll position when inserting or deleting cells by adjusting the content offset
-    if (keepScrollPosition) {
-        NSIndexPath *top = _tableView.indexPathsForVisibleRows.firstObject;
+    [self _performUpdates:^{
+        [_tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:animation];
+    } withKeepScrollPosition:keepScrollPosition adjustmentBlock:^CGFloat(NSIndexPath *top) {
         if ([indexPath compare:top] <= 0) {
-            adjustment = [self tableView:_tableView heightForRowAtIndexPath:indexPath];
+            return [self tableView:_tableView heightForRowAtIndexPath:indexPath];
+        } else {
+            return 0.0;
         }
-    }
-    
-    [_tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:animation];
-    
-    if (keepScrollPosition) {
-        CGPoint afterContentOffset = _tableView.contentOffset;
-        CGPoint newContentOffset = CGPointMake(afterContentOffset.x, afterContentOffset.y - adjustment > 0 ? afterContentOffset.y - adjustment : 0);
-        _tableView.contentOffset = newContentOffset;
-    }
-    
-    [self handleAppear];
+    }];
 }
 
 - (void)fixFlicker