引言
- 应用场景: 查看多张大图,比如查看风险商户的证明材料,图片支持滑动切换
- 主要功能:进入查看器之后,可左右滑动查看上/下张,并支持下滑视图退出查看器
I 用法
/**
初始化查看大图的controller
@param imageUrls 所有大图的数组
@param originImageViews 所有小图原始的imageView数组
@param selectPage 选中的是第几个
@return 大图的controller
*/
- (id)initWithUrlStr:(NSArray<NSString *>*)imageUrls originImageViews:(NSArray<UIImageView *>*)originImageViews selectPage:(NSInteger)selectPage;
此功能推荐采用UIModalPresentationOverCurrentContext
- 用法一: 采用模型数据进行传递
避免多个数组下标不一致问题
//处理查看大图事件
- (void)showImageBrowser:(QCTCollectionModel*)m
{
[self setupImageBrowserModels];
KNImageBrowserViewController * imageBrowserViewController = [[KNImageBrowserViewController alloc] initWithImageBrowserModels:self.viewModel.ImageBrowserModels selectPage:m.selectPage];
// KNImageBrowserViewController * imageBrowserViewController = [[KNImageBrowserViewController alloc] initWithUrlStr:imageUrls originImageViews:imageView4smalls selectPage:m.selectPage];
[self presentViewController:imageBrowserViewController animated:YES completion:nil];
}
- 用法二: 废弃
- (void)showImageBrowser {
KNImageBrowserViewController * imageBrowserViewController = [[KNImageBrowserViewController alloc] initWithUrlStr:self.imageUrls originImageViews:self.originImageViews selectPage:self.selectPage];
[self.controller presentViewController:imageBrowserViewController animated:YES completion:nil];
}
II demo
2.1 数据模型
@interface KNImageBrowserModel : NSObject
/**
大图的图片地址
*/
@property(nonatomic,copy)NSString * urlStr;
/**
小图原始的imageView,用于加载大图时的占位图片
*/
@property(nonatomic,weak)UIImageView * smallImageView;
/**
选中的是第几个imageView
*/
@property(nonatomic,assign)NSInteger
- 构建数据模型:KNImageBrowserModel
KNImageBrowserModel * imageBrowserModel = [[KNImageBrowserModel alloc] init];
imageBrowserModel.smallImageView = imageView;
imageBrowserModel.urlStr = urlStr;
void)setupImageBrowserModels{
// NSArray *imageView4smalls = [self.viewModel.collectionDataArray valueForKeyPath:@"@distinctUnionOfObjects.imageView4small"];//arDistinct是一些含有originalAddress属性的对象集合
//
// NSArray *imageUrls = [self.viewModel.collectionDataArray valueForKeyPath:@"@distinctUnionOfObjects.originalAddress"];//arDistinct是一些含有originalAddress属性的对象集合
self.viewModel.ImageBrowserModels = [NSMutableArray array];
for ( QCTCollectionModel *obj in self.viewModel.collectionDataArray) {
KNImageBrowserModel * imageBrowserModel = [[KNImageBrowserModel alloc] init];
imageBrowserModel.smallImageView = obj.imageView4small;
imageBrowserModel.urlStr = obj.originalAddress;
[self.viewModel.ImageBrowserModels addObject:imageBrowserModel];
}
}
2.2 向下滑动触发退出操作。
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
CGFloat contentOffsetY = scrollView.contentOffset.y;
if ((contentOffsetY<0 && _touchFingerNumber==1) && (velocity.y<0 && fabs(velocity.y)>fabs(velocity.x))) {
//如果是向下滑动才触发消失的操作。
if ([self.delegate respondsToSelector:@selector(imageBrowserSubViewSingleTapWithModel:)]) {
[self.delegate imageBrowserSubViewSingleTapWithModel:_imageBrowserModel];
}
} else {
[self changeSizeCenterY:0.0];
CGFloat offsetX = (scrollView.frame.size.width > scrollView.contentSize.width) ? (scrollView.frame.size.width - scrollView.contentSize.width) * 0.5 : 0.0;
CGFloat offsetY = (scrollView.frame.size.height > scrollView.contentSize.height) ? (scrollView.frame.size.height - scrollView.contentSize.height) * 0.5 : 0.0;
self.subImageView.center = CGPointMake(scrollView.contentSize.width * 0.5 + offsetX, scrollView.contentSize.height * 0.5 + offsetY);
}
_touchFingerNumber = 0;
self.subScrollView.clipsToBounds = YES;
}
2.3 下载demo源码
- 应用场景: 查看多张大图,比如查看风险商户的证明材料,图片支持滑动切换
- 主要功能:进入查看器之后,可左右滑动查看上/下张,并支持下滑视图退出查看器
private projects
III 转场动画
- UIModalPresentationStyle
self.modalPresentationStyle = UIModalPresentationOverCurrentContext;
self.transitioningDelegate = self;
typedef NS_ENUM(NSInteger, UIModalPresentationStyle) {
UIModalPresentationFullScreen = 0,
UIModalPresentationPageSheet API_AVAILABLE(ios(3.2)) API_UNAVAILABLE(tvos),
UIModalPresentationFormSheet API_AVAILABLE(ios(3.2)) API_UNAVAILABLE(tvos),
UIModalPresentationCurrentContext API_AVAILABLE(ios(3.2)),
UIModalPresentationCustom API_AVAILABLE(ios(7.0)),
UIModalPresentationOverFullScreen API_AVAILABLE(ios(8.0)),
UIModalPresentationOverCurrentContext API_AVAILABLE(ios(8.0)),
UIModalPresentationPopover API_AVAILABLE(ios(8.0)) API_UNAVAILABLE(tvos),
UIModalPresentationBlurOverFullScreen API_AVAILABLE(tvos(11.0)) API_UNAVAILABLE(ios) API_UNAVAILABLE(watchos),
UIModalPresentationNone API_AVAILABLE(ios(7.0)) = -1,
UIModalPresentationAutomatic API_AVAILABLE(ios(13.0)) = -2,
};
3.1 Modal 转场动画
此功能推荐采用UIModalPresentationOverCurrentContext
- 实现代理方法UIViewControllerTransitioningDelegate
presentViewController 转场动画
#pragma
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
self.browserTranslation.isBrowserMainView = YES;// 进入
return self.browserTranslation;
}
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
self.browserTranslation.isBrowserMainView = NO;// 离开
return self.browserTranslation;
}
- 自定义UIViewControllerAnimatedTransitioning
@interface KNImageBrowserTranslation : NSObject<UIViewControllerAnimatedTransitioning>
/* 自定义转场动画 */
//动画时间
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
return 0.3;
}
//转场动画
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
// return ;
NSMutableArray * dataM = [self.mainBrowserMainView dataSource];
NSInteger currentIndex = [self.mainBrowserMainView selectPage];
KNImageBrowserModel * currentModel = [dataM objectAtIndex:currentIndex];
//转场过程中显示的view,所有动画控件都应该加在这上面
UIView * containerView = [transitionContext containerView];
//转场去往的控制器
UIViewController * toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
if (_isBrowserMainView) {
//是进入
[containerView addSubview:toViewController.view];
CGRect frame = [currentModel smallImageViewframeOriginWindow];
UIImage * image = [currentModel getCurrentImage];
UIImageView * imageView = [self addShadowImageViewWithFrame:frame image:image];
//隐藏子组件
[self.mainBrowserMainView subViewHidden:YES];
self.browserControllerView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.0];
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
imageView.frame = [currentModel imageViewframeShowWindow];
self.browserControllerView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:1.0];
} completion:^(BOOL finished) {
if ([transitionContext transitionWasCancelled]) {
[transitionContext completeTransition:NO];
} else {
[transitionContext completeTransition:YES];
[self.mainBrowserMainView subViewHidden:NO];
[imageView removeFromSuperview];
// [toViewController.view removeFromSuperview];
}
}];
} else {
//是离开
CGRect frame = [currentModel bigImageViewFrameOnScrollView];
UIImage * image = [currentModel getCurrentImage];
UIImageView * imageView = [self addShadowImageViewWithFrame:frame image:image];
[self.mainBrowserMainView subViewHidden:YES];
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
imageView.frame = [currentModel smallImageViewframeOriginWindow];
self.browserControllerView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.0];
} completion:^(BOOL finished) {
if ([transitionContext transitionWasCancelled]) {
[transitionContext completeTransition:NO];
} else {
[transitionContext completeTransition:YES];
[imageView removeFromSuperview];
}
}];
}
}
- (UIImageView *)addShadowImageViewWithFrame:(CGRect)frame image:(UIImage *)image {
UIImageView * imageView = [[UIImageView alloc] initWithFrame:frame];
imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.clipsToBounds = YES;
imageView.image = image;
[self.browserControllerView addSubview:imageView];
return imageView;
}
@end
3.2 push 转场动画
UIView transitionWithView:self.navigationController.view duration:0.5 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
[weakSelf.navigationController pushViewController:detail animated:NO];
} completion:nil];
see also
通过 isSelected 筛选选中的规格数据
- (NSString *)SpecValIds{
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"isSelected == %d",YES];
NSMutableArray *tmparr = [self.platProductAttributeAndSpecificationDto.ProductSpecificationDtos filteredArrayUsingPredicate:predicate];
NSArray *editReturnedModeltmparr = [tmparr valueForKeyPath:@"@distinctUnionOfObjects.id"];
NSString *string = [editReturnedModeltmparr componentsJoinedByString:@","];// iOS 将数组中的元素用符号拼接字符串的方法
return