iOS 图片自动布局类

  • 内容
  • 评论
  • 相关
#import <UIKit/UIKit.h>

@interface ImageFlowLayout : NSObject

@property (nonatomic, assign) CGFloat fixedHeight;     // 固定图片高度
@property (nonatomic, assign) CGFloat horizontalSpacing; // 水平间距
@property (nonatomic, assign) CGFloat verticalSpacing;   // 垂直间距
@property (nonatomic, assign) CGFloat containerWidth;    // 容器宽度

// 布局完成回调,返回所有图片视图数组和最终容器所需高度
typedef void(^LayoutCompletionBlock)(NSArray<UIImageView *> *imageViews, CGFloat containerHeight);

// 主要布局方法
- (void)layoutWithImageUrls:(NSArray<NSString *> *)imageUrls
                completion:(LayoutCompletionBlock)completion;

@end

#import "ImageFlowLayout.h"

@implementation ImageFlowLayout

- (instancetype)init {
    self = [super init];
    if (self) {
        // 默认值设置
        _fixedHeight = 24;
        _horizontalSpacing = 8;
        _verticalSpacing = 8;
    }
    return self;
}

- (void)layoutWithImageUrls:(NSArray<NSString *> *)imageUrls
                completion:(LayoutCompletionBlock)completion {
    if (imageUrls.count == 0) {
        if (completion) {
            completion(@[], 0);
        }
        return;
    }
    
    NSMutableArray *imageInfoArray = [NSMutableArray array];
    __block NSInteger loadedCount = 0;
    NSInteger totalCount = imageUrls.count;
    
    // 创建并加载所有图片
    for (NSString *url in imageUrls) {
        UIImageView *imageView = [[UIImageView alloc] init];
        imageView.contentMode = UIViewContentModeScaleAspectFit;
        
        NSMutableDictionary *info = [NSMutableDictionary dictionary];
        info[@"imageView"] = imageView;
        [imageInfoArray addObject:info];
        
        [imageView sd_setImageWithURL:[NSURL URLWithString:url] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
            if (image) {
                // 计算等比例宽度
                CGFloat aspectRatio = image.size.width / image.size.height;
                info[@"width"] = @(self.fixedHeight * aspectRatio);
            } else {
                // 加载失败时使用默认宽度
                info[@"width"] = @(self.fixedHeight);
            }
            
            loadedCount++;
            if (loadedCount == totalCount) {
                // 所有图片加载完成,进行布局
                [self performLayoutWithImageInfo:imageInfoArray completion:completion];
            }
        }];
    }
}

- (void)performLayoutWithImageInfo:(NSArray *)imageInfoArray 
                      completion:(LayoutCompletionBlock)completion {
    CGFloat currentX = 0;
    CGFloat currentY = 0;
    NSMutableArray *imageViews = [NSMutableArray array];
    
    for (NSDictionary *info in imageInfoArray) {
        UIImageView *imageView = info[@"imageView"];
        CGFloat imageWidth = [info[@"width"] floatValue];
        
        // 检查是否需要换行
        if (currentX + imageWidth > self.containerWidth) {
            currentX = 0;
            currentY += self.fixedHeight + self.verticalSpacing;
        }
        
        // 设置图片位置
        imageView.frame = CGRectMake(currentX, currentY, imageWidth, self.fixedHeight);
        [imageViews addObject:imageView];
        
        currentX += imageWidth + self.horizontalSpacing;
    }
    
    // 计算最终容器高度
    CGFloat containerHeight = currentY + self.fixedHeight;
    
    if (completion) {
        completion(imageViews, containerHeight);
    }
}

@end

// 在需要使用的地方
ImageFlowLayout *layout = [[ImageFlowLayout alloc] init];
layout.containerWidth = self.containerView.frame.size.width;
layout.fixedHeight = 24;  // 可选,默认就是24
layout.horizontalSpacing = 8;  // 可选,默认就是8
layout.verticalSpacing = 8;    // 可选,默认就是8

[layout layoutWithImageUrls:imageUrls completion:^(NSArray<UIImageView *> *imageViews, CGFloat containerHeight) {
    // 更新容器高度
    self.containerHeightConstraint.constant = containerHeight;
    
    // 添加图片视图到容器
    for (UIImageView *imageView in imageViews) {
        [self.containerView addSubview:imageView];
    }
    
    [self layoutIfNeeded];
}];

评论

0条评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注