关于搜索时请求取消和热门标签的自适应布局。
之前看过叶孤城___的博客,大概了解一下,博客地址,并没有深入去了解和测试。最近刚好在做搜索时需要处理请求取消,但因为AF3.0 之后做了一些改变,没有使用AFHTTPRequestOperation而使用是NSURLSessionDataTask。同样的,NSURLSessionDataTask也可以cancel 并且cancel的请求会进入failure,标志为已取消,省的我们去判断是否已经取消了。
AF3.0后的方法
- (NSURLSessionDataTask *)POST:(NSString *)URLString
parameters:(id)parameters
progress:(void (^)(NSProgress * _Nonnull))uploadProgress
success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure
{
NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"POST" URLString:URLString parameters:parameters uploadProgress:uploadProgress downloadProgress:nil success:success failure:failure];
[dataTask resume];
return dataTask;
}
然后在自己的请求类里面调用上面的方法
BaseRequest.m
+ (NSURLSessionDataTask *)checkRegionsuccesBlock:(SuccessBlock)successBlock
failue:(FailureBlock)failueBlock;
请求测试
for (int i = 0; i<10; i++) {
static NSURLSessionDataTask *task;
if (task) {
[task cancel];
}
task = [BaseRequest checkRegionsuccesBlock:^(id data) {
NSLog(@"task : %d",i);
} failue:^(id data, NSError *error) {
}];
}
其中一条取消的结果
2016-09-22 17:52:18.689 917IM[6626:373279] task : 9
热门标签 的自适应大小。
接下来说说热门标签,我的做法是用UICollectionView去显示,每个标签的大小可以通过bounces函数获取到,但会发现UICollectionViewFlowLayout
设置的minimumInteritemSpacing只是设置了最小的距离同一行的情况下间距还是会变大。而且只有一个的情况下就会居中;要解决这个问题很简单,重写UICollectionViewFlowLayout的布局,把布局调整为我们想要的布局,这也是自定义UICollectionView布局需要做的.
首先新建一个类继承UICollectionViewFlowLayout
然后重写layoutAttributesForElementsInRect:(CGRect)rect
方法,使用的时候就用这个类去创建UICollectionView
。
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{
NSArray *attributes = [super layoutAttributesForElementsInRect:rect];
for(int i = 1; i < [attributes count]; ++i) {
//当前attributes
UICollectionViewLayoutAttributes *currentLayoutAttributes = attributes[i];
//上一个attributes
UICollectionViewLayoutAttributes *prevLayoutAttributes = attributes[i - 1];
//我们想设置的最大间距,可根据需要改
NSInteger maximumSpacing = self.minimumInteritemSpacing;
//前一个cell的最右边
NSInteger origin = CGRectGetMaxX(prevLayoutAttributes.frame);
//如果当前一个cell的最右边加上我们想要的间距加上当前cell的宽度依然在contentSize中,我们改变当前cell的原点位置
//不加这个判断的后果是,UICollectionView只显示一行,原因是下面所有cell的x值都被加到第一行最后一个元素的后面了
if(origin + maximumSpacing + currentLayoutAttributes.frame.size.width <= self.collectionViewContentSize.width) {
CGRect frame = currentLayoutAttributes.frame;
frame.origin.x = origin + maximumSpacing;
currentLayoutAttributes.frame = frame;
}else{
//不在同一行把 第一个置顶
CGRect frame = currentLayoutAttributes.frame;
frame.origin.x = 0;
currentLayoutAttributes.frame = frame;
//当前第二个置顶时 把第一个也置顶
if (i == 1) {
CGRect frame = prevLayoutAttributes.frame;
frame.origin.x = 0;
prevLayoutAttributes.frame = frame;
}
}
}
//只有一个时第一个置顶
if (attributes.count == 1) {
UICollectionViewLayoutAttributes *currentLayoutAttributes = attributes[0];
CGRect frame = currentLayoutAttributes.frame;
frame.origin.x = 0;
currentLayoutAttributes.frame = frame;
}
return attributes;
}
这样做有一点比较麻烦,就是需要预先计算总高度的时候要写个方法去计算标签的高度,不过更新数据的时候只要reload就可以了。
效果: