diff --git a/Framework/Info.plist b/Framework/Info.plist index 9c590b8..95d9477 100644 --- a/Framework/Info.plist +++ b/Framework/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.1.0 + 1.1.1 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/Framework/StencilLayout.xcodeproj/project.pbxproj b/Framework/StencilLayout.xcodeproj/project.pbxproj index 514104f..a6ecad9 100644 --- a/Framework/StencilLayout.xcodeproj/project.pbxproj +++ b/Framework/StencilLayout.xcodeproj/project.pbxproj @@ -22,6 +22,8 @@ /* Begin PBXBuildFile section */ 78BA7DBC3DDC290E76D30B00 /* Pods_StencilLayout.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 972C5CA58F3AD29DE3436AF5 /* Pods_StencilLayout.framework */; }; + 890C8F2D21AE695D004A2904 /* StencilAdditionalFooterCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 890C8F2B21AE695D004A2904 /* StencilAdditionalFooterCell.h */; }; + 890C8F2E21AE695D004A2904 /* StencilAdditionalFooterCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 890C8F2C21AE695D004A2904 /* StencilAdditionalFooterCell.m */; }; 892B849B1FDFCA4F00038DD0 /* StencilFlowLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 892B846F1FDFCA4F00038DD0 /* StencilFlowLayout.m */; }; 892B849C1FDFCA4F00038DD0 /* StencilInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 892B84701FDFCA4F00038DD0 /* StencilInfo.m */; }; 892B849D1FDFCA4F00038DD0 /* StencilColloectionViewDelegateFlowLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 892B84711FDFCA4F00038DD0 /* StencilColloectionViewDelegateFlowLayout.h */; }; @@ -71,6 +73,8 @@ /* Begin PBXFileReference section */ 0300DCBDE87F590E15B1AF5C /* Pods-StencilLayout.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-StencilLayout.debug.xcconfig"; path = "Pods/Target Support Files/Pods-StencilLayout/Pods-StencilLayout.debug.xcconfig"; sourceTree = ""; }; + 890C8F2B21AE695D004A2904 /* StencilAdditionalFooterCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StencilAdditionalFooterCell.h; sourceTree = ""; }; + 890C8F2C21AE695D004A2904 /* StencilAdditionalFooterCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StencilAdditionalFooterCell.m; sourceTree = ""; }; 892B846F1FDFCA4F00038DD0 /* StencilFlowLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StencilFlowLayout.m; sourceTree = ""; }; 892B84701FDFCA4F00038DD0 /* StencilInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StencilInfo.m; sourceTree = ""; }; 892B84711FDFCA4F00038DD0 /* StencilColloectionViewDelegateFlowLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StencilColloectionViewDelegateFlowLayout.h; sourceTree = ""; }; @@ -161,6 +165,7 @@ children = ( 892B848A1FDFCA4F00038DD0 /* Categories */, 892B84861FDFCA4F00038DD0 /* StencilAdditionalHeaderCell.m */, + 890C8F2C21AE695D004A2904 /* StencilAdditionalFooterCell.m */, 892B84811FDFCA4F00038DD0 /* StencilCollectionReusableView.h */, 892B848D1FDFCA4F00038DD0 /* StencilCollectionReusableView.m */, 892B84711FDFCA4F00038DD0 /* StencilColloectionViewDelegateFlowLayout.h */, @@ -214,6 +219,7 @@ children = ( 892B84911FDFCA4F00038DD0 /* SampleStencilSectionStyle.h */, 892B84901FDFCA4F00038DD0 /* StencilAdditionalHeaderCell.h */, + 890C8F2B21AE695D004A2904 /* StencilAdditionalFooterCell.h */, 892B84931FDFCA4F00038DD0 /* StencilInfo.h */, 892B84961FDFCA4F00038DD0 /* StencilItemCell.h */, 892B84941FDFCA4F00038DD0 /* StencilItemImageCell.h */, @@ -310,6 +316,7 @@ 892B84C21FDFCA4F00038DD0 /* StencilLayoutViewController.h in Headers */, 892B849D1FDFCA4F00038DD0 /* StencilColloectionViewDelegateFlowLayout.h in Headers */, 892B84A21FDFCA4F00038DD0 /* StencilDataParseUtil.h in Headers */, + 890C8F2D21AE695D004A2904 /* StencilAdditionalFooterCell.h in Headers */, 892B84B61FDFCA4F00038DD0 /* UIColor+StencilHexString.h in Headers */, 892B84A11FDFCA4F00038DD0 /* StencilStringUtil.h in Headers */, 892B84AC1FDFCA4F00038DD0 /* StencilCollectionReusableView.h in Headers */, @@ -480,6 +487,7 @@ files = ( 892B84B21FDFCA4F00038DD0 /* StencilLayoutViewController+SelectEvent.m in Sources */, 892B84A31FDFCA4F00038DD0 /* StencilStringUtil.m in Sources */, + 890C8F2E21AE695D004A2904 /* StencilAdditionalFooterCell.m in Sources */, 892B84AA1FDFCA4F00038DD0 /* StencilSectionFooterCell.m in Sources */, 892B84A51FDFCA4F00038DD0 /* StencilItemCell.m in Sources */, 892B84AB1FDFCA4F00038DD0 /* StencilLayoutViewController.m in Sources */, diff --git a/StencilLayout.podspec b/StencilLayout.podspec index 90000b4..27e23cd 100644 --- a/StencilLayout.podspec +++ b/StencilLayout.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = 'StencilLayout' s.summary = 'iOS一种基于模版的布局模式,旨在支持广告位灵活配置,高效运营,UI动态生成,提高开发效率。' - s.version = '1.1.0' + s.version = '1.1.1' s.license = { :type => 'MIT', :file => 'LICENSE' } s.authors = { 'pcjbird' => 'pcjbird@hotmail.com' } s.social_media_url = 'http://www.lessney.com' diff --git a/StencilLayout/StencilAdditionalFooterCell.m b/StencilLayout/StencilAdditionalFooterCell.m new file mode 100644 index 0000000..d04e47a --- /dev/null +++ b/StencilLayout/StencilAdditionalFooterCell.m @@ -0,0 +1,18 @@ +// +// StencilAdditionalFooterCell.m +// StencilLayout +// +// Created by pcjbird on 2018/11/28. +// Copyright © 2018 Zero Status. All rights reserved. +// + +#import "StencilAdditionalFooterCell.h" + +@implementation StencilAdditionalFooterCell + +-(void) updateDataSource:(id)ds +{ + +} + +@end diff --git a/StencilLayout/StencilLayoutDefine.h b/StencilLayout/StencilLayoutDefine.h index 5d2496f..2930766 100644 --- a/StencilLayout/StencilLayoutDefine.h +++ b/StencilLayout/StencilLayoutDefine.h @@ -15,9 +15,9 @@ //! 是否调试模式. #define bDebugMode ([[[NSUserDefaults standardUserDefaults] objectForKey:StencilLayoutDebugKey] boolValue]) -#define SDK_VERSION @"1.1.0" +#define SDK_VERSION @"1.1.1" -#define SDK_BUILD_VERSION @"201811270001" +#define SDK_BUILD_VERSION @"201811280001" #define SDKLog(fmt, ...) (bDebugMode ? NSLog((@"[🐌StencilLayout] %s (line %d) " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__) : nil) diff --git a/StencilLayout/StencilLayoutViewController.m b/StencilLayout/StencilLayoutViewController.m index 24a0823..e777ad2 100644 --- a/StencilLayout/StencilLayoutViewController.m +++ b/StencilLayout/StencilLayoutViewController.m @@ -13,6 +13,7 @@ #import "StencilSectionTitleCell.h" #import "StencilSectionFooterCell.h" #import "StencilAdditionalHeaderCell.h" +#import "StencilAdditionalFooterCell.h" #import "StencilItemCell.h" #import "StencilStringUtil.h" @@ -21,6 +22,7 @@ @interface StencilLayoutViewController () { NSMutableArray * _headers; + NSMutableArray * _footers; NSMutableArray * _dataSource; NSMutableArray * _cellNibNames; } @@ -64,6 +66,7 @@ -(void)SetupCollectionView [self.view addConstraints:constraints_v]; } _headers = [NSMutableArray array]; + _footers = [NSMutableArray array]; _dataSource = [NSMutableArray array]; _cellNibNames = [NSMutableArray array]; @@ -127,6 +130,20 @@ -(void)SetupCollectionView } } + //additional footer + if(self.footerDataSource && [self.footerDataSource respondsToSelector:@selector(stencilLayoutViewControllerAdditionalFooterNibNames:)]) + { + NSArray *nibNames = [self.footerDataSource stencilLayoutViewControllerAdditionalFooterNibNames:self]; + if([nibNames isKindOfClass:[NSArray class]]) + { + for(NSString* nibName in nibNames) + { + if([nibName length] > 0)[self.collectionView registerNib:[UINib nibWithNibName:nibName bundle:nil] forCellWithReuseIdentifier:nibName]; + } + [_cellNibNames addObjectsFromArray:nibNames]; + } + } + if([[[UIDevice currentDevice] systemVersion] floatValue] >= 10.0f) { if([self.collectionView respondsToSelector:@selector(setPrefetchingEnabled:)]) @@ -157,6 +174,14 @@ -(void) setAdditionalHeaderDataSource:(NSArray*)ds SDKLog(@"更新AdditionalHeader数据源,重新加载界面。"); } +-(void)setAdditionalFooterDataSource:(NSArray *)ds +{ + [_footers removeAllObjects]; + if([ds isKindOfClass:[NSArray class]])[_footers addObjectsFromArray:ds]; + [self.collectionView reloadData]; + SDKLog(@"更新AdditionalFooter数据源,重新加载界面。"); +} + -(void) loadWithDataSource:(NSArray*)ds replaceOld:(BOOL)bReplace { if(bReplace)[_dataSource removeAllObjects]; @@ -183,8 +208,9 @@ -(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { if(collectionView == self.collectionView) { - SDKLog(@"numberOfSections:%d",(int)([_headers count] + [_dataSource count])); - return ([_headers count] + [_dataSource count]); + NSUInteger count = [_headers count] + [_dataSource count] + [_footers count]; + SDKLog(@"numberOfSections:%@",@(count)); + return (NSInteger)count; } return 0; } @@ -230,6 +256,12 @@ -(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSec SDKLog(@"can not find section style: %@", adSection.styleId); } } + else if([_dataSource count] + [_footers count] > section) + { + section = section - [_dataSource count]; + SDKLog(@"numberOfItemsInFooterSection:%d(footer section index:%d)", 1, (int)section); + return 1; + } } } return 0; @@ -265,6 +297,12 @@ - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollection return headersize; } } + else if([_dataSource count] + [_footers count] > section) + { + section = section-[_dataSource count]; + SDKLog(@"referenceSizeForFooterInSection:%@(footer section index:%d)", NSStringFromCGSize(CGSizeZero), (int)section); + return CGSizeZero; + } } } @@ -457,6 +495,25 @@ -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellF } } } + else if([_dataSource count] + [_footers count] > section) + { + section = section - [_dataSource count]; + if(self.footerDataSource && [self.footerDataSource respondsToSelector:@selector(stencilLayoutViewControllerAdditionalFooterNibNames:)]) + { + NSArray *nibNames = [self.footerDataSource stencilLayoutViewControllerAdditionalFooterNibNames:self]; + if([nibNames isKindOfClass:[NSArray class]] && [nibNames count] > section) + { + NSString* nibName = [nibNames objectAtIndex:section]; + StencilAdditionalFooterCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:nibName forIndexPath:indexPath]; + id ds = [_footers objectAtIndex:section]; + [cell updateDataSource:ds]; + + return cell; + } + } + NSString *exception = [NSString stringWithFormat:@"无法为indexPath创建StencilAdditionaFooterCell,indexPath:%@",[indexPath description]]; + SDK_RAISE_EXCEPTION(exception); + } } } NSString *exception = [NSString stringWithFormat:@"无法为indexPath创建UICollectionViewCell,indexPath:%@",[indexPath description]]; @@ -594,6 +651,18 @@ - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollection } } + else if([_dataSource count] + [_footers count] > section) + { + section = section - [_dataSource count]; + if(self.footerDataSource && [self.footerDataSource respondsToSelector:@selector(stencilLayoutViewController:heightForAdditionalFooterAtIndex:)]) + { + CGSize size = CGSizeMake(SDKScreenWidth, [self.footerDataSource stencilLayoutViewController:self heightForAdditionalFooterAtIndex:section]); + SDKLog(@"sizeForItemAtIndexPath:%@(footer section index:%d)", NSStringFromCGSize(size), (int)section); + return size; + } + SDKLog(@"sizeForItemAtIndexPath:%@(footer section index:%d)", NSStringFromCGSize(CGSizeZero), (int)section); + return CGSizeZero; + } } } @@ -622,6 +691,10 @@ -(UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UIColle return UIEdgeInsetsMake(SDK_AUTOLAYOUTSPACE(adSection.fMarginTop), SDK_AUTOLAYOUTSPACE(sectionStyle.section_margin_left), SDK_AUTOLAYOUTSPACE(sectionStyle.section_margin_bottom), SDK_AUTOLAYOUTSPACE(sectionStyle.section_margin_right)); } } + else if([_dataSource count] + [_footers count] > section) + { + return UIEdgeInsetsZero; + } } } return UIEdgeInsetsZero; @@ -648,6 +721,10 @@ - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UIColl return UIEdgeInsetsMake(SDK_AUTOLAYOUTSPACE(sectionStyle.content_margin_top), SDK_AUTOLAYOUTSPACE(sectionStyle.content_margin_left), SDK_AUTOLAYOUTSPACE(sectionStyle.content_margin_bottom), SDK_AUTOLAYOUTSPACE(sectionStyle.content_margin_right)); } } + else if([_dataSource count] + [_footers count] > section) + { + return UIEdgeInsetsZero; + } } } return UIEdgeInsetsZero; @@ -674,6 +751,10 @@ - (UIColor*)collectionView:(UICollectionView *)collectionView layout:(UICollecti return sectionStyle.background ? sectionStyle.background :[UIColor clearColor]; } } + else if([_dataSource count] + [_footers count] > section) + { + return [UIColor clearColor]; + } } } return [UIColor clearColor]; @@ -700,6 +781,10 @@ - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectio return floorf(sectionStyle.item_line_spacing); } } + else if([_dataSource count] + [_footers count] > section) + { + return 0; + } } } return 0; @@ -725,6 +810,10 @@ - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectio return floorf(sectionStyle.item_interitem_spacing); } } + else if([_dataSource count] + [_footers count] > section) + { + return 0; + } } } return 0; @@ -773,6 +862,10 @@ -(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPat } } + else if([_dataSource count] + [_footers count] > section) + { + return; + } } } } @@ -807,6 +900,10 @@ - (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:( } } + else if([_dataSource count] + [_footers count] > section) + { + return; + } } } } diff --git a/StencilLayout/public_headers/StencilAdditionalFooterCell.h b/StencilLayout/public_headers/StencilAdditionalFooterCell.h new file mode 100644 index 0000000..96b8caa --- /dev/null +++ b/StencilLayout/public_headers/StencilAdditionalFooterCell.h @@ -0,0 +1,16 @@ +// +// StencilAdditionalFooterCell.h +// StencilLayout +// +// Created by pcjbird on 2018/11/28. +// Copyright © 2018 Zero Status. All rights reserved. +// + +#import + +@interface StencilAdditionalFooterCell : UICollectionViewCell + +-(void) updateDataSource:(id)ds; + +@end + diff --git a/StencilLayout/public_headers/StencilLayout.h b/StencilLayout/public_headers/StencilLayout.h index b641ee5..19b7ad8 100644 --- a/StencilLayout/public_headers/StencilLayout.h +++ b/StencilLayout/public_headers/StencilLayout.h @@ -8,6 +8,9 @@ // 框架名称:iOS模版布局框架SDK // 框架功能:基于模版的布局模式,旨在支持广告位灵活配置,高效运营,UI动态生成,提高开发效率。 // 修改记录: +// pcjbird 2018-11-28 Version:1.1.1 Build:201811280001 +// 1.支持尾部附加数据源 +// // pcjbird 2018-11-27 Version:1.1.0 Build:201811270001 // 1.Animated Image Support // @@ -60,6 +63,8 @@ FOUNDATION_EXPORT const unsigned char StencilLayoutVersionString[]; //头部数据源占位符 #define STENCILADDITIONALHEADERDATASOURCEPLACEHOLDER @"StencilAdditionalHeaderDataSourcePlaceHolder" +//尾部数据源占位符 +#define STENCILADDITIONALFOOTERDATASOURCEPLACEHOLDER @"StencilAdditionalFooterDataSourcePlaceHolder" //!模版样式更新通知 #define STENCIL_LAYOUT_STYLE_UPDATED_NOTIFICATION @"StencilLayoutStyleUpdatedNotification" @@ -72,6 +77,7 @@ FOUNDATION_EXPORT const unsigned char StencilLayoutVersionString[]; #import #import #import +#import #import /** StencilLayout错误定义 diff --git a/StencilLayout/public_headers/StencilLayoutViewController.h b/StencilLayout/public_headers/StencilLayoutViewController.h index 7e01dc8..171612f 100644 --- a/StencilLayout/public_headers/StencilLayoutViewController.h +++ b/StencilLayout/public_headers/StencilLayoutViewController.h @@ -128,6 +128,27 @@ @end +/** + *@brief StencilLayoutViewControllerAdditionalFooterDataSource + */ +@protocol StencilLayoutViewControllerAdditionalFooterDataSource +@optional +/** + *@brief AdditionalFooterCellNibs数据源,用于registerNib + *@param vc StencilLayoutViewController + *@return nib name的字符串数组 + */ +-(nullable NSArray*) stencilLayoutViewControllerAdditionalFooterNibNames:(nonnull StencilLayoutViewController*)vc; +/** + *@brief AdditionalFooterCell的高度 + *@param vc StencilLayoutViewController + *@param index 索引,从0开始 + *@return AdditionalFooterCell的高度 + */ +-(CGFloat) stencilLayoutViewController:(nonnull StencilLayoutViewController*)vc heightForAdditionalFooterAtIndex:(NSInteger)index; + +@end + /** *@brief StencilLayoutViewController */ @@ -158,6 +179,11 @@ */ @property(nullable, nonatomic, weak) id headerDataSource; +/** + *@brief additional footer datasource + */ +@property(nullable, nonatomic, weak) id footerDataSource; + /** *@brief 设置附加头部数据源 *@param ds 数据源 @@ -165,6 +191,13 @@ */ -(void) setAdditionalHeaderDataSource:(nullable NSArray*)ds; +/** + *@brief 设置附加尾部数据源 + *@param ds 数据源 + *@note 倘若尾部某一section确实不需要填充数据源,请填写STENCILADDITIONALFOOTERDATASOURCEPLACEHOLDER 数据源占位符,不能为空 + */ +-(void) setAdditionalFooterDataSource:(nullable NSArray*)ds; + /** *@brief 加载数据源 *@param ds 数据源