首次提交

This commit is contained in:
启星
2025-08-08 11:05:33 +08:00
parent 1b3bb91b4a
commit adc1a2a25d
8803 changed files with 708874 additions and 0 deletions

22
Pods/SDAutoLayout/LICENSE generated Executable file
View File

@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015 GSD_iOS
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

188
Pods/SDAutoLayout/README.md generated Executable file
View File

@@ -0,0 +1,188 @@
# SDAutoLayout一行代码搞定自动布局
##众多公司和个人开发者已经使用本库布局:
SDAutoLayout使用者开发的部分app截图 http://www.jianshu.com/p/9bc04d3effb8
一行代码搞定自动布局致力于做最简单易用的Autolayout库。The most easy way for autolayout.
## 技术支持(QQ交流群)
4971407131群 5194896822群已满
## Pod支持
支持pod pod 'SDAutoLayout', '~> 2.1.3'
如果发现pod search SDAutoLayout 搜索出来的不是最新版本需要在终端执行cd转换文件路径命令退回到desktop然后执行pod setup命令更新本地spec缓存可能需要几分钟然后再搜索就可以了
## 更新记录:
2018.07.02 -- 修复了部分布局组合下view居中布局失效bug
2017.11.11 -- 实现控制富文本可显示行数功能
2017.11.11 -- 解决朋友圈demo在iOS11上文字收折或者展开时出现cell跳动问题
2017.06.26 -- 解决部分开发者反应因出现“UITableViewCellContentView”而导致应用审核被拒问题
2016.08.12 -- 实现在tableview插入新的cell数据时自动缓存管理
2016.06.30 -- 增加多参照view的leftSpaceToView和topSpaceToView约束topSpaceToView(@[self.view3, self.view4], 30)
2016.06.24 -- 修复给button设置约束时在iOS8.x系统中出现的崩溃问题发布2.1.2版本
2016.06.23 -- 实现删除某行cell时自动调整height缓存
2016.05.16 -- 修复用xib生成的view出现的部分约束失效问题发布pod2.0.0版本)
2016.05.15 -- 增加设置偏移量offset功能
2016.04.30 -- 修复之前button作为父视图时内部控件不能自动布局问题
2016.04.05 -- 修复宽度自适应label在重用时候偶尔出现的宽度计算不准确的问题发布pod1.51版本)
2016.03.23 -- 升级了缓存机制新版本在tableview滑动cell时候流畅度和性能提升20%以上发布pod1.50版本)
2016.01.23 -- 增加label对attributedString的内容自适应
2016.01.21 -- 实现tableview局部刷新cell高度缓存的自动管理
2016.01.20 -- demo适配在ios7上的屏幕旋转问题
2016.01.18 -- 推出“普通简化版”tableview的cell自动高度方法推荐使用原来的需2步设置的普通版方法将标记过期
2016.01.13 -- 增加在不确定bottom view的情况下的cell高度自适应方法
2016.01.07 -- 1.增加 scrollview 横向内容自适应功能2.增加view宽高相等的功能
2016.01.03 -- 增加任何类型对象都可以实现一行代码搞定cell高度自适应增加文档注释
2015.12.08 -- 重大升级1.支持scrollview内容自适应2.任意添加或者修改约束不冲突3.性能提升40%以上4.添加最大、最小宽高约束
## 视频教程:
☆☆ SDAutoLayout 基础版视频教程http://www.letv.com/ptv/vplay/24038772.html ☆☆
☆☆ SDAutoLayout 进阶版视频教程http://www.letv.com/ptv/vplay/24381390.html ☆☆
☆☆ SDAutoLayout 原理简介视频教程http://www.iqiyi.com/w_19rt0tec4p.html ☆☆
☆☆ SDAutoLayout 朋友圈demo视频教程http://v.youku.com/v_show/id_XMTYzNzg2NzA0MA==.html ☆☆
## 部分SDAutoLayout的DEMO
完整微信Demo https://github.com/gsdios/GSD_WeiXin
![](http://ww3.sinaimg.cn/mw690/9b8146edgw1f1nm3pziawg205u0a0qv5.gif)![](http://ww1.sinaimg.cn/bmiddle/9b8146edgw1f06aoe2umhg206e0b4u0x.gif)![](http://ww4.sinaimg.cn/bmiddle/9b8146edgw1ezal3smihcg206y0ciqv5.gif)![](http://ww3.sinaimg.cn/mw690/9b8146edgw1f1nm3lweg3g207s0dcu0x.gif)![](http://ww2.sinaimg.cn/mw690/9b8146edgw1f23irukb0qg207i0dwu0x.gif)![](http://ww2.sinaimg.cn/bmiddle/9b8146edgw1eya1jv951ig208c0etqv5.gif)
# 用法简介
## tableview和cell高度自适应
####普通简化版【推荐使用】tableview 高度自适应设置只需要2步
1. >> 设置cell高度自适应
// cell布局设置好之后调用此方法就可以实现高度自适应注意如果用高度自适应则不要再以cell的底边为参照去布局其子view
[cell setupAutoHeightWithBottomView:_view4 bottomMargin:10];
2. >> 获取自动计算出的cell高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
id model = self.modelsArray[indexPath.row];
// 获取cell高度
return [self.tableView cellHeightForIndexPath:indexPath model:model keyPath:@"model" cellClass:[DemoVC9Cell class] contentViewWidth:cellContentViewWith];
}
####升级版适应于cell条数少于100的tableviewtableview 高度自适应设置只需要2步
1. >> 设置cell高度自适应
// cell布局设置好之后调用此方法就可以实现高度自适应注意如果用高度自适应则不要再以cell的底边为参照去布局其子view
[cell setupAutoHeightWithBottomView:_view4 bottomMargin:10];
2. >> 获取自动计算出的cell高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 获取cell高度
return [self cellHeightForIndexPath:indexPath cellContentViewWidth:[UIScreen mainScreen].bounds.size.width];
}
## 普通view的自动布局
#### 用法示例
/* 用法一 */
_view.sd_layout
.leftSpaceToView(self.view, 10)
.topSpaceToView(self.view, 80)
.heightIs(130)
.widthRatioToView(self.view, 0.4);
/* 用法二 (一行代码搞定,其实用法一也是一行代码) */
_view.sd_layout.leftSpaceToView(self.view, 10).topSpaceToView(self.view,80).heightIs(130).widthRatioToView(self.view, 0.4);
>> UILabel文字自适应
// autoHeightRatio() 传0则根据文字自动计算高度传大于0的值则根据此数值设置高度和宽度的比值
_label.sd_layout.autoHeightRatio(0);
*******************************************************************************
注意:先把需要自动布局的view加入父view然后在进行自动布局
UIView *view0 = [UIView new];
UIView *view1 = [UIView new];
[self.view addSubview:view0];
[self.view addSubview:view1];
view0.sd_layout
.leftSpaceToView(self.view, 10)
.topSpaceToView(self.view, 80)
.heightIs(100)
.widthRatioToView(self.view, 0.4);
view1.sd_layout
.leftSpaceToView(view0, 10)
.topEqualToView(view0)
.heightRatioToView(view0, 1)
.rightSpaceToView(self.view, 10);
*******************************************************************************
#### 自动布局用法简析
![](http://ww1.sinaimg.cn/mw690/9b8146edgw1ex4or5ixkjj20k60gw3zg.jpg)
1.1 > leftSpaceToView(self.view, 10)
方法名中带有“SpaceToView”的方法表示到某个参照view的间距需要传递2个参数UIView参照view 和 CGFloat间距数值
1.2 > widthRatioToView(self.view, 1)
方法名中带有“RatioToView”的方法表示view的宽度或者高度等属性相对于参照view的对应属性值的比例需要传递2个参数UIView参照view 和 CGFloat倍数
1.3 > topEqualToView(view)
方法名中带有“EqualToView”的方法表示view的某一属性等于参照view的对应的属性值需要传递1个参数UIView参照view
1.4 > widthIs(100)
方法名中带有“Is”的方法表示view的某一属性值等于参数数值需要传递1个参数CGFloat数值
# PS
// 如果需要用“断言”调试程序请打开此宏(位于UIView+SDAutoLayout.h)
//#define SDDebugWithAssert
![](http://ww3.sinaimg.cn/bmiddle/9b8146edgw1ex4mukixr6g209g07lhdt.gif)
![](http://upload-images.jianshu.io/upload_images/1157161-07fa43e0f539ebad.jpeg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](http://upload-images.jianshu.io/upload_images/1157161-453a5d33d7f3d48d.jpeg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

View File

@@ -0,0 +1,24 @@
//
// SDAutoLayout.h
// SDAutoLayoutDemo
//
// Created by gsd on 16/6/27.
// Copyright © 2016年 gsd. All rights reserved.
//
/*
SDAutoLayout
版本2.1.7
发布2016.08.12
*/
#ifndef SDAutoLayout_h
#define SDAutoLayout_h
#import "UIView+SDAutoLayout.h"
#import "UITableView+SDAutoTableViewCellHeight.h"
#endif

View File

@@ -0,0 +1,169 @@
//
// UITableView+SDAutoTableViewCellHeight.h
// SDAutoLayout 测试 Demo
//
// Created by aier on 15/11/1.
// Copyright © 2015年 gsd. All rights reserved.
//
/*
*********************************************************************************
* *
* 在您使用此自动布局库的过程中如果出现bug请及时以以下任意一种方式联系我们我们会及时修复bug并 *
* 帮您解决问题。 *
* QQ : 2689718696(gsdios) *
* Email : gsdios@126.com *
* GitHub: https://github.com/gsdios *
* 新浪微博:GSD_iOS *
* *
*********************************************************************************
*/
/*
PS:cell高度自适应前提>>应该调用cell的“- (void)setupAutoHeightWithBottomView:(UIView *)bottomView bottomMargin:(CGFloat)bottomMargin”方法进行cell的自动高度设置
*/
#import <UIKit/UIKit.h>
#import "UIView+SDAutoLayout.h"
@class SDCellAutoHeightManager;
typedef void (^AutoCellHeightDataSettingBlock)(UITableViewCell *cell);
#define kSDModelCellTag 199206
#pragma mark - UITableView 方法返回自动计算出的cell高度
@interface UITableView (SDAutoTableViewCellHeight)
@property (nonatomic, strong) SDCellAutoHeightManager *cellAutoHeightManager;
/**
* 返回计算出的cell高度普通简化版方法同样只需一步设置即可完成(用法单cell详见demo5多cell详见demo7)
* model : cell的数据模型实例
* keyPath : cell的数据模型属性的属性名字符串即kvc原理中的key
* cellClass : 当前的indexPath对应的cell的class
* contentViewWidth : cell的contentView的宽度
*/
- (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath model:(id)model keyPath:(NSString *)keyPath cellClass:(Class)cellClass contentViewWidth:(CGFloat)contentViewWidth;
/**
* 返回计算出的cell高度普通简化版方法同样只需一步设置即可完成(用法见DemoVC14)
* cellClass : 当前的indexPath对应的cell的class
* contentViewWidth : cell的contentView的宽度
* cellDataSetting : 设置cell数据的block
*/
- (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath cellClass:(Class)cellClass cellContentViewWidth:(CGFloat)width cellDataSetting:(AutoCellHeightDataSettingBlock)cellDataSetting;
/** 刷新tableView但不清空之前已经计算好的高度缓存用于直接将新数据拼接在旧数据之后的tableView刷新 */
- (void)reloadDataWithExistedHeightCache;
/** 刷新tableView同时调整已经计算好的高度缓存用于直接将新数据插在旧数据前面的tableView的刷新 */
- (void)reloadDataWithInsertingDataAtTheBeginingOfSection:(NSInteger)section newDataCount:(NSInteger)count;
/**
* 刷新tableView同时调整已经计算好的高度缓存用于直接将新数据插在旧数据前面的tableView的刷新(用于刷新多个section)
* sectionNumsArray : 要刷新的所有section序号组成的数组, 例@[@(0), @(1)]
* dataCountsArray : 每个section的数据条数组成的数组, 例@[@(20), @(10)]
*/
- (void)reloadDataWithInsertingDataAtTheBeginingOfSections:(NSArray *)sectionNumsArray newDataCounts:(NSArray *)dataCountsArray;
/** 返回所有cell的高度总和 */
- (CGFloat)cellsTotalHeight;
@property (nonatomic, copy) AutoCellHeightDataSettingBlock cellDataSetting;
@end
#pragma mark - UITableViewController 方法返回自动计算出的cell高度
@interface UITableViewController (SDTableViewControllerAutoCellHeight)
/** (UITableViewController方法)升级版一行代码一步设置搞定tableview的cell高度自适应,同时适用于单cell和多cell,性能比普通版稍微差一些,不建议在数据量大的tableview中使用 */
- (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath cellContentViewWidth:(CGFloat)width;
@end
#pragma mark - NSObject 方法返回自动计算出的cell高度
@interface NSObject (SDAnyObjectAutoCellHeight)
/** (NSObject方法)升级版一行代码一步设置搞定tableview的cell高度自适应,同时适用于单cell和多cell,性能比普通版稍微差一些,不建议在数据量大的tableview中使用 */
- (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath cellContentViewWidth:(CGFloat)width tableView:(UITableView *)tableView;
@end
// ------------------------------- 以下为库内部使用无须了解 --------------------
@interface SDCellAutoHeightManager : NSObject
@property (nonatomic, assign) BOOL shouldKeepHeightCacheWhenReloadingData;
@property (nonatomic, assign) CGFloat contentViewWidth;
@property (nonatomic, assign) Class cellClass;
@property (nonatomic, assign) CGFloat cellHeight;
@property (nonatomic, strong) UITableViewCell *modelCell;
@property (nonatomic, strong) NSMutableDictionary *subviewFrameCacheDict;
@property (nonatomic, strong, readonly) NSDictionary *heightCacheDict;
@property (nonatomic, copy) AutoCellHeightDataSettingBlock cellDataSetting;
- (void)clearHeightCache;
- (void)clearHeightCacheOfIndexPaths:(NSArray *)indexPaths;
- (void)deleteThenResetHeightCache:(NSIndexPath *)indexPathToDelete;
- (void)insertNewDataAtTheBeginingOfSection:(NSInteger)section newDataCount:(NSInteger)count;
- (void)insertNewDataAtIndexPaths:(NSArray *)indexPaths;
- (NSNumber *)heightCacheForIndexPath:(NSIndexPath *)indexPath;
- (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath model:(id)model keyPath:(NSString *)keyPath;
- (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath model:(id)model keyPath:(NSString *)keyPath cellClass:(Class)cellClass;
- (NSMutableArray *)subviewFrameCachesWithIndexPath:(NSIndexPath *)indexPath;;
- (void)setSubviewFrameCache:(CGRect)rect WithIndexPath:(NSIndexPath *)indexPath;
- (instancetype)initWithCellClass:(Class)cellClass tableView:(UITableView *)tableView;
+ (instancetype)managerWithCellClass:(Class)cellClass tableView:(UITableView *)tableView;
@end

View File

@@ -0,0 +1,537 @@
//
// UITableView+SDAutoTableViewCellHeight.m
// SDAutoLayout Demo
//
// Created by aier on 15/11/1.
// Copyright © 2015 gsd. All rights reserved.
//
/*
*********************************************************************************
* *
* 使bugbug *
* *
* QQ : 2689718696(gsdios) *
* Email : gsdios@126.com *
* GitHub: https://github.com/gsdios *
* :GSD_iOS *
* *
*********************************************************************************
*/
#import "UITableView+SDAutoTableViewCellHeight.h"
#import <objc/runtime.h>
@interface SDCellAutoHeightManager ()
@property (nonatomic, weak) UITableView *modelTableview;
@end
@implementation SDCellAutoHeightManager
{
NSMutableDictionary *_cacheDictionary;
NSMutableDictionary *_modelCellsDict;
}
- (instancetype)init
{
if (self = [super init]) {
[self setup];
}
return self;
}
- (instancetype)initWithCellClass:(Class)cellClass tableView:(UITableView *)tableView
{
if (self = [super init]) {
[self setup];
self.modelTableview = tableView;
[self registerCellWithCellClass:cellClass];
}
return self;
}
- (instancetype)initWithCellClasses:(NSArray *)cellClassArray tableView:(UITableView *)tableView
{
if (self = [super init]) {
[self setup];
self.modelTableview = tableView;
[cellClassArray enumerateObjectsUsingBlock:^(Class obj, NSUInteger idx, BOOL *stop) {
[self registerCellWithCellClass:obj];
}];
}
return self;
}
- (void)setup
{
_cacheDictionary = [NSMutableDictionary new];
_modelCellsDict = [NSMutableDictionary new];
}
- (void)registerCellWithCellClass:(Class)cellClass
{
[_modelTableview registerClass:cellClass forCellReuseIdentifier:NSStringFromClass(cellClass)];
self.modelCell = [_modelTableview dequeueReusableCellWithIdentifier:NSStringFromClass(cellClass)];
if (!self.modelCell.contentView.subviews.count) {
NSString *path = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%@.nib", NSStringFromClass(cellClass)] ofType:nil];
if (path) {
self.modelCell = nil;
[_modelTableview registerNib:[UINib nibWithNibName:NSStringFromClass(cellClass) bundle:nil] forCellReuseIdentifier:NSStringFromClass(cellClass)];
self.modelCell = [_modelTableview dequeueReusableCellWithIdentifier:NSStringFromClass(cellClass)];
}
}
if (self.modelCell) {
[_modelCellsDict setObject:self.modelCell forKey:NSStringFromClass(cellClass)];
}
}
+ (instancetype)managerWithCellClass:(Class)cellClass tableView:(UITableView *)tableView
{
SDCellAutoHeightManager *manager = [[self alloc] initWithCellClass:cellClass tableView:tableView];
return manager;
}
- (UITableViewCell *)modelCell
{
if (_modelCell.contentView.tag != kSDModelCellTag) {
_modelCell.contentView.tag = kSDModelCellTag;
}
return _modelCell;
}
- (NSDictionary *)heightCacheDict
{
return _cacheDictionary;
}
- (void)clearHeightCache
{
[_cacheDictionary removeAllObjects];
[_subviewFrameCacheDict removeAllObjects];
}
- (NSString *)cacheKeyForIndexPath:(NSIndexPath *)indexPath
{
return [NSString stringWithFormat:@"%ld-%ld", (long)indexPath.section, (long)indexPath.row];
}
- (void)clearHeightCacheOfIndexPaths:(NSArray *)indexPaths
{
[indexPaths enumerateObjectsUsingBlock:^(NSIndexPath *indexPath, NSUInteger idx, BOOL *stop) {
NSString *cacheKey = [self cacheKeyForIndexPath:indexPath];
[_cacheDictionary removeObjectForKey:cacheKey];
[_subviewFrameCacheDict removeObjectForKey:cacheKey];
}];
}
- (void)deleteThenResetHeightCache:(NSIndexPath *)indexPathToDelete
{
NSString *cacheKey = [self cacheKeyForIndexPath:indexPathToDelete];
[_cacheDictionary removeObjectForKey:cacheKey];
[_subviewFrameCacheDict removeObjectForKey:cacheKey];
long sectionOfToDeleteItem = indexPathToDelete.section;
long rowOfToDeleteItem = indexPathToDelete.row;
NSMutableDictionary *tempHeightCacheDict = [NSMutableDictionary new];
NSMutableDictionary *tempFrameCacheDict = [NSMutableDictionary new];
for (NSString *key in _cacheDictionary.allKeys) {
NSArray *res = [key componentsSeparatedByString:@"-"];
long section = [res.firstObject integerValue];
long row = [res.lastObject integerValue];
if (section == sectionOfToDeleteItem && row > rowOfToDeleteItem) {
NSNumber *heightCache = _cacheDictionary[key];
NSArray *frameCache = _subviewFrameCacheDict[key];
NSString *newKey = [NSString stringWithFormat:@"%ld-%ld", section, (row - 1)];
[tempHeightCacheDict setValue:heightCache forKey:newKey];
[tempFrameCacheDict setValue:frameCache forKey:newKey];
[_cacheDictionary removeObjectForKey:key];
[_subviewFrameCacheDict removeObjectForKey:key];
}
}
[_cacheDictionary addEntriesFromDictionary:tempHeightCacheDict];
[_subviewFrameCacheDict addEntriesFromDictionary:tempFrameCacheDict];
}
- (void)insertNewDataAtTheBeginingOfSection:(NSInteger)section newDataCount:(NSInteger)count
{
NSMutableDictionary *tempHeightCacheDict = [NSMutableDictionary new];
NSMutableDictionary *tempFrameCacheDict = [NSMutableDictionary new];
for (NSString *key in _cacheDictionary.allKeys) {
NSArray *res = [key componentsSeparatedByString:@"-"];
long originalSection = [res.firstObject integerValue];
long row = [res.lastObject integerValue];
if (originalSection == section) {
NSNumber *heightCache = _cacheDictionary[key];
NSArray *frameCache = _subviewFrameCacheDict[key];
NSString *newKey = [NSString stringWithFormat:@"%ld-%ld", originalSection, (row + count)];
[tempHeightCacheDict setValue:heightCache forKey:newKey];
[tempFrameCacheDict setValue:frameCache forKey:newKey];
[_cacheDictionary removeObjectForKey:key];
[_subviewFrameCacheDict removeObjectForKey:key];
}
}
[_cacheDictionary addEntriesFromDictionary:tempHeightCacheDict];
[_subviewFrameCacheDict addEntriesFromDictionary:tempFrameCacheDict];
}
- (void)insertNewDataAtIndexPaths:(NSArray *)indexPaths
{
NSMutableDictionary *sectionsdict = [NSMutableDictionary new];
for (NSIndexPath *indexPath in indexPaths) {
NSString *sectionkey = [@(indexPath.section) stringValue];
if (![sectionsdict objectForKey:sectionkey]) {
[sectionsdict setValue:[NSMutableArray new] forKey:sectionkey];
}
NSMutableArray *arr = sectionsdict[sectionkey];
[arr addObject:indexPath];
}
for (NSString *sectionkey in sectionsdict.allKeys) {
NSMutableArray *tempHeightCaches = [NSMutableArray new];
NSMutableArray *tempFrameCaches = [NSMutableArray new];
NSInteger section = [sectionkey integerValue];
NSInteger rowCount = [self.modelTableview numberOfRowsInSection:section];
if (rowCount <= 0) {
continue;
} else {
for (int i = 0; i < rowCount; i++) {
[tempHeightCaches addObject:[NSNull null]];
[tempFrameCaches addObject:[NSNull null]];
}
}
for (NSString *key in _cacheDictionary.allKeys) {
NSArray *res = [key componentsSeparatedByString:@"-"];
long originalSection = [res.firstObject integerValue];
long row = [res.lastObject integerValue];
if (originalSection == section) {
NSNumber *heightCache = _cacheDictionary[key];
NSArray *frameCache = _subviewFrameCacheDict[key];
[tempHeightCaches setObject:heightCache atIndexedSubscript:row];
[tempFrameCaches setObject:frameCache atIndexedSubscript:row];
[_cacheDictionary removeObjectForKey:key];
[_subviewFrameCacheDict removeObjectForKey:key];
}
}
NSMutableArray *objsToInsert = [NSMutableArray new];
NSMutableIndexSet *indexSet = [NSMutableIndexSet new];
NSArray *indexPaths = sectionsdict[sectionkey];
[indexPaths enumerateObjectsUsingBlock:^(NSIndexPath *obj, NSUInteger idx, BOOL *stop) {
[objsToInsert addObject:[NSNull null]];
[indexSet addIndex:obj.row];
}];
[tempHeightCaches insertObjects:objsToInsert atIndexes:indexSet];
[tempFrameCaches insertObjects:objsToInsert atIndexes:indexSet];
[tempHeightCaches enumerateObjectsUsingBlock:^(NSNumber *heightCache, NSUInteger idx, BOOL *stop) {
if (![heightCache isKindOfClass:[NSNull class]]) {
NSString *key = [NSString stringWithFormat:@"%zd-%zd", section, idx];
[_cacheDictionary setValue:heightCache forKey:key];
[_subviewFrameCacheDict setValue:[tempFrameCaches objectAtIndex:idx] forKey:key];
}
}];
}
}
- (NSNumber *)heightCacheForIndexPath:(NSIndexPath *)indexPath
{
/*
dequeueReusableCellWithIdentifier:forIndexPath:celldequeueReusableCellWithIdentifier:IndexPath
*/
NSString *cacheKey = [self cacheKeyForIndexPath:indexPath];
return (NSNumber *)[_cacheDictionary objectForKey:cacheKey];
}
- (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath model:(id)model keyPath:(NSString *)keyPath
{
NSNumber *cacheHeight = [self heightCacheForIndexPath:indexPath];
if (cacheHeight) {
return [cacheHeight floatValue];
} else {
if (!self.modelCell) {
return 0;
}
if (self.modelTableview && self.modelTableview != self.modelCell.sd_tableView) {
self.modelCell.sd_tableView = self.modelTableview;
}
self.modelCell.sd_indexPath = indexPath;
if (model && keyPath) {
[self.modelCell setValue:model forKey:keyPath];
} else if (self.cellDataSetting) {
self.cellDataSetting(self.modelCell);
}
#ifdef SDDebugWithAssert
/*
cellsetupAutoHeightWithBottomView:(UIView *)bottomView bottomMargin:(CGFloat)bottomMarginbottomViewnil
//bottomViewnil
[cell setupAutoHeightWithBottomView:bottomView bottomMargin:bottomMargin];
*/
NSAssert(self.modelCell.sd_bottomViewsArray.count, @">>>>>> 你的cell还没有调用“setupAutoHeightWithBottomView:(UIView *)bottomView bottomMargin:(CGFloat)bottomMargin”方法或者你传递的bottomView为nil请检查并修改");
#endif
[self.modelCell.contentView layoutSubviews];
NSString *cacheKey = [self cacheKeyForIndexPath:indexPath];
[_cacheDictionary setObject:@(self.modelCell.autoHeight) forKey:cacheKey];
if (self.modelCell.sd_indexPath && self.modelCell.sd_tableView) {
if (self.modelCell.contentView.shouldReadjustFrameBeforeStoreCache) {
self.modelCell.contentView.height_sd = self.modelCell.autoHeight;
[self.modelCell.contentView layoutSubviews];
}
[self.modelCell.contentView.autoLayoutModelsArray enumerateObjectsUsingBlock:^(SDAutoLayoutModel *model, NSUInteger idx, BOOL *stop) {
[self.modelTableview.cellAutoHeightManager setSubviewFrameCache:model.needsAutoResizeView.frame WithIndexPath:self.modelCell.sd_indexPath];
}];
}
return self.modelCell.autoHeight;
}
}
- (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath model:(id)model keyPath:(NSString *)keyPath cellClass:(Class)cellClass
{
if (![self.modelCell isKindOfClass:cellClass]) {
self.modelCell = nil;
self.modelCell = [_modelCellsDict objectForKey:NSStringFromClass(cellClass)];
if (!self.modelCell) {
[self registerCellWithCellClass:cellClass];
}
_modelCell.contentView.tag = kSDModelCellTag;
}
if (self.modelCell.contentView.width_sd != self.contentViewWidth) {
_modelCell.contentView.width_sd = self.contentViewWidth;
}
return [self cellHeightForIndexPath:indexPath model:model keyPath:keyPath];
}
- (void)setContentViewWidth:(CGFloat)contentViewWidth
{
if (_contentViewWidth == contentViewWidth) return;
CGFloat lastContentViewWidth = _contentViewWidth;
_contentViewWidth = contentViewWidth;
self.modelCell.contentView.width_sd = self.contentViewWidth;
if (lastContentViewWidth > 0) {
[_subviewFrameCacheDict removeAllObjects];
dispatch_async(dispatch_get_main_queue(), ^{
[self clearHeightCache];
[self.modelTableview reloadData];
});
}
}
- (void)setSubviewFrameCache:(CGRect)rect WithIndexPath:(NSIndexPath *)indexPath
{
if (!self.subviewFrameCacheDict) {
self.subviewFrameCacheDict = [NSMutableDictionary new];
}
NSString *cacheKey = [self cacheKeyForIndexPath:indexPath];
NSMutableArray *caches = [self.subviewFrameCacheDict objectForKey:cacheKey];
if (!caches) {
caches = [NSMutableArray new];
[self.subviewFrameCacheDict setValue:caches forKey:cacheKey];
}
[caches addObject:[NSValue valueWithCGRect:rect]];
}
- (NSMutableArray *)subviewFrameCachesWithIndexPath:(NSIndexPath *)indexPath
{
NSString *cacheKey = [self cacheKeyForIndexPath:indexPath];
return [self.subviewFrameCacheDict valueForKey:cacheKey];
}
@end
@implementation UITableView (SDAutoTableViewCellHeight)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSArray *selStringsArray = @[@"reloadData", @"reloadRowsAtIndexPaths:withRowAnimation:", @"deleteRowsAtIndexPaths:withRowAnimation:", @"insertRowsAtIndexPaths:withRowAnimation:"];
[selStringsArray enumerateObjectsUsingBlock:^(NSString *selString, NSUInteger idx, BOOL *stop) {
NSString *mySelString = [@"sd_" stringByAppendingString:selString];
Method originalMethod = class_getInstanceMethod(self, NSSelectorFromString(selString));
Method myMethod = class_getInstanceMethod(self, NSSelectorFromString(mySelString));
method_exchangeImplementations(originalMethod, myMethod);
}];
});
}
- (void)sd_reloadData
{
if (!self.cellAutoHeightManager.shouldKeepHeightCacheWhenReloadingData) {
[self.cellAutoHeightManager clearHeightCache];
}
[self sd_reloadData];
self.cellAutoHeightManager.shouldKeepHeightCacheWhenReloadingData = NO;
}
- (void)sd_reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
{
[self.cellAutoHeightManager clearHeightCacheOfIndexPaths:indexPaths];
[self sd_reloadRowsAtIndexPaths:indexPaths withRowAnimation:animation];
}
- (void)sd_deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
{
for (NSIndexPath *indexPath in indexPaths) {
[self.cellAutoHeightManager deleteThenResetHeightCache:indexPath];
}
[self sd_deleteRowsAtIndexPaths:indexPaths withRowAnimation:animation];
}
- (void)sd_insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
{
[self.cellAutoHeightManager insertNewDataAtIndexPaths:indexPaths];
[self sd_insertRowsAtIndexPaths:indexPaths withRowAnimation:animation];
}
/*
*
- (void)sd_moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath
{
[self sd_moveRowAtIndexPath:indexPath toIndexPath:newIndexPath];
}
*/
- (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath model:(id)model keyPath:(NSString *)keyPath cellClass:(Class)cellClass contentViewWidth:(CGFloat)contentViewWidth
{
self.cellAutoHeightManager.modelTableview = self;
self.cellAutoHeightManager.contentViewWidth = contentViewWidth;
return [self.cellAutoHeightManager cellHeightForIndexPath:indexPath model:model keyPath:keyPath cellClass:cellClass];
}
- (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath cellClass:(__unsafe_unretained Class)cellClass cellContentViewWidth:(CGFloat)width cellDataSetting:(AutoCellHeightDataSettingBlock)cellDataSetting
{
self.cellDataSetting = cellDataSetting;
return [self cellHeightForIndexPath:indexPath model:nil keyPath:nil cellClass:cellClass contentViewWidth:width];
}
- (void)reloadDataWithExistedHeightCache
{
self.cellAutoHeightManager.shouldKeepHeightCacheWhenReloadingData = YES;
[self reloadData];
}
- (void)reloadDataWithInsertingDataAtTheBeginingOfSection:(NSInteger)section newDataCount:(NSInteger)count
{
self.cellAutoHeightManager.shouldKeepHeightCacheWhenReloadingData = YES;
[self.cellAutoHeightManager insertNewDataAtTheBeginingOfSection:section newDataCount:count];
[self reloadData];
}
- (void)reloadDataWithInsertingDataAtTheBeginingOfSections:(NSArray *)sectionNumsArray newDataCounts:(NSArray *)dataCountsArray
{
self.cellAutoHeightManager.shouldKeepHeightCacheWhenReloadingData = YES;
[sectionNumsArray enumerateObjectsUsingBlock:^(NSNumber *num, NSUInteger idx, BOOL *stop) {
int section = [num intValue];
int dataCountForSection = [dataCountsArray[idx] intValue];
[self.cellAutoHeightManager insertNewDataAtTheBeginingOfSection:section newDataCount:dataCountForSection];
}];
[self reloadData];
}
- (CGFloat)cellsTotalHeight
{
CGFloat h = 0;
if (!self.cellAutoHeightManager.heightCacheDict.count) {
[self reloadData];
}
NSArray *values = [self.cellAutoHeightManager.heightCacheDict allValues];
for (NSNumber *number in values) {
h += [number floatValue];
}
return h;
}
- (SDCellAutoHeightManager *)cellAutoHeightManager
{
SDCellAutoHeightManager *cellAutoHeightManager = objc_getAssociatedObject(self, _cmd);
if (!cellAutoHeightManager) {
cellAutoHeightManager = [[SDCellAutoHeightManager alloc] init];
[self setCellAutoHeightManager:cellAutoHeightManager];
}
return cellAutoHeightManager;
}
- (void)setCellAutoHeightManager:(SDCellAutoHeightManager *)cellAutoHeightManager
{
objc_setAssociatedObject(self, @selector(cellAutoHeightManager), cellAutoHeightManager, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (void)setCellDataSetting:(AutoCellHeightDataSettingBlock)cellDataSetting
{
self.cellAutoHeightManager.cellDataSetting = cellDataSetting;
}
- (AutoCellHeightDataSettingBlock)cellDataSetting
{
return self.cellAutoHeightManager.cellDataSetting;
}
@end
@implementation UITableViewController (SDTableViewControllerAutoCellHeight)
- (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath cellContentViewWidth:(CGFloat)width
{
return [self cellHeightForIndexPath:indexPath cellContentViewWidth:width tableView:self.tableView];
}
@end
@implementation NSObject (SDAnyObjectAutoCellHeight)
- (CGFloat)cellHeightForIndexPath:(NSIndexPath *)indexPath cellContentViewWidth:(CGFloat)width tableView:(UITableView *)tableView
{
tableView.cellAutoHeightManager.modelTableview = tableView;
if (tableView.cellAutoHeightManager.contentViewWidth != width) {
tableView.cellAutoHeightManager.contentViewWidth = width;
}
if ([tableView.cellAutoHeightManager heightCacheForIndexPath:indexPath]) {
return [[tableView.cellAutoHeightManager heightCacheForIndexPath:indexPath] floatValue];
}
UITableViewCell *cell = [tableView.dataSource tableView:tableView cellForRowAtIndexPath:indexPath];
tableView.cellAutoHeightManager.modelCell = cell;
if (cell.contentView.width_sd != width) {
cell.contentView.width_sd = width;
}
return [[tableView cellAutoHeightManager] cellHeightForIndexPath:indexPath model:nil keyPath:nil];
}
@end

View File

@@ -0,0 +1,484 @@
//
// UIView+SDAutoLayout.h
//
// Created by gsd on 15/10/6.
// Copyright (c) 2015年 gsd. All rights reserved.
//
/*
*************************************************************************
--------- INTRODUCTION ---------
USAGE:
MODE 1. >>>>>>>>>>>>>>> You can use it in this way:
Demo.sd_layout
.topSpaceToView(v1, 100)
.bottomSpaceToView(v3, 100)
.leftSpaceToView(v0, 150)
.rightSpaceToView(v2, 150);
MODE 2. >>>>>>>>>>>>>>> You can also use it in this way that is more brevity:
Demo.sd_layout.topSpaceToView(v1, 100).bottomSpaceToView(v3, 100).leftSpaceToView(v0, 150).rightSpaceToView(v2, 150);
*************************************************************************
*/
/*
*********************************************************************************
*
* 在您使用此自动布局库的过程中如果出现bug请及时以以下任意一种方式联系我们我们会及时修复bug并
* 帮您解决问题。
* QQ : 2689718696(gsdios)
* Email : gsdios@126.com
* GitHub: https://github.com/gsdios
* 新浪微博:GSD_iOS
*
* 视频教程http://www.letv.com/ptv/vplay/24038772.html
* 用法示例https://github.com/gsdios/SDAutoLayout/blob/master/README.md
*
*********************************************************************************
SDAutoLayout
版本2.1.7
发布2016.08.12
*/
// 如果需要用“断言”调试程序请打开此宏
//#define SDDebugWithAssert
#import <UIKit/UIKit.h>
@class SDAutoLayoutModel, SDUIViewCategoryManager;
typedef SDAutoLayoutModel *(^MarginToView)(id viewOrViewsArray, CGFloat value);
typedef SDAutoLayoutModel *(^Margin)(CGFloat value);
typedef SDAutoLayoutModel *(^MarginEqualToView)(UIView *toView);
typedef SDAutoLayoutModel *(^WidthHeight)(CGFloat value);
typedef SDAutoLayoutModel *(^WidthHeightEqualToView)(UIView *toView, CGFloat ratioValue);
typedef SDAutoLayoutModel *(^AutoHeightWidth)(CGFloat ratioValue);
typedef SDAutoLayoutModel *(^SameWidthHeight)();
typedef SDAutoLayoutModel *(^Offset)(CGFloat value);
typedef void (^SpaceToSuperView)(UIEdgeInsets insets);
@interface SDAutoLayoutModel : NSObject
/*
*************************说明************************
方法名中带有“SpaceToView”的需要传递2个参数UIView参照view 和 CGFloat间距数值
方法名中带有“RatioToView”的需要传递2个参数UIView参照view 和 CGFloat倍数
方法名中带有“EqualToView”的需要传递1个参数UIView参照view
方法名中带有“Is”的需要传递1个参数CGFloat数值
*****************************************************
*/
/* 设置距离其它view的间距 */
/** 左边到其参照view之间的间距参数为“(View 或者 view数组, CGFloat)” */
@property (nonatomic, copy, readonly) MarginToView leftSpaceToView;
/** 右边到其参照view之间的间距参数为“(View, CGFloat)” */
@property (nonatomic, copy, readonly) MarginToView rightSpaceToView;
/** 顶部到其参照view之间的间距参数为“(View 或者 view数组, CGFloat)” */
@property (nonatomic, copy, readonly) MarginToView topSpaceToView;
/** 底部到其参照view之间的间距参数为“(View, CGFloat)” */
@property (nonatomic, copy, readonly) MarginToView bottomSpaceToView;
/* 设置x、y、width、height、centerX、centerY 值 */
/** x值参数为“(CGFloat)” */
@property (nonatomic, copy, readonly) Margin xIs;
/** y值参数为“(CGFloat)” */
@property (nonatomic, copy, readonly) Margin yIs;
/** centerX值参数为“(CGFloat)” */
@property (nonatomic, copy, readonly) Margin centerXIs;
/** centerY值参数为“(CGFloat)” */
@property (nonatomic, copy, readonly) Margin centerYIs;
/** 宽度值,参数为“(CGFloat)” */
@property (nonatomic, copy, readonly) WidthHeight widthIs;
/** 高度值,参数为“(CGFloat)” */
@property (nonatomic, copy, readonly) WidthHeight heightIs;
/* 设置最大宽度和高度、最小宽度和高度 */
/** 最大宽度值,参数为“(CGFloat)” */
@property (nonatomic, copy, readonly) WidthHeight maxWidthIs;
/** 最大高度值,参数为“(CGFloat)” */
@property (nonatomic, copy, readonly) WidthHeight maxHeightIs;
/** 最小宽度值,参数为“(CGFloat)” */
@property (nonatomic, copy, readonly) WidthHeight minWidthIs;
/** 最小高度值,参数为“(CGFloat)” */
@property (nonatomic, copy, readonly) WidthHeight minHeightIs;
/* 设置和某个参照view的边距相同 */
/** 左间距与参照view相同参数为“(View)” */
@property (nonatomic, copy, readonly) MarginEqualToView leftEqualToView;
/** 右间距与参照view相同参数为“(View)” */
@property (nonatomic, copy, readonly) MarginEqualToView rightEqualToView;
/** 顶部间距与参照view相同参数为“(View)” */
@property (nonatomic, copy, readonly) MarginEqualToView topEqualToView;
/** 底部间距与参照view相同参数为“(View)” */
@property (nonatomic, copy, readonly) MarginEqualToView bottomEqualToView;
/** centerX与参照view相同参数为“(View)” */
@property (nonatomic, copy, readonly) MarginEqualToView centerXEqualToView;
/** centerY与参照view相同参数为“(View)” */
@property (nonatomic, copy, readonly) MarginEqualToView centerYEqualToView;
/* 设置宽度或者高度等于参照view的多少倍 */
/** 宽度是参照view宽度的多少倍参数为“(View, CGFloat)” */
@property (nonatomic, copy, readonly) WidthHeightEqualToView widthRatioToView;
/** 高度是参照view高度的多少倍参数为“(View, CGFloat)” */
@property (nonatomic, copy, readonly) WidthHeightEqualToView heightRatioToView;
/** 设置一个view的宽度和它的高度相同参数为空“()” */
@property (nonatomic, copy, readonly) SameWidthHeight widthEqualToHeight;
/** 设置一个view的高度和它的宽度相同参数为空“()” */
@property (nonatomic, copy, readonly) SameWidthHeight heightEqualToWidth;
/** 自适应高度传入高宽比值label可以传0实现文字高度自适应 */
@property (nonatomic, copy, readonly) AutoHeightWidth autoHeightRatio;
/** 自适应宽度,参数为宽高比值 */
@property (nonatomic, copy, readonly) AutoHeightWidth autoWidthRatio;
/* 填充父view(快捷方法) */
/** 传入UIEdgeInsetsMake(top, left, bottom, right)可以快捷设置view到其父view上左下右的间距 */
@property (nonatomic, copy, readonly) SpaceToSuperView spaceToSuperView;
/** 设置偏移量,参数为“(CGFloat value)目前只有带有equalToView的方法可以设置offset” */
@property (nonatomic, copy, readonly) Offset offset;
@property (nonatomic, weak) UIView *needsAutoResizeView;
@end
#pragma mark - UIView 高度、宽度自适应相关方法
@interface UIView (SDAutoHeightWidth)
/** 设置Cell的高度自适应也可用于设置普通view内容高度自适应 */
- (void)setupAutoHeightWithBottomView:(UIView *)bottomView bottomMargin:(CGFloat)bottomMargin;
/** 用于设置普通view内容宽度自适应 */
- (void)setupAutoWidthWithRightView:(UIView *)rightView rightMargin:(CGFloat)rightMargin;
/** 设置Cell的高度自适应也可用于设置普通view内容自适应应用于当你不确定哪个view在自动布局之后会排布在最下方最为bottomView的时候可以调用次方法将所有可能在最下方的view都传过去 */
- (void)setupAutoHeightWithBottomViewsArray:(NSArray *)bottomViewsArray bottomMargin:(CGFloat)bottomMargin;
/** 更新布局主动刷新布局如果你需要设置完布局代码就获得view的frame请调用此方法 */
- (void)updateLayout;
/** 更新cell内部的控件的布局cell内部控件专属的更新约束方法,如果启用了cell frame缓存则会自动清除缓存再更新约束 */
- (void)updateLayoutWithCellContentView:(UIView *)cellContentView;
/** 清空高度自适应设置 */
- (void)clearAutoHeigtSettings;
/** 清空宽度自适应设置 */
- (void)clearAutoWidthSettings;
@property (nonatomic) CGFloat autoHeight;
@property (nonatomic, readonly) SDUIViewCategoryManager *sd_categoryManager;
@property (nonatomic, readonly) NSMutableArray *sd_bottomViewsArray;
@property (nonatomic) CGFloat sd_bottomViewBottomMargin;
@property (nonatomic) NSArray *sd_rightViewsArray;
@property (nonatomic) CGFloat sd_rightViewRightMargin;
@end
#pragma mark - UIView 设置圆角半径、自动布局回调block等相关方法
@interface UIView (SDLayoutExtention)
/** 自动布局完成后的回调block可以在这里获取到view的真实frame */
@property (nonatomic) void (^didFinishAutoLayoutBlock)(CGRect frame);
/** 添加一组子view */
- (void)sd_addSubviews:(NSArray *)subviews;
/* 设置圆角 */
/** 设置圆角半径值 */
@property (nonatomic, strong) NSNumber *sd_cornerRadius;
/** 设置圆角半径值为view宽度的多少倍 */
@property (nonatomic, strong) NSNumber *sd_cornerRadiusFromWidthRatio;
/** 设置圆角半径值为view高度的多少倍 */
@property (nonatomic, strong) NSNumber *sd_cornerRadiusFromHeightRatio;
/** 设置等宽子view子view需要在同一水平方向 */
@property (nonatomic, strong) NSArray *sd_equalWidthSubviews;
@end
#pragma mark - UIView 九宫格浮动布局效果
@interface UIView (SDAutoFlowItems)
/**
* 设置类似collectionView效果的固定间距自动宽度浮动子view
* viewsArray : 需要浮动布局的所有视图
* perRowItemsCount : 每行显示的视图个数
* verticalMargin : 视图之间的垂直间距
* horizontalMargin : 视图之间的水平间距
* vInset : 上下缩进值
* hInset : 左右缩进值
*/
- (void)setupAutoWidthFlowItems:(NSArray *)viewsArray withPerRowItemsCount:(NSInteger)perRowItemsCount verticalMargin:(CGFloat)verticalMargin horizontalMargin:(CGFloat)horizontalMagin verticalEdgeInset:(CGFloat)vInset horizontalEdgeInset:(CGFloat)hInset;
/** 清除固定间距自动宽度浮动子view设置 */
- (void)clearAutoWidthFlowItemsSettings;
/**
* 设置类似collectionView效果的固定宽带自动间距浮动子view
* viewsArray : 需要浮动布局的所有视图
* perRowItemsCount : 每行显示的视图个数
* verticalMargin : 视图之间的垂直间距
* vInset : 上下缩进值
* hInset : 左右缩进值
*/
- (void)setupAutoMarginFlowItems:(NSArray *)viewsArray withPerRowItemsCount:(NSInteger)perRowItemsCount itemWidth:(CGFloat)itemWidth verticalMargin:(CGFloat)verticalMargin verticalEdgeInset:(CGFloat)vInset horizontalEdgeInset:(CGFloat)hInset;
/** 清除固定宽带自动间距浮动子view设置 */
- (void)clearAutoMarginFlowItemsSettings;
@end
#pragma mark - UIView 设置约束、更新约束、清空约束、从父view移除并清空约束、开启cell的frame缓存等相关方法
@interface UIView (SDAutoLayout)
/** 开始自动布局 */
- (SDAutoLayoutModel *)sd_layout;
/** 清空之前的自动布局设置,重新开始自动布局(重新生成布局约束并使其在父view的布局序列数组中位置保持不变) */
- (SDAutoLayoutModel *)sd_resetLayout;
/** 清空之前的自动布局设置,重新开始自动布局(重新生成布局约束并添加到父view布局序列数组中的最后一个位置) */
- (SDAutoLayoutModel *)sd_resetNewLayout;
/** 是否关闭自动布局 */
@property (nonatomic, getter = sd_isClosingAutoLayout) BOOL sd_closeAutoLayout;
/** 从父view移除并清空约束 */
- (void)removeFromSuperviewAndClearAutoLayoutSettings;
/** 清空之前的自动布局设置 */
- (void)sd_clearAutoLayoutSettings;
/** 将自身frame清零一般在cell内部控件重用前调用 */
- (void)sd_clearViewFrameCache;
/** 将自己的需要自动布局的subviews的frame(或者frame缓存)清零 */
- (void)sd_clearSubviewsAutoLayoutFrameCaches;
/** 设置固定宽度保证宽度不在自动布局过程再做中调整 */
@property (nonatomic, strong) NSNumber *fixedWidth;
/** 设置固定高度保证高度不在自动布局过程中再做调整 */
@property (nonatomic, strong) NSNumber *fixedHeight;
/** 启用cell frame缓存可以提高cell滚动的流畅度, 目前为cell专用方法后期会扩展到其他view */
- (void)useCellFrameCacheWithIndexPath:(NSIndexPath *)indexPath tableView:(UITableView *)tableview;
/** 所属tableview目前为cell专用属性后期会扩展到其他view */
@property (nonatomic) UITableView *sd_tableView;
/** cell的indexPath目前为cell专用属性后期会扩展到cell的其他子view */
@property (nonatomic) NSIndexPath *sd_indexPath;
- (NSMutableArray *)autoLayoutModelsArray;
- (void)addAutoLayoutModel:(SDAutoLayoutModel *)model;
@property (nonatomic) SDAutoLayoutModel *ownLayoutModel;
@property (nonatomic, strong) NSNumber *sd_maxWidth;
@property (nonatomic, strong) NSNumber *autoHeightRatioValue;
@property (nonatomic, strong) NSNumber *autoWidthRatioValue;
@end
#pragma mark - UIScrollView 内容竖向自适应、内容横向自适应方法
@interface UIScrollView (SDAutoContentSize)
/** 设置scrollview内容竖向自适应 */
- (void)setupAutoContentSizeWithBottomView:(UIView *)bottomView bottomMargin:(CGFloat)bottomMargin;
/** 设置scrollview内容横向自适应 */
- (void)setupAutoContentSizeWithRightView:(UIView *)rightView rightMargin:(CGFloat)rightMargin;
@end
#pragma mark - UILabel 开启富文本布局、设置单行文本label宽度自适应、 设置label最多可以显示的行数
@interface UILabel (SDLabelAutoResize)
/** 是否是attributedString */
@property (nonatomic) BOOL isAttributedContent;
/** 设置单行文本label宽度自适应 */
- (void)setSingleLineAutoResizeWithMaxWidth:(CGFloat)maxWidth;
/** 设置label最多可以显示多少行如果传0则显示所有行文字 */
- (void)setMaxNumberOfLinesToShow:(NSInteger)lineCount;
@end
#pragma mark - UIButton 设置button根据单行文字自适应
@interface UIButton (SDExtention)
/*
* 设置button根据单行文字自适应
* hPadding左右边距
*/
- (void)setupAutoSizeWithHorizontalPadding:(CGFloat)hPadding buttonHeight:(CGFloat)buttonHeight;
@end
#pragma mark - 其他方法(如果有需要可以自己利用以下接口拓展更多功能)
@interface SDAutoLayoutModelItem : NSObject
@property (nonatomic, strong) NSNumber *value;
@property (nonatomic, weak) UIView *refView;
@property (nonatomic, assign) CGFloat offset;
@property (nonatomic, strong) NSArray *refViewsArray;
@end
@interface UIView (SDChangeFrame)
@property (nonatomic) BOOL shouldReadjustFrameBeforeStoreCache;
@property (nonatomic) CGFloat left_sd;
@property (nonatomic) CGFloat top_sd;
@property (nonatomic) CGFloat right_sd;
@property (nonatomic) CGFloat bottom_sd;
@property (nonatomic) CGFloat centerX_sd;
@property (nonatomic) CGFloat centerY_sd;
@property (nonatomic) CGFloat width_sd;
@property (nonatomic) CGFloat height_sd;
@property (nonatomic) CGPoint origin_sd;
@property (nonatomic) CGSize size_sd;
// 兼容旧版本
@property (nonatomic) CGFloat left;
@property (nonatomic) CGFloat top;
@property (nonatomic) CGFloat right;
@property (nonatomic) CGFloat bottom;
@property (nonatomic) CGFloat centerX;
@property (nonatomic) CGFloat centerY;
@property (nonatomic) CGFloat width;
@property (nonatomic) CGFloat height;
@property (nonatomic) CGPoint origin;
@property (nonatomic) CGSize size;
@end
@interface SDUIViewCategoryManager : NSObject
@property (nonatomic, strong) NSArray *rightViewsArray;
@property (nonatomic, assign) CGFloat rightViewRightMargin;
@property (nonatomic, weak) UITableView *sd_tableView;
@property (nonatomic, strong) NSIndexPath *sd_indexPath;
@property (nonatomic, assign) BOOL hasSetFrameWithCache;
@property (nonatomic) BOOL shouldReadjustFrameBeforeStoreCache;
@property (nonatomic, assign, getter = sd_isClosingAutoLayout) BOOL sd_closeAutoLayout;
/** 设置类似collectionView效果的固定间距自动宽度浮动子view */
@property (nonatomic, strong) NSArray *flowItems;
@property (nonatomic, assign) CGFloat verticalMargin;
@property (nonatomic, assign) CGFloat horizontalMargin;
@property (nonatomic, assign) NSInteger perRowItemsCount;
@property (nonatomic, assign) CGFloat lastWidth;
/** 设置类似collectionView效果的固定宽带自动间距浮动子view */
@property (nonatomic, assign) CGFloat flowItemWidth;
@property (nonatomic, assign) BOOL shouldShowAsAutoMarginViews;
@property (nonatomic) CGFloat horizontalEdgeInset;
@property (nonatomic) CGFloat verticalEdgeInset;
@end

File diff suppressed because it is too large Load Diff