iOS: Fix layout in flowlayout or list

This commit is contained in:
pengfei.zhou 2022-09-08 18:34:27 +08:00 committed by osborn
parent 1dc167a43c
commit 0df882f28c
3 changed files with 29 additions and 30 deletions

View File

@ -45,8 +45,8 @@ @interface DoricFlowLayout : UICollectionViewLayout
@property(nonatomic, readonly) CGFloat rowSpace; @property(nonatomic, readonly) CGFloat rowSpace;
@property(nonatomic, strong) NSMutableDictionary <NSNumber *, NSNumber *> *columnHeightInfo; @property(nonatomic, strong) NSMutableDictionary <NSNumber *, NSNumber *> *columnHeightInfo;
@property(nonatomic, weak) id <DoricFlowLayoutDelegate> delegate; @property(nonatomic, weak) id <DoricFlowLayoutDelegate> delegate;
@property(nonatomic, copy) NSArray<UICollectionViewLayoutAttributes*> *layoutAttributes; @property(nonatomic, copy) NSArray<UICollectionViewLayoutAttributes *> *layoutAttributes;
@property(nonatomic, copy) NSArray<NSValue*> *unionRects; @property(nonatomic, copy) NSArray<NSValue *> *unionRects;
@property(nonatomic, strong) NSArray *swapDisabled; @property(nonatomic, strong) NSArray *swapDisabled;
@end @end
@ -81,25 +81,25 @@ - (void)prepareLayout {
} }
NSMutableArray *array = [NSMutableArray array]; NSMutableArray *array = [NSMutableArray array];
NSInteger count = [self.collectionView numberOfItemsInSection:0]; NSInteger count = [self.collectionView numberOfItemsInSection:0];
NSNumber *minYOfColumn = @(0); NSNumber *minYOfColumn = @(0);
NSArray<NSNumber *> *keys = self.columnHeightInfo.allKeys; NSArray<NSNumber *> *keys = self.columnHeightInfo.allKeys;
NSArray<NSNumber *> *sortedKeys = [keys sortedArrayUsingComparator:^NSComparisonResult(NSNumber *obj1, NSNumber *obj2) { NSArray<NSNumber *> *sortedKeys = [keys sortedArrayUsingComparator:^NSComparisonResult(NSNumber *obj1, NSNumber *obj2) {
return ([obj1 intValue] <= [obj2 intValue] ? NSOrderedAscending : NSOrderedDescending); return ([obj1 intValue] <= [obj2 intValue] ? NSOrderedAscending : NSOrderedDescending);
}]; }];
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
minYOfColumn = @(0); minYOfColumn = @(0);
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0] ; NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
for (NSNumber *key in sortedKeys) { for (NSNumber *key in sortedKeys) {
if ([self.columnHeightInfo[key] floatValue] < [self.columnHeightInfo[minYOfColumn] floatValue]) { if ([self.columnHeightInfo[key] floatValue] < [self.columnHeightInfo[minYOfColumn] floatValue]) {
minYOfColumn = key; minYOfColumn = key;
} }
} }
CGFloat width = [self.delegate doricFlowLayoutItemWidthAtIndexPath:indexPath]; CGFloat width = [self.delegate doricFlowLayoutItemWidthAtIndexPath:indexPath];
CGFloat height = [self.delegate doricFlowLayoutItemHeightAtIndexPath:indexPath]; CGFloat height = [self.delegate doricFlowLayoutItemHeightAtIndexPath:indexPath];
CGFloat x = 0; CGFloat x = 0;
@ -126,15 +126,15 @@ - (void)prepareLayout {
self.columnHeightInfo[minYOfColumn] = @(y + height); self.columnHeightInfo[minYOfColumn] = @(y + height);
} }
attrs.frame = CGRectMake(x, y, width, height); attrs.frame = CGRectMake(x, y, width, height);
[array addObject:attrs]; [array addObject:attrs];
} }
self.layoutAttributes = array; self.layoutAttributes = array;
NSMutableArray *mutableCopy = [NSMutableArray array]; NSMutableArray *mutableCopy = [NSMutableArray array];
long idx = 0; long idx = 0;
NSInteger itemCounts = count; NSInteger itemCounts = count;
while(idx < itemCounts){ while (idx < itemCounts) {
CGRect rect1 = self.layoutAttributes[idx].frame; CGRect rect1 = self.layoutAttributes[idx].frame;
idx = MIN(idx + count, itemCounts) - 1; idx = MIN(idx + count, itemCounts) - 1;
CGRect rect2 = self.layoutAttributes[idx].frame; CGRect rect2 = self.layoutAttributes[idx].frame;
@ -147,29 +147,29 @@ - (void)prepareLayout {
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
NSInteger begin = 0; NSInteger begin = 0;
NSInteger end = self.unionRects.count; NSInteger end = self.unionRects.count;
NSMutableArray<UICollectionViewLayoutAttributes*> *attrs = [NSMutableArray array]; NSMutableArray<UICollectionViewLayoutAttributes *> *attrs = [NSMutableArray array];
for (int i = 0; i < end; i++) { for (int i = 0; i < end; i++) {
if (CGRectIntersectsRect(rect, [self.unionRects[i] CGRectValue])) { if (CGRectIntersectsRect(rect, [self.unionRects[i] CGRectValue])) {
begin = i * self.layoutAttributes.count; begin = i * self.layoutAttributes.count;
break; break;
} }
} }
for (long i = self.unionRects.count - 1; i >= 0; i--) { for (long i = self.unionRects.count - 1; i >= 0; i--) {
if (CGRectIntersectsRect(rect, [self.unionRects[i] CGRectValue])) { if (CGRectIntersectsRect(rect, [self.unionRects[i] CGRectValue])) {
end = MIN((i + 1) * self.layoutAttributes.count, self.layoutAttributes.count); end = MIN((i + 1) * self.layoutAttributes.count, self.layoutAttributes.count);
break; break;
} }
} }
for (NSInteger i = begin; i < end; i++) { for (NSInteger i = begin; i < end; i++) {
UICollectionViewLayoutAttributes *attr = self.layoutAttributes[i]; UICollectionViewLayoutAttributes *attr = self.layoutAttributes[i];
if (CGRectIntersectsRect(rect, attr.frame)) { if (CGRectIntersectsRect(rect, attr.frame)) {
[attrs addObject:attr]; [attrs addObject:attr];
} }
} }
return attrs; return attrs;
} }
@ -255,7 +255,7 @@ - (UICollectionView *)build {
if (@available(iOS 11, *)) { if (@available(iOS 11, *)) {
it.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; it.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
} }
self.longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressAction:)]; self.longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressAction:)];
[it addGestureRecognizer:self.longPress]; [it addGestureRecognizer:self.longPress];
[self.longPress setEnabled:NO]; [self.longPress setEnabled:NO];
@ -268,9 +268,9 @@ - (void)longPressAction:(UILongPressGestureRecognizer *)sender {
if (sender.state == UIGestureRecognizerStateBegan) { if (sender.state == UIGestureRecognizerStateBegan) {
if (indexPath != nil) { if (indexPath != nil) {
[self.view beginInteractiveMovementForItemAtIndexPath:indexPath]; [self.view beginInteractiveMovementForItemAtIndexPath:indexPath];
self.currentDragIndexPath = indexPath; self.currentDragIndexPath = indexPath;
if (self.beforeDraggingFuncId != nil) { if (self.beforeDraggingFuncId != nil) {
DoricAsyncResult *asyncResult = [self callJSResponse:self.beforeDraggingFuncId, @(indexPath.row), nil]; DoricAsyncResult *asyncResult = [self callJSResponse:self.beforeDraggingFuncId, @(indexPath.row), nil];
JSValue *model = [asyncResult waitUntilResult]; JSValue *model = [asyncResult waitUntilResult];
@ -486,12 +486,9 @@ - (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collection
if (props[@"fullSpan"]) { if (props[@"fullSpan"]) {
fullSpan = [props[@"fullSpan"] boolValue]; fullSpan = [props[@"fullSpan"] boolValue];
} }
if (fullSpan) { CGFloat width = fullSpan ? collectionView.width : (collectionView.width - (self.columnCount - 1) * self.columnSpace) / self.columnCount;
node.view.width = collectionView.width; CGFloat height = node.view.doricLayout.heightSpec == DoricLayoutFit ? CGFLOAT_MAX : collectionView.height;
} else { [node.view.doricLayout apply:CGSizeMake(width, height)];
node.view.width = (collectionView.width - (self.columnCount - 1) * self.columnSpace) / self.columnCount;
}
[node.view.doricLayout apply];
[node requestLayout]; [node requestLayout];
[self callItem:position size:node.view.frame.size]; [self callItem:position size:node.view.frame.size];
return cell; return cell;

View File

@ -126,7 +126,7 @@ - (void)longPressAction:(UILongPressGestureRecognizer *)sender {
if (sender.state == UIGestureRecognizerStateBegan) { if (sender.state == UIGestureRecognizerStateBegan) {
if (indexPath != nil) { if (indexPath != nil) {
[self.view beginInteractiveMovementForItemAtIndexPath:indexPath]; [self.view beginInteractiveMovementForItemAtIndexPath:indexPath];
self.currentDragIndexPath = indexPath; self.currentDragIndexPath = indexPath;
if (self.beforeDraggingFuncId != nil) { if (self.beforeDraggingFuncId != nil) {
DoricAsyncResult *asyncResult = [self callJSResponse:self.beforeDraggingFuncId, @(indexPath.row), nil]; DoricAsyncResult *asyncResult = [self callJSResponse:self.beforeDraggingFuncId, @(indexPath.row), nil];
@ -266,7 +266,8 @@ - (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collection
DoricHorizontalListItemNode *node = cell.doricHorizontalListItemNode; DoricHorizontalListItemNode *node = cell.doricHorizontalListItemNode;
node.viewId = model[@"id"]; node.viewId = model[@"id"];
[node blend:props]; [node blend:props];
[node.view.doricLayout apply:CGSizeMake(collectionView.width, collectionView.height)]; CGFloat width = node.view.doricLayout.widthSpec == DoricLayoutFit ? CGFLOAT_MAX : collectionView.width;
[node.view.doricLayout apply:CGSizeMake(width, collectionView.height)];
[node requestLayout]; [node requestLayout];
[self callItem:position width:node.view.width]; [self callItem:position width:node.view.width];
return cell; return cell;

View File

@ -40,7 +40,7 @@ @interface DoricTableView : UITableView
@implementation DoricTableView @implementation DoricTableView
- (CGSize)sizeThatFits:(CGSize)size { - (CGSize)sizeThatFits:(CGSize)size {
CGSize result = [super sizeThatFits:size]; CGSize result = [super sizeThatFits:size];
if(self.doricLayout.widthSpec == DoricLayoutFit && self.contentSize.width>0){ if (self.doricLayout.widthSpec == DoricLayoutFit && self.contentSize.width > 0) {
return CGSizeMake(self.contentSize.width, result.height); return CGSizeMake(self.contentSize.width, result.height);
} }
return result; return result;
@ -135,7 +135,7 @@ - (void)longPressAction:(UILongPressGestureRecognizer *)sender {
return; return;
} }
} }
NSString *fromValue = self.itemViewIds[@(self.currentDragIndexPath.row)]; NSString *fromValue = self.itemViewIds[@(self.currentDragIndexPath.row)];
NSString *toValue = self.itemViewIds[@(indexPath.row)]; NSString *toValue = self.itemViewIds[@(indexPath.row)];
self.itemViewIds[@(self.currentDragIndexPath.row)] = toValue; self.itemViewIds[@(self.currentDragIndexPath.row)] = toValue;
@ -268,7 +268,8 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
DoricListItemNode *node = cell.doricListItemNode; DoricListItemNode *node = cell.doricListItemNode;
node.viewId = model[@"id"]; node.viewId = model[@"id"];
[node blend:props]; [node blend:props];
[node.view.doricLayout apply:CGSizeMake(tableView.width, tableView.height)]; CGFloat height = node.view.doricLayout.heightSpec == DoricLayoutFit ? CGFLOAT_MAX : tableView.height;
[node.view.doricLayout apply:CGSizeMake(tableView.width, height)];
[node requestLayout]; [node requestLayout];
[self callItem:position height:node.view.height]; [self callItem:position height:node.view.height];
return cell; return cell;