bm-core-ui 2.8.2 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/@types/index.d.ts +327 -31
- package/build/BMCollectionView/BMCollectionView.js +33 -16
- package/build/BMCollectionView/BMCollectionViewFlowLayout.js +159 -39
- package/build/BMCollectionView/BMCollectionViewLayout.js +4 -1
- package/build/BMCoreUI.css +161 -13
- package/build/BMView/BMLayoutConstraint_v2.5.js +1 -1
- package/build/BMView/BMMenu.js +790 -65
- package/build/BMView/BMScrollView.js +1 -1
- package/build/BMView/BMTextFieldDelegate.js +6 -6
- package/build/BMViewLayoutEditor/BMLayoutEditorSettingCells.js +2 -2
- package/build/BMViewLayoutEditor/BMLayoutEditorViewSettings.js +5 -2
- package/build/BMWindow/BMConfirmationPopup.js +21 -1
- package/build/BMWindow/BMPopover/BMPopover.js +310 -52
- package/build/BMWindow/BMWindow.js +61 -18
- package/lib/@types/BMCoreUI.min.d.ts +327 -31
- package/lib/BMCoreUI.min.js +1 -1
- package/package.json +1 -1
- package/CHANGELOG.md +0 -1739
- package/build/BMViewLayoutEditor/BMLayoutEditorDelegate.js +0 -59
- package/build/BMViewLayoutEditor/BMLayoutEditorSettingsDelegate.js +0 -46
- package/build/BMViewLayoutEditor/BMLayoutVariableProvider.js +0 -202
|
@@ -4,7 +4,7 @@ import {YES, NO, BMExtend, BMScrollBarGetSize, BMAddSmoothMousewheelInteractionT
|
|
|
4
4
|
import {BMInset} from '../Core/BMInset'
|
|
5
5
|
import {BMPointMake} from '../Core/BMPoint'
|
|
6
6
|
import {BMSizeMake} from '../Core/BMSize'
|
|
7
|
-
import {BMRect, BMRectMake, BMRectMakeWithNodeFrame, BMRectByInterpolatingRect} from '../Core/BMRect'
|
|
7
|
+
import {BMRect, BMRectMake, BMRectMakeWithNodeFrame, BMRectMakeWithOrigin, BMRectByInterpolatingRect} from '../Core/BMRect'
|
|
8
8
|
import {BMIndexPathNone} from '../Core/BMIndexPath'
|
|
9
9
|
import {BMAnimateWithBlock, BMAnimationContextBeginStatic, BMAnimationContextGetCurrent, BMAnimationContextAddCompletionHandler, BMAnimationApply, __BMVelocityAnimate, BMHook} from '../Core/BMAnimationContext'
|
|
10
10
|
import {BMView, BMViewLayoutQueue} from '../BMView/BMView_v2.5'
|
|
@@ -693,7 +693,7 @@ BMCollectionView.prototype = BMExtend(BM_COLLECTION_VIEW_USE_BMVIEW_SUBCLASS ? O
|
|
|
693
693
|
/**
|
|
694
694
|
* Defaults to `YES`. When set to `NO`, keyboard navigation is disabled.
|
|
695
695
|
*/
|
|
696
|
-
_supportsKeyboardNavigation:
|
|
696
|
+
_supportsKeyboardNavigation: NO, // <Boolean>
|
|
697
697
|
|
|
698
698
|
get supportsKeyboardNavigation() {
|
|
699
699
|
return this._supportsKeyboardNavigation;
|
|
@@ -1024,8 +1024,6 @@ BMCollectionView.prototype = BMExtend(BM_COLLECTION_VIEW_USE_BMVIEW_SUBCLASS ? O
|
|
|
1024
1024
|
this.__awaitsLayout = YES;
|
|
1025
1025
|
return;
|
|
1026
1026
|
}
|
|
1027
|
-
|
|
1028
|
-
this._blocksLayoutInvalidation = YES;
|
|
1029
1027
|
|
|
1030
1028
|
// Do not invalidate the layout during an animated data update
|
|
1031
1029
|
if (this.isUpdatingData) {
|
|
@@ -1033,6 +1031,8 @@ BMCollectionView.prototype = BMExtend(BM_COLLECTION_VIEW_USE_BMVIEW_SUBCLASS ? O
|
|
|
1033
1031
|
this.registerDataCompletionCallback(function () { self.invalidateLayout(); });
|
|
1034
1032
|
return;
|
|
1035
1033
|
}
|
|
1034
|
+
|
|
1035
|
+
this._blocksLayoutInvalidation = YES;
|
|
1036
1036
|
|
|
1037
1037
|
// If the layout supports animated changes and an animation context is active, make this change animated
|
|
1038
1038
|
let animation;
|
|
@@ -1185,8 +1185,13 @@ BMCollectionView.prototype = BMExtend(BM_COLLECTION_VIEW_USE_BMVIEW_SUBCLASS ? O
|
|
|
1185
1185
|
* Should be invoked by layout objects when the content size changes, but no other aspect of the layout does.
|
|
1186
1186
|
*/
|
|
1187
1187
|
invalidateContentSize() {
|
|
1188
|
-
// If an update is in progress,
|
|
1189
|
-
if (!this._collectionEnabled)
|
|
1188
|
+
// If an update is in progress, delay this until after the update
|
|
1189
|
+
if (!this._collectionEnabled) {
|
|
1190
|
+
this.registerDataCompletionCallback(() => {
|
|
1191
|
+
this.invalidateContentSize();
|
|
1192
|
+
})
|
|
1193
|
+
return;
|
|
1194
|
+
}
|
|
1190
1195
|
|
|
1191
1196
|
var size = this._layout.contentSize();
|
|
1192
1197
|
|
|
@@ -1451,6 +1456,8 @@ BMCollectionView.prototype = BMExtend(BM_COLLECTION_VIEW_USE_BMVIEW_SUBCLASS ? O
|
|
|
1451
1456
|
return;
|
|
1452
1457
|
}
|
|
1453
1458
|
|
|
1459
|
+
const previousBounds = BMRectMakeWithOrigin(previousBoundsOffset, {size: this._bounds.size.copy()});
|
|
1460
|
+
|
|
1454
1461
|
// Dequeue the layout queue after a minimal delay to minimize visual artifacts
|
|
1455
1462
|
(async () => {
|
|
1456
1463
|
await 0;
|
|
@@ -1459,19 +1466,21 @@ BMCollectionView.prototype = BMExtend(BM_COLLECTION_VIEW_USE_BMVIEW_SUBCLASS ? O
|
|
|
1459
1466
|
|
|
1460
1467
|
|
|
1461
1468
|
// Invalidate the layout if the layout object requires invalidation when the bounds change
|
|
1462
|
-
if (this._layout.shouldInvalidateLayoutForBoundsChange(this._bounds)) {
|
|
1469
|
+
if (this._layout.shouldInvalidateLayoutForBoundsChange(this._bounds, {fromBounds: previousBounds})) {
|
|
1463
1470
|
this.invalidateLayoutForBoundsChange();
|
|
1464
1471
|
|
|
1465
1472
|
// Let the delegate know that the bounds were updated
|
|
1466
1473
|
if (this.delegate && typeof this.delegate.collectionViewBoundsDidChange == 'function') {
|
|
1467
|
-
this.delegate.collectionViewBoundsDidChange(this, this._bounds);
|
|
1474
|
+
this.delegate.collectionViewBoundsDidChange(this, this._bounds, {fromBounds: previousBounds});
|
|
1468
1475
|
}
|
|
1469
1476
|
|
|
1470
1477
|
// Let the layout know that the invalidation was successful.
|
|
1471
1478
|
this._layout.didInvalidateLayoutForBoundsChange();
|
|
1472
1479
|
|
|
1473
1480
|
// Prepare to request and apply the snapping offset from the layout
|
|
1474
|
-
|
|
1481
|
+
if (snapsScrollPosition) {
|
|
1482
|
+
this._prepareForSnappingScrollOffsetWithPreviousOffset(previousBoundsOffset);
|
|
1483
|
+
}
|
|
1475
1484
|
|
|
1476
1485
|
return;
|
|
1477
1486
|
}
|
|
@@ -1619,12 +1628,14 @@ BMCollectionView.prototype = BMExtend(BM_COLLECTION_VIEW_USE_BMVIEW_SUBCLASS ? O
|
|
|
1619
1628
|
|
|
1620
1629
|
// Let the delegate know that the bounds were updated
|
|
1621
1630
|
if (this.delegate && typeof this.delegate.collectionViewBoundsDidChange == 'function') {
|
|
1622
|
-
this.delegate.collectionViewBoundsDidChange(this, this._bounds);
|
|
1631
|
+
this.delegate.collectionViewBoundsDidChange(this, this._bounds, {fromBounds: previousBounds});
|
|
1623
1632
|
}
|
|
1624
1633
|
|
|
1625
1634
|
|
|
1626
1635
|
// Prepare to request and apply the snapping offset from the layout
|
|
1627
|
-
|
|
1636
|
+
if (snapsScrollPosition) {
|
|
1637
|
+
this._prepareForSnappingScrollOffsetWithPreviousOffset(previousBoundsOffset);
|
|
1638
|
+
}
|
|
1628
1639
|
|
|
1629
1640
|
return;
|
|
1630
1641
|
}
|
|
@@ -1644,13 +1655,15 @@ BMCollectionView.prototype = BMExtend(BM_COLLECTION_VIEW_USE_BMVIEW_SUBCLASS ? O
|
|
|
1644
1655
|
|
|
1645
1656
|
// Let the delegate know that the bounds were updated
|
|
1646
1657
|
if (this.delegate && typeof this.delegate.collectionViewBoundsDidChange == 'function') {
|
|
1647
|
-
this.delegate.collectionViewBoundsDidChange(this, this._bounds);
|
|
1658
|
+
this.delegate.collectionViewBoundsDidChange(this, this._bounds, {fromBounds: previousBounds});
|
|
1648
1659
|
}
|
|
1649
1660
|
|
|
1650
1661
|
// Prepare to request and apply the snapping offset from the layout, unless the collection view is performing an
|
|
1651
1662
|
// automated scrolling animation
|
|
1652
1663
|
if (!this._isPerformingAnimatedScrolling) {
|
|
1653
|
-
|
|
1664
|
+
if (snapsScrollPosition) {
|
|
1665
|
+
this._prepareForSnappingScrollOffsetWithPreviousOffset(previousBoundsOffset);
|
|
1666
|
+
}
|
|
1654
1667
|
}
|
|
1655
1668
|
|
|
1656
1669
|
|
|
@@ -3988,7 +4001,7 @@ BMCollectionView.prototype = BMExtend(BM_COLLECTION_VIEW_USE_BMVIEW_SUBCLASS ? O
|
|
|
3988
4001
|
if (options && options.withEvent) options.withEvent._BMOriginalTarget = cell.node;
|
|
3989
4002
|
|
|
3990
4003
|
// Acquire focus if not already owned
|
|
3991
|
-
if (document.activeElement != this.node) {
|
|
4004
|
+
if (document.activeElement != this.node && this._supportsKeyboardNavigation) {
|
|
3992
4005
|
this.node.focus();
|
|
3993
4006
|
}
|
|
3994
4007
|
|
|
@@ -4053,7 +4066,7 @@ BMCollectionView.prototype = BMExtend(BM_COLLECTION_VIEW_USE_BMVIEW_SUBCLASS ? O
|
|
|
4053
4066
|
if (options && options.withEvent) options.withEvent._BMOriginalTarget = cell.node;
|
|
4054
4067
|
|
|
4055
4068
|
// Acquire focus if not already owned
|
|
4056
|
-
if (document.activeElement != this.node) {
|
|
4069
|
+
if (document.activeElement != this.node && this._supportsKeyboardNavigation) {
|
|
4057
4070
|
this.node.focus();
|
|
4058
4071
|
}
|
|
4059
4072
|
|
|
@@ -4075,7 +4088,7 @@ BMCollectionView.prototype = BMExtend(BM_COLLECTION_VIEW_USE_BMVIEW_SUBCLASS ? O
|
|
|
4075
4088
|
if (options && options.withEvent) options.withEvent._BMOriginalTarget = cell.node;
|
|
4076
4089
|
|
|
4077
4090
|
// Acquire focus if not already owned
|
|
4078
|
-
if (document.activeElement != this.node) {
|
|
4091
|
+
if (document.activeElement != this.node && this._supportsKeyboardNavigation) {
|
|
4079
4092
|
this.node.focus();
|
|
4080
4093
|
}
|
|
4081
4094
|
|
|
@@ -5028,6 +5041,10 @@ BMCollectionView.prototype = BMExtend(BM_COLLECTION_VIEW_USE_BMVIEW_SUBCLASS ? O
|
|
|
5028
5041
|
}
|
|
5029
5042
|
}
|
|
5030
5043
|
|
|
5044
|
+
if (options && options.completionHandler) {
|
|
5045
|
+
options.completionHandler();
|
|
5046
|
+
}
|
|
5047
|
+
|
|
5031
5048
|
this._executeDataCompletionCallbacks();
|
|
5032
5049
|
resolveUpdateData();
|
|
5033
5050
|
// Resolve the static animation context prior to returning
|
|
@@ -1699,9 +1699,15 @@ BMCollectionViewFlowLayout.prototype = BMExtend(Object.create(BMCollectionViewLa
|
|
|
1699
1699
|
* When using automatic cell sizes, the generator will yield execution and only calculate portions of the layout on demand.
|
|
1700
1700
|
* With the exeption of the first invocation, it is required to pass an index path to the iterator's `next` method. The layout process
|
|
1701
1701
|
* will continue until it fully lays out the cell for that index path, at which point it will yield again.
|
|
1702
|
-
* @param useOffset <Boolean>
|
|
1702
|
+
* @param useOffset <Boolean> When set to `YES` the layout will take the scrollbar size into account.
|
|
1703
|
+
* {
|
|
1704
|
+
* @param targetRect <BMRect, nullable> When computing a layout using automatic cell sizes, this is an optional rect up to which
|
|
1705
|
+
* to measure cells. This is reserved for when this is invoked as a delegate.
|
|
1706
|
+
* @param targetIndexPath <BMIndexPath, nullable> When computing a layout using automatic cell sizes, this is an optional index path up to which
|
|
1707
|
+
* to measure cells. This is reserved for when this is invoked as a delegate.
|
|
1708
|
+
* }
|
|
1703
1709
|
*/
|
|
1704
|
-
*_prepareLayoutWithScrollbarOffsetGenerator(useOffset) {
|
|
1710
|
+
*_prepareLayoutWithScrollbarOffsetGenerator(useOffset, target) {
|
|
1705
1711
|
|
|
1706
1712
|
// To standardize naming in order to support the orientation setting, the following terms are used:
|
|
1707
1713
|
// Length - refers to the dimension across the axis on which collection view scrolls: height for vertical and width for horizontal
|
|
@@ -1803,7 +1809,6 @@ BMCollectionViewFlowLayout.prototype = BMExtend(Object.create(BMCollectionViewLa
|
|
|
1803
1809
|
targetRect?: BMRect;
|
|
1804
1810
|
}
|
|
1805
1811
|
*/
|
|
1806
|
-
let target;
|
|
1807
1812
|
|
|
1808
1813
|
// The sections that contain the preliminary layout
|
|
1809
1814
|
const preliminarySections = [];
|
|
@@ -1977,15 +1982,15 @@ BMCollectionViewFlowLayout.prototype = BMExtend(Object.create(BMCollectionViewLa
|
|
|
1977
1982
|
|
|
1978
1983
|
numberOfColumns++;
|
|
1979
1984
|
} while (usedLength < maximumLength && expectedSize);
|
|
1980
|
-
|
|
1981
|
-
// Ensure that there is at least one column
|
|
1982
|
-
numberOfColumns = Math.max(numberOfColumns, 1);
|
|
1983
1985
|
}
|
|
1984
1986
|
else {
|
|
1985
1987
|
// If there is no minimum spacing required, then the number of columns is simply the available space divided
|
|
1986
1988
|
// by the cell width
|
|
1987
|
-
numberOfColumns =
|
|
1989
|
+
numberOfColumns = (maximumLength / expectedSize) | 0;
|
|
1988
1990
|
}
|
|
1991
|
+
|
|
1992
|
+
// Ensure that there is at least one column
|
|
1993
|
+
numberOfColumns = Math.max(numberOfColumns, 1);
|
|
1989
1994
|
}
|
|
1990
1995
|
|
|
1991
1996
|
// Create the preliminary sections
|
|
@@ -2069,7 +2074,12 @@ BMCollectionViewFlowLayout.prototype = BMExtend(Object.create(BMCollectionViewLa
|
|
|
2069
2074
|
|
|
2070
2075
|
cachedLayout.size = BMSizeMake(this.collectionView.frame.size.width, height);
|
|
2071
2076
|
|
|
2072
|
-
target
|
|
2077
|
+
// Yield after building the preliminary layout and wait for a target rect or index path up to which to measure
|
|
2078
|
+
if (!target) {
|
|
2079
|
+
// If a target is already supplied (as a parameter) this is a delegate generator and processing should continue
|
|
2080
|
+
// until this target
|
|
2081
|
+
target = yield;
|
|
2082
|
+
}
|
|
2073
2083
|
|
|
2074
2084
|
// When requesting a rect initially, pre-measure the cells up to that rect
|
|
2075
2085
|
if (target.rect) {
|
|
@@ -2085,7 +2095,13 @@ BMCollectionViewFlowLayout.prototype = BMExtend(Object.create(BMCollectionViewLa
|
|
|
2085
2095
|
|
|
2086
2096
|
cachedLayout.size = BMSizeMake(width, this.collectionView.frame.size.height);
|
|
2087
2097
|
|
|
2088
|
-
target
|
|
2098
|
+
// Yield after building the preliminary layout and wait for a target rect or index path up to which to measure
|
|
2099
|
+
if (!target) {
|
|
2100
|
+
// If a target is already supplied (as a parameter) this is a delegate generator and processing should continue
|
|
2101
|
+
// until this target
|
|
2102
|
+
target = yield;
|
|
2103
|
+
}
|
|
2104
|
+
|
|
2089
2105
|
// When requesting a rect initially, pre-measure the cells up to that rect
|
|
2090
2106
|
if (target.rect) {
|
|
2091
2107
|
measureCellsInRect(target.rect);
|
|
@@ -2220,7 +2236,15 @@ BMCollectionViewFlowLayout.prototype = BMExtend(Object.create(BMCollectionViewLa
|
|
|
2220
2236
|
|
|
2221
2237
|
// If the row height exceeds the collection view frame height, perform a second layout pass to account for the scrollbars
|
|
2222
2238
|
if (row[rowStartAttribute] + rowBreadth > frameSize) {
|
|
2223
|
-
if (this.collectionView.scrollBarSize && !useOffset)
|
|
2239
|
+
if (this.collectionView.scrollBarSize && !useOffset) {
|
|
2240
|
+
if (target) {
|
|
2241
|
+
// With automatic cell size delegate iteration to the new invocation
|
|
2242
|
+
return yield *this._prepareLayoutWithScrollbarOffsetGenerator(YES, target);
|
|
2243
|
+
}
|
|
2244
|
+
else {
|
|
2245
|
+
return this._prepareLayoutWithScrollbarOffset(YES);
|
|
2246
|
+
}
|
|
2247
|
+
}
|
|
2224
2248
|
}
|
|
2225
2249
|
|
|
2226
2250
|
// if there is one
|
|
@@ -2383,7 +2407,15 @@ BMCollectionViewFlowLayout.prototype = BMExtend(Object.create(BMCollectionViewLa
|
|
|
2383
2407
|
|
|
2384
2408
|
// If the total height exceeds the collection view frame height, perform a second layout pass to account for the scrollbars
|
|
2385
2409
|
if (height > frameHeight) {
|
|
2386
|
-
if (this.collectionView.scrollBarSize && !useOffset)
|
|
2410
|
+
if (this.collectionView.scrollBarSize && !useOffset) {
|
|
2411
|
+
if (target) {
|
|
2412
|
+
// With automatic cell size delegate iteration to the new invocation
|
|
2413
|
+
return yield *this._prepareLayoutWithScrollbarOffsetGenerator(YES, target);
|
|
2414
|
+
}
|
|
2415
|
+
else {
|
|
2416
|
+
return this._prepareLayoutWithScrollbarOffset(YES);
|
|
2417
|
+
}
|
|
2418
|
+
}
|
|
2387
2419
|
}
|
|
2388
2420
|
}
|
|
2389
2421
|
else {
|
|
@@ -2404,7 +2436,15 @@ BMCollectionViewFlowLayout.prototype = BMExtend(Object.create(BMCollectionViewLa
|
|
|
2404
2436
|
|
|
2405
2437
|
// If the total height exceeds the collection view frame height, perform a second layout pass to account for the scrollbars
|
|
2406
2438
|
if (width > frameWidth) {
|
|
2407
|
-
if (this.collectionView.scrollBarSize && !useOffset)
|
|
2439
|
+
if (this.collectionView.scrollBarSize && !useOffset) {
|
|
2440
|
+
if (target) {
|
|
2441
|
+
// With automatic cell size delegate iteration to the new invocation
|
|
2442
|
+
return yield *this._prepareLayoutWithScrollbarOffsetGenerator(YES, target);
|
|
2443
|
+
}
|
|
2444
|
+
else {
|
|
2445
|
+
return this._prepareLayoutWithScrollbarOffset(YES);
|
|
2446
|
+
}
|
|
2447
|
+
}
|
|
2408
2448
|
}
|
|
2409
2449
|
}
|
|
2410
2450
|
}
|
|
@@ -2418,7 +2458,15 @@ BMCollectionViewFlowLayout.prototype = BMExtend(Object.create(BMCollectionViewLa
|
|
|
2418
2458
|
|
|
2419
2459
|
// If the total height exceeds the collection view frame height, perform a second layout pass to account for the scrollbars
|
|
2420
2460
|
if (height > frameHeight) {
|
|
2421
|
-
if (this.collectionView.scrollBarSize && !useOffset)
|
|
2461
|
+
if (this.collectionView.scrollBarSize && !useOffset) {
|
|
2462
|
+
if (target) {
|
|
2463
|
+
// With automatic cell size delegate iteration to the new invocation
|
|
2464
|
+
return yield *this._prepareLayoutWithScrollbarOffsetGenerator(YES, target);
|
|
2465
|
+
}
|
|
2466
|
+
else {
|
|
2467
|
+
return this._prepareLayoutWithScrollbarOffset(YES);
|
|
2468
|
+
}
|
|
2469
|
+
}
|
|
2422
2470
|
}
|
|
2423
2471
|
}
|
|
2424
2472
|
else {
|
|
@@ -2429,7 +2477,15 @@ BMCollectionViewFlowLayout.prototype = BMExtend(Object.create(BMCollectionViewLa
|
|
|
2429
2477
|
|
|
2430
2478
|
// If the total height exceeds the collection view frame height, perform a second layout pass to account for the scrollbars
|
|
2431
2479
|
if (width > frameWidth) {
|
|
2432
|
-
if (this.collectionView.scrollBarSize && !useOffset)
|
|
2480
|
+
if (this.collectionView.scrollBarSize && !useOffset) {
|
|
2481
|
+
if (target) {
|
|
2482
|
+
// With automatic cell size delegate iteration to the new invocation
|
|
2483
|
+
return yield *this._prepareLayoutWithScrollbarOffsetGenerator(YES, target);
|
|
2484
|
+
}
|
|
2485
|
+
else {
|
|
2486
|
+
return this._prepareLayoutWithScrollbarOffset(YES);
|
|
2487
|
+
}
|
|
2488
|
+
}
|
|
2433
2489
|
}
|
|
2434
2490
|
}
|
|
2435
2491
|
|
|
@@ -2440,7 +2496,15 @@ BMCollectionViewFlowLayout.prototype = BMExtend(Object.create(BMCollectionViewLa
|
|
|
2440
2496
|
|
|
2441
2497
|
// If the total height exceeds the collection view frame height, perform a second layout pass to account for the scrollbars
|
|
2442
2498
|
if (height > frameHeight) {
|
|
2443
|
-
if (this.collectionView.scrollBarSize && !useOffset)
|
|
2499
|
+
if (this.collectionView.scrollBarSize && !useOffset) {
|
|
2500
|
+
if (target) {
|
|
2501
|
+
// With automatic cell size delegate iteration to the new invocation
|
|
2502
|
+
return yield *this._prepareLayoutWithScrollbarOffsetGenerator(YES, target);
|
|
2503
|
+
}
|
|
2504
|
+
else {
|
|
2505
|
+
return this._prepareLayoutWithScrollbarOffset(YES);
|
|
2506
|
+
}
|
|
2507
|
+
}
|
|
2444
2508
|
}
|
|
2445
2509
|
|
|
2446
2510
|
// If the height is lower than the collection view's height, the content gravity must be applied to all cached attributes
|
|
@@ -2534,7 +2598,15 @@ BMCollectionViewFlowLayout.prototype = BMExtend(Object.create(BMCollectionViewLa
|
|
|
2534
2598
|
else {
|
|
2535
2599
|
// If the total height exceeds the collection view frame height, perform a second layout pass to account for the scrollbars
|
|
2536
2600
|
if (width > frameWidth) {
|
|
2537
|
-
if (this.collectionView.scrollBarSize && !useOffset)
|
|
2601
|
+
if (this.collectionView.scrollBarSize && !useOffset) {
|
|
2602
|
+
if (target) {
|
|
2603
|
+
// With automatic cell size delegate iteration to the new invocation
|
|
2604
|
+
return yield *this._prepareLayoutWithScrollbarOffsetGenerator(YES, target);
|
|
2605
|
+
}
|
|
2606
|
+
else {
|
|
2607
|
+
return this._prepareLayoutWithScrollbarOffset(YES);
|
|
2608
|
+
}
|
|
2609
|
+
}
|
|
2538
2610
|
}
|
|
2539
2611
|
|
|
2540
2612
|
// If the height is lower than the collection view's height, the content gravity must be applied to all cached attributes
|
|
@@ -2607,7 +2679,7 @@ BMCollectionViewFlowLayout.prototype = BMExtend(Object.create(BMCollectionViewLa
|
|
|
2607
2679
|
const scaledRowHeight = rowWidth * scaleFactor | 0;
|
|
2608
2680
|
for (const attribute of row.attributes) {
|
|
2609
2681
|
attribute.frame.origin.x += displacement;
|
|
2610
|
-
attribute.frame.size.
|
|
2682
|
+
attribute.frame.size.width = attribute.frame.size.width * scaleFactor | 0;
|
|
2611
2683
|
}
|
|
2612
2684
|
|
|
2613
2685
|
// Advance the displacement based on the row's new width then displace the row end
|
|
@@ -2710,14 +2782,14 @@ BMCollectionViewFlowLayout.prototype = BMExtend(Object.create(BMCollectionViewLa
|
|
|
2710
2782
|
|
|
2711
2783
|
numberOfColumns++;
|
|
2712
2784
|
} while (usedLength < length && cellSize);
|
|
2713
|
-
|
|
2714
|
-
numberOfColumns = Math.max(numberOfColumns, 1);
|
|
2715
2785
|
}
|
|
2716
2786
|
else {
|
|
2717
2787
|
// If there is no minimum spacing required, then the number of columns is simply the available space divided
|
|
2718
2788
|
// by the cell width
|
|
2719
|
-
numberOfColumns =
|
|
2789
|
+
numberOfColumns = (length / cellSize) | 0;
|
|
2720
2790
|
}
|
|
2791
|
+
|
|
2792
|
+
numberOfColumns = Math.max(numberOfColumns, 1);
|
|
2721
2793
|
}
|
|
2722
2794
|
cachedLayout.numberOfColumns = numberOfColumns;
|
|
2723
2795
|
|
|
@@ -3263,10 +3335,18 @@ BMCollectionViewFlowLayout.prototype = BMExtend(Object.create(BMCollectionViewLa
|
|
|
3263
3335
|
// for the requested index path
|
|
3264
3336
|
if (this._expectedCellSize) {
|
|
3265
3337
|
if (this.cachedLayout.resolvedIndexPath.section < indexPath.section ||
|
|
3266
|
-
(this.cachedLayout.resolvedIndexPath.section == indexPath.section && this.cachedLayout.resolvedIndexPath.row < indexPath.row)
|
|
3267
|
-
|
|
3268
|
-
|
|
3338
|
+
(this.cachedLayout.resolvedIndexPath.section == indexPath.section && this.cachedLayout.resolvedIndexPath.row < indexPath.row)
|
|
3339
|
+
) {
|
|
3340
|
+
const currentResolvedHeight = this.cachedLayout.resolvedHeight;
|
|
3341
|
+
|
|
3342
|
+
// If the layout has not been resolved up to this index path, continue computing it until it has
|
|
3343
|
+
this._layoutIterator.next({indexPath: indexPath});
|
|
3344
|
+
|
|
3345
|
+
// If the resolved height changes, invalidate the content size
|
|
3346
|
+
if (currentResolvedHeight != this.cachedLayout.resolvedHeight) {
|
|
3347
|
+
this.invalidateContentSize();
|
|
3269
3348
|
}
|
|
3349
|
+
}
|
|
3270
3350
|
}
|
|
3271
3351
|
|
|
3272
3352
|
// Return the cached attributes when using dynamic sizes
|
|
@@ -4252,22 +4332,33 @@ BMCollectionViewFlowLayout.prototype = BMExtend(Object.create(BMCollectionViewLa
|
|
|
4252
4332
|
var attributes;
|
|
4253
4333
|
var self = this;
|
|
4254
4334
|
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
if (self.
|
|
4259
|
-
|
|
4260
|
-
|
|
4335
|
+
// When using automatic cell sizes, it is important to ensure that the sizing information has been computed
|
|
4336
|
+
// for the requested index path
|
|
4337
|
+
if (self._expectedCellSize) {
|
|
4338
|
+
if (self.previousLayout.resolvedIndexPath.section < indexPath.section ||
|
|
4339
|
+
(self.previousLayout.resolvedIndexPath.section == indexPath.section && self.previousLayout.resolvedIndexPath.row < indexPath.row)) {
|
|
4340
|
+
self.collectionView.usingOldDataSet(function () {
|
|
4261
4341
|
// If the layout has not been resolved up to this index path, continue computing it until it has
|
|
4262
4342
|
self.previousLayout.iterator.next({indexPath: indexPath});
|
|
4263
|
-
}
|
|
4264
|
-
|
|
4343
|
+
});
|
|
4344
|
+
}
|
|
4345
|
+
}
|
|
4346
|
+
|
|
4347
|
+
this.collectionView.usingOldDataSet(function () {
|
|
4265
4348
|
|
|
4266
4349
|
if (self._cellSize && !self._expectedCellSize) {
|
|
4267
4350
|
attributes = self.computedAttributesForCellAtIndexPath(indexPath, {usingCache: self.previousLayout});
|
|
4268
4351
|
}
|
|
4269
4352
|
else {
|
|
4270
4353
|
attributes = self.cachedAttributesForCellAtIndexPath(indexPath, {usingCache: self.previousLayout});
|
|
4354
|
+
|
|
4355
|
+
if (!attributes) {
|
|
4356
|
+
// When using automatic cell sizes, it is possible that the attributes for the moving cell were not computed
|
|
4357
|
+
// in this case, return a copy of the current attributes, with the opacity set to 0
|
|
4358
|
+
attributes = options.withTargetAttributes.copy();
|
|
4359
|
+
|
|
4360
|
+
attributes.style = Object.assign(attributes.style, {opacity: 0});
|
|
4361
|
+
}
|
|
4271
4362
|
}
|
|
4272
4363
|
});
|
|
4273
4364
|
|
|
@@ -4278,6 +4369,21 @@ BMCollectionViewFlowLayout.prototype = BMExtend(Object.create(BMCollectionViewLa
|
|
|
4278
4369
|
initialAttributesForMovingSupplementaryViewWithIdentifier: function (identifier, options) {
|
|
4279
4370
|
var attributes;
|
|
4280
4371
|
var self = this;
|
|
4372
|
+
|
|
4373
|
+
// When using automatic cell sizes, ensure that the sizing information has been computed for the requested index path
|
|
4374
|
+
if (self._expectedCellSize) {
|
|
4375
|
+
if (self.cachedLayout.resolvedIndexPath.section < options.atIndexPath.section ||
|
|
4376
|
+
(self.cachedLayout.resolvedIndexPath.section == options.atIndexPath.section && identifier == BMCollectionViewFlowLayoutSupplementaryView.Footer)) {
|
|
4377
|
+
if (options.atIndexPath.section == self.collectionView.numberOfSections() - 1) {
|
|
4378
|
+
// If there is no following section, compute until the last index path
|
|
4379
|
+
self._layoutIterator.next({indexPath: self.collectionView.indexPathForObjectAtRow(self.collectionView.numberOfObjectsInSectionAtIndex(options.atIndexPath.section) - 1, {inSectionAtIndex: options.atIndexPath.section})});
|
|
4380
|
+
}
|
|
4381
|
+
else {
|
|
4382
|
+
// If the layout has not been resolved up to this index path, continue computing up to the beginning of the next section
|
|
4383
|
+
self._layoutIterator.next({indexPath: self.collectionView.indexPathForObjectAtRow(0, {inSectionAtIndex: options.atIndexPath.section + 1})});
|
|
4384
|
+
}
|
|
4385
|
+
}
|
|
4386
|
+
}
|
|
4281
4387
|
|
|
4282
4388
|
this.collectionView.usingOldDataSet(function () {
|
|
4283
4389
|
if (identifier === BMCollectionViewTableLayoutSupplementaryView.Empty) {
|
|
@@ -4288,6 +4394,14 @@ BMCollectionViewFlowLayout.prototype = BMExtend(Object.create(BMCollectionViewLa
|
|
|
4288
4394
|
}
|
|
4289
4395
|
else {
|
|
4290
4396
|
attributes = self.cachedAttributesForSupplementaryViewWithIdentifier(identifier, {atIndexPath: options.atIndexPath, usingCache: self.previousLayout});
|
|
4397
|
+
|
|
4398
|
+
if (!attributes) {
|
|
4399
|
+
// When using automatic cell sizes, it is possible that the attributes for the moving supplementary view were not computed
|
|
4400
|
+
// in this case, return a copy of the current attributes, with the opacity set to 0
|
|
4401
|
+
attributes = options.withTargetAttributes.copy();
|
|
4402
|
+
|
|
4403
|
+
attributes.style = Object.assign(attributes.style, {opacity: 0});
|
|
4404
|
+
}
|
|
4291
4405
|
}
|
|
4292
4406
|
});
|
|
4293
4407
|
|
|
@@ -4489,19 +4603,22 @@ BMCollectionViewFlowLayout.prototype = BMExtend(Object.create(BMCollectionViewLa
|
|
|
4489
4603
|
const row = indexPath.row;
|
|
4490
4604
|
|
|
4491
4605
|
// Find the row where the current index path is
|
|
4492
|
-
const
|
|
4606
|
+
const cachedSection = this.cachedLayout.sections[section];
|
|
4493
4607
|
|
|
4494
|
-
if (!
|
|
4608
|
+
if (!cachedSection) return indexPath;
|
|
4609
|
+
|
|
4610
|
+
const sectionRows = cachedSection.rows;
|
|
4495
4611
|
|
|
4496
4612
|
let rowIndex = 0;
|
|
4497
4613
|
const rowCount = sectionRows.length;
|
|
4498
4614
|
for (rowIndex; rowIndex < rowCount; rowIndex++) {
|
|
4499
|
-
|
|
4615
|
+
const sectionRow = sectionRows[rowIndex];
|
|
4616
|
+
if (sectionRow.startIndex <= row && sectionRow.endIndex >= row) {
|
|
4500
4617
|
break;
|
|
4501
4618
|
}
|
|
4502
4619
|
}
|
|
4503
4620
|
|
|
4504
|
-
const attributes = sectionRows[rowIndex].attributes;
|
|
4621
|
+
const attributes = sectionRows[rowIndex].attributes.find(a => a.indexPath.row == row);
|
|
4505
4622
|
const positionProperty = this._orientation == BMCollectionViewFlowLayoutOrientation.Vertical ? 'x' : 'y';
|
|
4506
4623
|
const position = attributes.frame.center[positionProperty];
|
|
4507
4624
|
|
|
@@ -4616,19 +4733,22 @@ BMCollectionViewFlowLayout.prototype = BMExtend(Object.create(BMCollectionViewLa
|
|
|
4616
4733
|
const row = indexPath.row;
|
|
4617
4734
|
|
|
4618
4735
|
// Find the row where the current index path is
|
|
4619
|
-
const
|
|
4736
|
+
const cachedSection = this.cachedLayout.sections[section];
|
|
4737
|
+
|
|
4738
|
+
if (!cachedSection) return indexPath;
|
|
4620
4739
|
|
|
4621
|
-
|
|
4740
|
+
const sectionRows = cachedSection.rows;
|
|
4622
4741
|
|
|
4623
4742
|
let rowIndex = 0;
|
|
4624
4743
|
const rowCount = sectionRows.length;
|
|
4625
4744
|
for (rowIndex; rowIndex < rowCount; rowIndex++) {
|
|
4626
|
-
|
|
4745
|
+
const sectionRow = sectionRows[rowIndex];
|
|
4746
|
+
if (sectionRow.startIndex <= row && sectionRow.endIndex >= row) {
|
|
4627
4747
|
break;
|
|
4628
4748
|
}
|
|
4629
4749
|
}
|
|
4630
4750
|
|
|
4631
|
-
const attributes = sectionRows[rowIndex].attributes;
|
|
4751
|
+
const attributes = sectionRows[rowIndex].attributes.find(a => a.indexPath.row == row);
|
|
4632
4752
|
const positionProperty = this._orientation == BMCollectionViewFlowLayoutOrientation.Vertical ? 'x' : 'y';
|
|
4633
4753
|
const position = attributes.frame.center[positionProperty];
|
|
4634
4754
|
|
|
@@ -659,9 +659,12 @@ BMCollectionViewLayout.prototype = {
|
|
|
659
659
|
* Layout objects should return YES from this method if the new bounds require a new layout.
|
|
660
660
|
* The default implementation returns NO in all cases.
|
|
661
661
|
* @param bounds <BMRect> The new bounds.
|
|
662
|
+
* {
|
|
663
|
+
* @param fromBounds <BMRect> The previous bounds.
|
|
664
|
+
* }
|
|
662
665
|
* @return <Boolean> True if the new frame requires a new layout, false otherwise.
|
|
663
666
|
*/
|
|
664
|
-
shouldInvalidateLayoutForBoundsChange: function (bounds) {
|
|
667
|
+
shouldInvalidateLayoutForBoundsChange: function (bounds, {fromBounds}) {
|
|
665
668
|
return NO;
|
|
666
669
|
},
|
|
667
670
|
|