Commit 31699c21 cgx

引入GKPhotoBrowser(YYImage)解决反馈图片查看问题

1 个父辈 2e89dba8
正在显示 33 个修改的文件 包含 1115 行增加43 行删除
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#import "FeedbackDetailController.h" #import "FeedbackDetailController.h"
#import "FeedbackRequestModel.h" #import "FeedbackRequestModel.h"
#import "GKPhotoBrowser.h"
@interface FeedbackDetailController () @interface FeedbackDetailController ()
@property (nonatomic, strong) UIScrollView *detailSV; @property (nonatomic, strong) UIScrollView *detailSV;
...@@ -25,7 +26,9 @@ ...@@ -25,7 +26,9 @@
@property (nonatomic, strong) ExceptionDefaultView *exceptionView; @property (nonatomic, strong) ExceptionDefaultView *exceptionView;
@end @end
@implementation FeedbackDetailController @implementation FeedbackDetailController {
NSMutableArray *_photos;
}
- (void)viewDidLoad { - (void)viewDidLoad {
[super viewDidLoad]; [super viewDidLoad];
...@@ -84,15 +87,22 @@ ...@@ -84,15 +87,22 @@
// 截取图片字符串链接 // 截取图片字符串链接
NSArray *imgUrls = [detailModel.content_img componentsSeparatedByString:@","]; NSArray *imgUrls = [detailModel.content_img componentsSeparatedByString:@","];
_photos = [NSMutableArray new];
for (int i = 0; i < imgUrls.count; i++) { for (int i = 0; i < imgUrls.count; i++) {
UIImageView *showIV = [[UIImageView alloc] initWithFrame:CGRectMake(i*(105 + 8), 0, 105, 105)]; UIImageView *showIV = [[UIImageView alloc] initWithFrame:CGRectMake(i*(105 + 8), 0, 105, 105)];
showIV.dk_alphaPicker = DKAlphaPickerWithAlphas(1.0, .5, .5); showIV.dk_alphaPicker = DKAlphaPickerWithAlphas(1.0, .5, .5);
[showIV yy_setImageWithURL:[NSURL URLWithString:imgUrls[i]] placeholder:[UIImage imageNamed:@"basicPlaceholder"]]; [showIV yy_setImageWithURL:[NSURL URLWithString:imgUrls[i]] placeholder:[UIImage imageNamed:@"basicPlaceholder"]];
[showIV cornerRadius:12.0]; [showIV cornerRadius:12.0];
showIV.tag = i;
[self.imgContainerView addSubview:showIV]; [self.imgContainerView addSubview:showIV];
UITapGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGRAction:)]; UITapGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGRAction:)];
[showIV addGestureRecognizer:tapGR]; [showIV addGestureRecognizer:tapGR];
showIV.userInteractionEnabled = YES; showIV.userInteractionEnabled = YES;
GKPhoto *photo = [GKPhoto new];
photo.url = [NSURL URLWithString:imgUrls[i]];
photo.sourceImageView = showIV;
[_photos addObject:photo];
} }
} }
...@@ -156,8 +166,10 @@ ...@@ -156,8 +166,10 @@
#pragma mark - 浏览图片 #pragma mark - 浏览图片
- (void)tapGRAction:(UITapGestureRecognizer *)gr { - (void)tapGRAction:(UITapGestureRecognizer *)gr {
UIImageView *showIV = (UIImageView *)gr.view; UIImageView *showIV = (UIImageView *)gr.view;
showIV.image; GKPhotoBrowser *browser = [GKPhotoBrowser photoBrowserWithPhotos:[_photos copy] currentIndex:showIV.tag];
DSLog(@"========="); browser.showStyle = GKPhotoBrowserShowStyleZoom;
browser.loadStyle = GKPhotoBrowserLoadStyleDeterminate;
[browser showFromVC:self];
} }
#pragma mark - 品牌模式 #pragma mark - 品牌模式
......
//
// GKLoadingView.h
// GKLoadingView
//
// Created by QuintGao on 2017/11/23.
// Copyright © 2017年 QuintGao. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "GKPhotoBrowserConfigure.h"
typedef NS_ENUM(NSUInteger, GKLoadingStyle) {
GKLoadingStyleIndeterminate, // 不明确的加载方式
GKLoadingStyleIndeterminateMask, // 不明确的加载方式带阴影
GKLoadingStyleDeterminate, // 明确的加载方式--进度条
GKLoadingStyleCustom // 自定义
};
@interface GKLoadingView : UIView
+ (instancetype)loadingViewWithFrame:(CGRect)frame style:(GKLoadingStyle)style;
@property (nonatomic, assign) GKPhotoBrowserFailStyle failStyle;
@property (nonatomic, strong) UIButton *centerButton;
/** 线条宽度:默认4 */
@property (nonatomic, assign) CGFloat lineWidth;
/** 圆弧半径:默认24 */
@property (nonatomic, assign) CGFloat radius;
/** 圆弧的背景颜色:默认半透明黑色 */
@property (nonatomic, strong) UIColor *bgColor;
/** 进度的颜色:默认白色 */
@property (nonatomic, strong) UIColor *strokeColor;
/** 进度,loadingStyle为GKLoadingStyleDeterminate时使用 */
@property (nonatomic, assign) CGFloat progress;
@property (nonatomic, copy) NSString *failText;
@property (nonatomic, strong) UIImage *failImage;
@property (nonatomic, copy) void (^progressChange)(GKLoadingView *loadingView, CGFloat progress);
@property (nonatomic, copy) void (^tapToReload)(void);
/**
开始动画方法-loadingStyle为GKLoadingStyleIndeterminate,GKLoadingStyleIndeterminateMask时使用
*/
- (void)startLoading;
/**
结束动画方法
*/
- (void)stopLoading;
- (void)showFailure;
- (void)hideFailure;
- (void)hideLoadingView;
- (void)removeAnimation;
// 在duration时间内加载,
- (void)startLoadingWithDuration:(NSTimeInterval)duration completion:(void (^)(GKLoadingView *loadingView, BOOL finished))completion;
@end
//
// GKPanGestureRecognizer.h
// GKPhotoBrowserDemo
//
// Created by gaokun on 2019/8/15.
// Copyright © 2019 QuintGao. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSUInteger, GKPanGestureRecognizerDirection) {
GKPanGestureRecognizerDirectionVertical,
GKPanGestureRecognizerDirectionHorizontal
};
@interface GKPanGestureRecognizer : UIPanGestureRecognizer
@property (nonatomic, assign) GKPanGestureRecognizerDirection direction;
@end
NS_ASSUME_NONNULL_END
//
// GKPanGestureRecognizer.m
// GKPhotoBrowserDemo
//
// Created by gaokun on 2019/8/15.
// Copyright © 2019 QuintGao. All rights reserved.
//
#import "GKPanGestureRecognizer.h"
int const static kDirectionPanThreshold = 5;
@interface GKPanGestureRecognizer()
@property (nonatomic, assign) BOOL isDrag;
@property (nonatomic, assign) int moveX;
@property (nonatomic, assign) int moveY;
@end
@implementation GKPanGestureRecognizer
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[super touchesMoved:touches withEvent:event];
if (self.state == UIGestureRecognizerStateFailed) return;
CGPoint nowPoint = [[touches anyObject] locationInView:self.view];
CGPoint prevPoint = [[touches anyObject] previousLocationInView:self.view];
_moveX += prevPoint.x - nowPoint.x;
_moveY += prevPoint.y - nowPoint.y;
if (!self.isDrag) {
if (abs(_moveX) > kDirectionPanThreshold) {
if (_direction == GKPanGestureRecognizerDirectionVertical) {
self.state = UIGestureRecognizerStateFailed;
}else {
_isDrag = YES;
}
}else if (abs(_moveY) > kDirectionPanThreshold) {
if (_direction == GKPanGestureRecognizerDirectionHorizontal) {
self.state = UIGestureRecognizerStateFailed;
}else {
_isDrag = YES;
}
}
}
}
- (void)reset {
[super reset];
_isDrag = NO;
_moveX = 0;
_moveY = 0;
}
@end
//
// GKPhotoBrowser.h
// GKPhotoBrowser
//
// Created by QuintGao on 2017/10/20.
// Copyright © 2017年 QuintGao. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "GKPhotoView.h"
NS_ASSUME_NONNULL_BEGIN
@class GKPhotoBrowser;
typedef void(^layoutBlock)(GKPhotoBrowser *photoBrowser, CGRect superFrame);
@protocol GKPhotoBrowserDelegate<NSObject>
@optional
// 滚动到一半时索引改变
- (void)photoBrowser:(GKPhotoBrowser *)browser didChangedIndex:(NSInteger)index;
// 选择photoView时回调
- (void)photoBrowser:(GKPhotoBrowser *)browser didSelectAtIndex:(NSInteger)index;
// 单击事件
- (void)photoBrowser:(GKPhotoBrowser *)browser singleTapWithIndex:(NSInteger)index;
// 长按事件
- (void)photoBrowser:(GKPhotoBrowser *)browser longPressWithIndex:(NSInteger)index;
// 旋转事件
- (void)photoBrowser:(GKPhotoBrowser *)browser onDeciceChangedWithIndex:(NSInteger)index isLandscape:(BOOL)isLandscape;
// 保存按钮点击事件
- (void)photoBrowser:(GKPhotoBrowser *)browser onSaveBtnClick:(NSInteger)index image:(UIImage *)image;
// 上下滑动消失
// 开始滑动时
- (void)photoBrowser:(GKPhotoBrowser *)browser panBeginWithIndex:(NSInteger)index;
// 结束滑动时 disappear:是否消失
- (void)photoBrowser:(GKPhotoBrowser *)browser panEndedWithIndex:(NSInteger)index willDisappear:(BOOL)disappear;
// 布局子视图
- (void)photoBrowser:(GKPhotoBrowser *)browser willLayoutSubViews:(NSInteger)index;
// browser完全消失回调
- (void)photoBrowser:(GKPhotoBrowser *)browser didDisappearAtIndex:(NSInteger)index;
// browser自定义加载方式时回调
- (void)photoBrowser:(GKPhotoBrowser *)browser loadImageAtIndex:(NSInteger)index progress:(float)progress isOriginImage:(BOOL)isOriginImage;
// browser加载失败自定义弹窗
- (void)photoBrowser:(GKPhotoBrowser *)browser loadFailedAtIndex:(NSInteger)index;
// browser UIScrollViewDelegate
- (void)photoBrowser:(GKPhotoBrowser *)browser scrollViewDidScroll:(UIScrollView *)scrollView;
- (void)photoBrowser:(GKPhotoBrowser *)browser scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
- (void)photoBrowser:(GKPhotoBrowser *)browser scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;
@end
@interface GKPhotoBrowser : UIViewController
/** 底部内容试图 */
@property (nonatomic, strong, readonly) UIView *contentView;
/** 图片模型数组 */
@property (nonatomic, strong, readonly) NSArray *photos;
/** 当前索引 */
@property (nonatomic, assign, readonly) NSInteger currentIndex;
/** 当前显示的photoView */
@property (nonatomic, strong, readonly) GKPhotoView *curPhotoView;
/** 是否是横屏 */
@property (nonatomic, assign, readonly) BOOL isLandscape;
/** 当前设备的方向 */
@property (nonatomic, assign, readonly) UIDeviceOrientation currentOrientation;
/** 显示方式 */
@property (nonatomic, assign) GKPhotoBrowserShowStyle showStyle;
/** 隐藏方式 */
@property (nonatomic, assign) GKPhotoBrowserHideStyle hideStyle;
/** 图片加载方式 */
@property (nonatomic, assign) GKPhotoBrowserLoadStyle loadStyle;
/** 原图加载加载方式 */
@property (nonatomic, assign) GKPhotoBrowserLoadStyle originLoadStyle;
/** 图片加载失败显示方式 */
@property (nonatomic, assign) GKPhotoBrowserFailStyle failStyle;
/** 代理 */
@property (nonatomic, weak) id<GKPhotoBrowserDelegate> delegate;
/// 是否跟随系统旋转,默认是NO,如果设置为YES,isScreenRotateDisabled属性将失效
@property (nonatomic, assign) BOOL isFollowSystemRotation;
/// 是否禁止屏幕旋转监测
@property (nonatomic, assign) BOOL isScreenRotateDisabled;
/// 是否禁用默认单击事件
@property (nonatomic, assign) BOOL isSingleTapDisabled;
/// 是否显示状态栏,默认NO:不显示状态栏
@property (nonatomic, assign) BOOL isStatusBarShow;
/// 状态栏样式,默认Light
@property (nonatomic, assign) UIStatusBarStyle statusBarStyle;
/// 滑动消失时是否隐藏原来的视图:默认YES
@property (nonatomic, assign) BOOL isHideSourceView;
/// 滑动切换图片时,是否恢复上(下)一张图片的缩放程度,默认是NO
/// 如果滑动超过一张,则恢复原状
@property (nonatomic, assign) BOOL isResumePhotoZoom;
/// 横屏时是否充满屏幕宽度,默认YES,为NO时图片自动填充屏幕
@property (nonatomic, assign) BOOL isFullWidthForLandScape;
/// 是否适配安全区域,默认NO,为YES时图片会自动适配iPhone X的安全区域
@property (nonatomic, assign) BOOL isAdaptiveSafeArea;
/// 是否启用滑动返回手势处理(当showStyle为GKPhotoBrowserShowStylePush时有效)
@property (nonatomic, assign) BOOL isPopGestureEnabled;
/// 是否隐藏countLabel,默认NO
@property (nonatomic, assign) BOOL hidesCountLabel;
/// 图片最大放大倍数
@property (nonatomic, assign) CGFloat maxZoomScale;
/// 双击放大倍数,默认maxZoomScale,不能超过maxZoomScale
@property (nonatomic, assign) CGFloat doubleZoomScale;
/// 动画时间,默认0.3
@property (nonatomic, assign) NSTimeInterval animDuration;
/// 浏览器背景(默认黑色)
@property (nonatomic, strong) UIColor *bgColor;
/// 数量Label,默认显示,若要隐藏需设置hidesCountLabel为YES
@property (nonatomic, strong) UILabel *countLabel;
/// 页码,默认隐藏
@property (nonatomic, strong) UIPageControl *pageControl;
/// 保存按钮,默认隐藏
@property (nonatomic, strong) UIButton *saveBtn;
/// 加载失败时显示的文字或图片
@property (nonatomic, copy) NSString *failureText;
@property (nonatomic, strong) UIImage *failureImage;
// 初始化方法
/**
创建图片浏览器
@param photos 包含GKPhoto对象的数组
@param currentIndex 当前的页码
@return 图片浏览器对象
*/
+ (instancetype)photoBrowserWithPhotos:(NSArray<GKPhoto *> *)photos currentIndex:(NSInteger)currentIndex;
- (instancetype)initWithPhotos:(NSArray<GKPhoto *> *)photos currentIndex:(NSInteger)currentIndex;
/// 自定义图片请求类
/// @param protocol 需实现GKWebImageProtocol协议
- (void)setupWebImageProtocol:(id<GKWebImageProtocol>)protocol;
/**
为浏览器添加自定义遮罩视图
@param coverViews 视图数组
@param layoutBlock 布局
*/
- (void)setupCoverViews:(NSArray *)coverViews layoutBlock:(layoutBlock)layoutBlock;
/**
显示图片浏览器
@param vc 控制器
*/
- (void)showFromVC:(UIViewController *)vc;
/**
隐藏图片浏览器
*/
- (void)dismiss;
/**
选中指定位置的内容
@param index 位置索引
*/
- (void)selectedPhotoWithIndex:(NSInteger)index animated:(BOOL)animated;
/**
移除指定位置的内容
@param index 位置索引
*/
- (void)removePhotoAtIndex:(NSInteger)index;
/**
重置图片浏览器
@param photos 图片内容数组
*/
- (void)resetPhotoBrowserWithPhotos:(NSArray *)photos;
/**
加载原图方法,外部调用
*/
- (void)loadCurrentPhotoImage;
@end
NS_ASSUME_NONNULL_END
//
// GKPhotoBrowserConfigure.h
// GKPhotoBrowser
//
// Created by QuintGao on 2020/10/19.
// Copyright © 2020年 QuintGao. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "UIScrollView+GKPhotoBrowser.h"
#define GKScreenW [UIScreen mainScreen].bounds.size.width
#define GKScreenH [UIScreen mainScreen].bounds.size.height
// 判断iPhone X
#define KIsiPhoneX [GKPhotoBrowserConfigure gk_isNotchedScreen]
// 底部安全区域高度
#define kSafeTopSpace (KIsiPhoneX ? 24.0f : 0.0f)
#define kSafeBottomSpace (KIsiPhoneX ? 34.0f : 0.0f)
// 默认最大缩放程度
#define kMaxZoomScale 2.0f
// 默认图片间距
#define kPhotoViewPadding 10
// 默认动画时间
#define kAnimationDuration 0.3f
// 加载本地图片
#define GKPhotoBrowserImage(name) [GKPhotoBrowserConfigure gk_imageWithName:name]
// 图片浏览器的显示方式
typedef NS_ENUM(NSUInteger, GKPhotoBrowserShowStyle) {
GKPhotoBrowserShowStyleNone, // 直接显示,默认方式
GKPhotoBrowserShowStyleZoom, // 缩放显示,动画效果
GKPhotoBrowserShowStylePush // push方式展示
};
// 图片浏览器的隐藏方式
typedef NS_ENUM(NSUInteger, GKPhotoBrowserHideStyle) {
GKPhotoBrowserHideStyleZoom, // 点击缩放消失
GKPhotoBrowserHideStyleZoomScale, // 点击缩放消失、滑动缩小后消失
GKPhotoBrowserHideStyleZoomSlide // 点击缩放消失、滑动平移后消失
};
// 图片浏览器的加载方式
typedef NS_ENUM(NSUInteger, GKPhotoBrowserLoadStyle) {
GKPhotoBrowserLoadStyleIndeterminate, // 不明确的加载方式
GKPhotoBrowserLoadStyleIndeterminateMask, // 不明确的加载方式带阴影
GKPhotoBrowserLoadStyleDeterminate, // 明确的加载方式带进度条
GKPhotoBrowserLoadStyleCustom // 自定义加载方式
};
// 图片加载失败的显示方式
typedef NS_ENUM(NSUInteger, GKPhotoBrowserFailStyle) {
GKPhotoBrowserFailStyleOnlyText, // 显示文字
GKPhotoBrowserFailStyleOnlyImage, // 显示图片
GKPhotoBrowserFailStyleImageAndText, // 显示图片+文字
GKPhotoBrowserFailStyleCustom // 自定义(如:显示HUD)
};
@interface GKPhotoBrowserConfigure : NSObject
/// 安全区域
+ (UIEdgeInsets)gk_safeAreaInsets;
/// 状态栏frame
+ (CGRect)gk_statusBarFrame;
/// 判断是否是刘海屏
+ (BOOL)gk_isNotchedScreen;
/// 根据图片名字获取图片
/// @param name 图片名字
+ (UIImage *)gk_imageWithName:(NSString *)name;
@end
//
// GKPhotoBrowserConfigure.m
// GKPhotoBrowser
//
// Created by gaokun on 2020/10/19.
// Copyright © 2020 QuintGao. All rights reserved.
//
#import "GKPhotoBrowserConfigure.h"
/// 设备宽度,跟横竖屏无关
#define GKPHOTO_DEVICE_WIDTH MIN([[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height)
/// 设备高度,跟横竖屏无关
#define GKPHOTO_DEVICE_HEIGHT MAX([[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height)
NSString *const GKPhotoBrowserBundleName = @"GKPhotoBrowser";
@interface GKPhotoPortraitViewController : UIViewController
@end
@implementation GKPhotoPortraitViewController
- (BOOL)shouldAutorotate {
return NO;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
@end
@implementation GKPhotoBrowserConfigure
+ (UIEdgeInsets)gk_safeAreaInsets {
UIEdgeInsets safeAreaInsets = UIEdgeInsetsZero;
if (@available(iOS 11.0, *)) {
UIWindow *window = [self getKeyWindow];
if (!window) {
// keyWindow还没创建时,通过创建临时window获取安全区域
window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
if (window.safeAreaInsets.bottom <= 0) {
UIViewController *viewController = [UIViewController new];
window.rootViewController = viewController;
}
}
safeAreaInsets = window.safeAreaInsets;
}
return safeAreaInsets;
}
+ (CGRect)gk_statusBarFrame {
CGRect statusBarFrame = CGRectZero;
if (@available(iOS 13.0, *)) {
statusBarFrame = [GKPhotoBrowserConfigure getKeyWindow].windowScene.statusBarManager.statusBarFrame;
}
if (CGRectEqualToRect(statusBarFrame, CGRectZero)) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
statusBarFrame = [UIApplication sharedApplication].statusBarFrame;
#pragma clang diagnostic pop
}
if (CGRectEqualToRect(statusBarFrame, CGRectZero)) {
CGFloat statusBarH = [GKPhotoBrowserConfigure gk_isNotchedScreen] ? 44 : 20;
statusBarFrame = CGRectMake(0, 0, GKScreenW, statusBarH);
}
return statusBarFrame;
}
static NSInteger isNotchedScreen = -1;
+ (BOOL)gk_isNotchedScreen {
if (isNotchedScreen < 0) {
if (@available(iOS 12.0, *)) {
/*
检测方式解释/测试要点:
1. iOS 11 与 iOS 12 可能行为不同,所以要分别测试。
2. 与触发 [QMUIHelper isNotchedScreen] 方法时的进程有关,例如 https://github.com/Tencent/QMUI_iOS/issues/482#issuecomment-456051738 里提到的 [NSObject performSelectorOnMainThread:withObject:waitUntilDone:NO] 就会导致较多的异常。
3. iOS 12 下,在非第2点里提到的情况下,iPhone、iPad 均可通过 UIScreen -_peripheryInsets 方法的返回值区分,但如果满足了第2点,则 iPad 无法使用这个方法,这种情况下要依赖第4点。
4. iOS 12 下,不管是否满足第2点,不管是什么设备类型,均可以通过一个满屏的 UIWindow 的 rootViewController.view.frame.origin.y 的值来区分,如果是非全面屏,这个值必定为20,如果是全面屏,则可能是24或44等不同的值。但由于创建 UIWindow、UIViewController 等均属于较大消耗,所以只在前面的步骤无法区分的情况下才会使用第4点。
5. 对于第4点,经测试与当前设备的方向、是否有勾选 project 里的 General - Hide status bar、当前是否处于来电模式的状态栏这些都没关系。
*/
SEL peripheryInsetsSelector = NSSelectorFromString([NSString stringWithFormat:@"_%@%@", @"periphery", @"Insets"]);
UIEdgeInsets peripheryInsets = UIEdgeInsetsZero;
[self object:[UIScreen mainScreen] performSelector:peripheryInsetsSelector returnValue:&peripheryInsets];
if (peripheryInsets.bottom <= 0) {
UIWindow *window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
peripheryInsets = window.safeAreaInsets;
if (peripheryInsets.bottom <= 0) {
// 使用一个强制竖屏的rootViewController,避免一个仅支持竖屏的App在横屏启动时会受到这里创建的window的影响,导致状态栏、safeAreaInsets等错乱
GKPhotoPortraitViewController *viewController = [GKPhotoPortraitViewController new];
window.rootViewController = viewController;
if (CGRectGetMinY(viewController.view.frame) > 20) {
peripheryInsets.bottom = 1;
}
}
}
isNotchedScreen = peripheryInsets.bottom > 0 ? 1 : 0;
} else {
isNotchedScreen = [self is58InchScreen] ? 1 : 0;
}
}
return isNotchedScreen > 0;
}
+ (void)object:(NSObject *)object performSelector:(SEL)selector returnValue:(void *)returnValue {
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[object methodSignatureForSelector:selector]];
[invocation setTarget:object];
[invocation setSelector:selector];
[invocation invoke];
if (returnValue) {
[invocation getReturnValue:returnValue];
}
}
+ (UIWindow *)getKeyWindow {
UIWindow *window = nil;
if (@available(iOS 13.0, *)) {
for (UIWindowScene *windowScene in [UIApplication sharedApplication].connectedScenes) {
if (windowScene.activationState == UISceneActivationStateForegroundActive) {
for (UIWindow *w in windowScene.windows) {
if (window.isKeyWindow) {
window = w;
break;
}
}
}
}
}
if (!window) {
window = [UIApplication sharedApplication].windows.firstObject;
if (!window.isKeyWindow) {
#pragma clang diagnostic push
#pragma clang disagnostic ignored "-Wdeprecated-declarations"
UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
#pragma clang disagnostic pop
if (CGRectEqualToRect(keyWindow.bounds, UIScreen.mainScreen.bounds)) {
window = keyWindow;
}
}
}
return window;
}
+ (UIImage *)gk_imageWithName:(NSString *)name {
static NSBundle *resourceBundle = nil;
if (!resourceBundle) {
NSBundle *mainBundle = [NSBundle bundleForClass:self];
NSString *resourcePath = [mainBundle pathForResource:GKPhotoBrowserBundleName ofType:@"bundle"];
resourceBundle = [NSBundle bundleWithPath:resourcePath] ?: mainBundle;
}
UIImage *image = [UIImage imageNamed:name inBundle:resourceBundle compatibleWithTraitCollection:nil];
return image;
}
static NSInteger is58InchScreen = -1;
+ (BOOL)is58InchScreen {
if (is58InchScreen < 0) {
// Both iPhone XS and iPhone X share the same actual screen sizes, so no need to compare identifiers
// iPhone XS 和 iPhone X 的物理尺寸是一致的,因此无需比较机器 Identifier
is58InchScreen = (GKPHOTO_DEVICE_WIDTH == self.screenSizeFor58Inch.width && GKPHOTO_DEVICE_HEIGHT == self.screenSizeFor58Inch.height) ? 1 : 0;
}
return is58InchScreen > 0;
}
+ (CGSize)screenSizeFor58Inch {
return CGSizeMake(375, 812);
}
@end
//
// GKPhotoManager.h
// GKPhotoBrowserDemo
//
// Created by gaokun on 2020/6/16.
// Copyright © 2020 QuintGao. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <Photos/Photos.h>
#import "GKPhotoBrowserConfigure.h"
NS_ASSUME_NONNULL_BEGIN
@interface GKPhoto : NSObject
/** 图片地址 */
@property (nonatomic, strong) NSURL *url;
/** 原图地址 */
@property (nonatomic, strong) NSURL *originUrl;
/** 来源imageView */
@property (nonatomic, strong) UIImageView *sourceImageView;
/** 来源frame */
@property (nonatomic, assign) CGRect sourceFrame;
/** 图片(静态) */
@property (nonatomic, strong, nullable) UIImage *image;
/** 相册图片资源 */
@property (nonatomic, strong, nullable) PHAsset *imageAsset;
/** 占位图 */
@property (nonatomic, strong, nullable) UIImage *placeholderImage;
/************************内部使用,无需关心 ********************/
/** 图片是否加载完成 */
@property (nonatomic, assign) BOOL finished;
@property (nonatomic, assign) BOOL originFinished;
/** 图片是否加载失败 */
@property (nonatomic, assign) BOOL failed;
/** 记录photoView是否缩放 */
@property (nonatomic, assign) BOOL isZooming;
/** 记录photoView缩放时的rect */
@property (nonatomic, assign) CGRect zoomRect;
/** 记录每个GKPhotoView的滑动位置 */
@property (nonatomic, assign) CGPoint offset;
@end
@interface GKPhotoManager : NSObject
/// 加载相册资源图片
/// @param imageAsset PHAsset对象
/// @param completion 完成回调
+ (PHImageRequestID)loadImageDataWithImageAsset:(PHAsset *)imageAsset completion:(nonnull void(^)(NSData *_Nullable data))completion;
/// 根据宽度加载相册资源图片
/// @param asset PHAsset对象
/// @param photoWidth 宽度
/// @param completion 完成回调
+ (PHImageRequestID)loadImageWithAsset:(PHAsset *)asset photoWidth:(CGFloat)photoWidth completion:(nonnull void(^)(UIImage *_Nullable image))completion;
@end
NS_ASSUME_NONNULL_END
//
// GKPhotoManager.m
// GKPhotoBrowserDemo
//
// Created by gaokun on 2020/6/16.
// Copyright © 2020 QuintGao. All rights reserved.
//
#import "GKPhotoManager.h"
@implementation GKPhoto
@end
@implementation GKPhotoManager
+ (PHImageRequestID)loadImageDataWithImageAsset:(PHAsset *)imageAsset completion:(void (^)(NSData * _Nullable))completion {
PHImageRequestOptions *options = [PHImageRequestOptions new];
options.networkAccessAllowed = YES;
options.resizeMode = PHImageRequestOptionsResizeModeFast;
PHImageRequestID requestID = [[PHImageManager defaultManager] requestImageDataForAsset:imageAsset options:options resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
BOOL complete = ![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey] && ![[info objectForKey:PHImageResultIsDegradedKey] boolValue];
if (complete && imageData) {
completion(imageData);
} else {
completion(nil);
}
}];
return requestID;
}
+ (PHImageRequestID)loadImageWithAsset:(PHAsset *)asset photoWidth:(CGFloat)photoWidth completion:(void (^)(UIImage * _Nullable))completion {
CGSize imageSize;
CGFloat scale = 2.0;
if (UIScreen.mainScreen.bounds.size.width > 700) {
scale = 1.5;
}
CGFloat aspectRatio = asset.pixelWidth / (CGFloat)asset.pixelHeight;
CGFloat pixelWidth = photoWidth * scale;
// 超宽图片
if (aspectRatio > 1.8) {
pixelWidth = pixelWidth * aspectRatio;
}
// 超高图片
if (aspectRatio < 0.2) {
pixelWidth = pixelWidth * 0.5;
}
CGFloat pixelHeight = pixelWidth / aspectRatio;
imageSize = CGSizeMake(pixelWidth, pixelHeight);
PHImageRequestOptions *option = [[PHImageRequestOptions alloc] init];
option.resizeMode = PHImageRequestOptionsResizeModeFast;
PHImageRequestID requestID = [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:imageSize contentMode:PHImageContentModeAspectFill options:option resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
BOOL cancelled = [[info objectForKey:PHImageCancelledKey] boolValue];
if (!cancelled && result) {
!completion ? : completion(result);
}
// Download image from iCloud / 从iCloud下载图片
if ([info objectForKey:PHImageResultIsInCloudKey] && !result) {
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.networkAccessAllowed = YES;
options.resizeMode = PHImageRequestOptionsResizeModeFast;
[[PHImageManager defaultManager] requestImageDataForAsset:asset options:options resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
UIImage *resultImage = [UIImage imageWithData:imageData];
!completion ? : completion(resultImage);
}];
}
}];
return requestID;
}
@end
//
// GKPhotoView.h
// GKPhotoBrowser
//
// Created by QuintGao on 2017/10/23.
// Copyright © 2017年 QuintGao. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "GKPhotoManager.h"
#import "GKWebImageProtocol.h"
#import "GKLoadingView.h"
NS_ASSUME_NONNULL_BEGIN
@interface GKScrollView : UIScrollView
@end
@class GKPhotoView;
@interface GKPhotoView : UIView<UIScrollViewDelegate>
@property (nonatomic, strong, readonly) GKScrollView *scrollView;
@property (nonatomic, strong, readonly) UIImageView *imageView;
@property (nonatomic, strong, readonly) GKLoadingView *loadingView;
@property (nonatomic, strong, readonly) GKPhoto *photo;
@property (nonatomic, copy) void(^zoomEnded)(GKPhotoView *photoView, CGFloat scale);
@property (nonatomic, copy) void(^loadFailed)(GKPhotoView *photoView);
@property (nonatomic, copy) void(^loadProgressBlock)(GKPhotoView *photoView, float progress, BOOL isOriginImage);
/** 横屏时是否充满屏幕宽度,默认YES,为NO时图片自动填充屏幕 */
@property (nonatomic, assign) BOOL isFullWidthForLandScape;
/** 图片最大放大倍数 */
@property (nonatomic, assign) CGFloat maxZoomScale;
/** 双击放大倍数 */
@property (nonatomic, assign) CGFloat doubleZoomScale;
/** 是否重新布局 */
@property (nonatomic, assign) BOOL isLayoutSubViews;
@property (nonatomic, assign) GKPhotoBrowserLoadStyle loadStyle;
@property (nonatomic, assign) GKPhotoBrowserLoadStyle originLoadStyle;
@property (nonatomic, assign) GKPhotoBrowserFailStyle failStyle;
@property (nonatomic, copy) NSString *failureText;
@property (nonatomic, strong) UIImage *failureImage;
- (instancetype)initWithFrame:(CGRect)frame imageProtocol:(id<GKWebImageProtocol>)imageProtocol;
// 设置数据
- (void)setupPhoto:(GKPhoto *)photo;
// 设置放大倍数
- (void)setScrollMaxZoomScale:(CGFloat)scale;
// 加载原图(必须传originUrl)
- (void)loadOriginImage;
// 缩放
- (void)zoomToRect:(CGRect)rect animated:(BOOL)animated;
// 调整布局
- (void)adjustFrame;
// 重新布局
- (void)resetFrame;
@end
NS_ASSUME_NONNULL_END
//
// GKWebImageProtocol.h
// GKPhotoBrowser
//
// Created by QuintGao on 2017/11/14.
// Copyright © 2017年 QuintGao. All rights reserved.
//
#import "GKPhotoBrowserConfigure.h"
typedef void (^GKWebImageProgressBlock)(NSInteger receivedSize, NSInteger expectedSize);
typedef void (^GKWebImageCompletionBlock)(UIImage * _Nullable image, NSURL * _Nullable url, BOOL finished, NSError * _Nullable error);
@protocol GKWebImageProtocol<NSObject>
/// 设置imageView类
- (Class _Nonnull)imageViewClass;
/// 为imageView设置图片
/// @param imageView imageView
/// @param url 图片url
/// @param placeholderImage 缺省图片
/// @param progressBlock 加载进度
/// @param completionBlock 完成进度
- (void)setImageForImageView:(nullable UIImageView *)imageView
url:(nullable NSURL *)url
placeholderImage:(nullable UIImage *)placeholderImage
progress:(nullable GKWebImageProgressBlock)progressBlock
completion:(nullable GKWebImageCompletionBlock)completionBlock;
/// 取消imageView的图片请求
/// @param imageView imageView
- (void)cancelImageRequestWithImageView:(nullable UIImageView *)imageView;
/// 根据url从内存中获取图片
/// @param url url
- (UIImage *_Nullable)imageFromMemoryForURL:(nullable NSURL *)url;
@optional
/// 可选实现,主要用于加载相册图片资源PHAsset
/// 根据data获取image对象
/// @param data 图片数据
- (UIImage *_Nullable)imageWithData:(nullable NSData *)data;
/// 清理内存
- (void)clearMemory;
@end
//
// UIScrollView+GKPhotoBrowser.h
// GKPhotoBrowser
//
// Created by QuintGao on 2017/11/10.
// Copyright © 2017年 QuintGao. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIScrollView (GKPhotoBrowser)
/**
* 是否启用手势处理功能,默认为NO
* 为了防止与APP中其他UIScrollview滑动的冲突,默认设置为NO,需要时设置为YES即可
*/
@property (nonatomic, assign) BOOL gk_gestureHandleEnabled;
@end
//
// UIScrollView+GKPhotoBrowser.m
// GKPhotoBrowser
//
// Created by QuintGao on 2017/11/10.
// Copyright © 2017年 QuintGao. All rights reserved.
//
#import "UIScrollView+GKPhotoBrowser.h"
#import <objc/runtime.h>
static const void* GKGestureHandleEnabled = @"GKGestureHandleEnabled";
@implementation UIScrollView (GKPhotoBrowser)
- (void)setGk_gestureHandleEnabled:(BOOL)gk_gestureHandleEnabled {
objc_setAssociatedObject(self, GKGestureHandleEnabled, @(gk_gestureHandleEnabled), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)gk_gestureHandleEnabled {
return [objc_getAssociatedObject(self, GKGestureHandleEnabled) boolValue];
}
#pragma mark - 解决全屏滑动
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
if (!self.gk_gestureHandleEnabled) return YES;
if ([self panBack:gestureRecognizer]) return NO;
return YES;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
if (!self.gk_gestureHandleEnabled) return NO;
if ([self panBack:gestureRecognizer]) return YES;
return NO;
}
- (BOOL)panBack:(UIGestureRecognizer *)gestureRecognizer {
if (gestureRecognizer == self.panGestureRecognizer) {
CGPoint point = [self.panGestureRecognizer translationInView:self];
UIGestureRecognizerState state = gestureRecognizer.state;
// 设置手势滑动的位置距屏幕左边的区域
CGFloat locationDistance = [UIScreen mainScreen].bounds.size.width;
if (state == UIGestureRecognizerStateBegan || state == UIGestureRecognizerStatePossible) {
CGPoint location = [gestureRecognizer locationInView:self];
if (point.x > 0 && location.x < locationDistance && self.contentOffset.x <= 0) {
return YES;
}
}
}
return NO;
}
@end
//
// GKYYWebImageManager.h
// GKPhotoBrowserDemo
//
// Created by gaokun on 2020/4/27.
// Copyright © 2020 QuintGao. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "GKWebImageProtocol.h"
NS_ASSUME_NONNULL_BEGIN
@interface GKYYWebImageManager : NSObject<GKWebImageProtocol>
@end
NS_ASSUME_NONNULL_END
//
// GKYYWebImageManager.m
// GKPhotoBrowserDemo
//
// Created by gaokun on 2020/4/27.
// Copyright © 2020 QuintGao. All rights reserved.
//
#import "GKYYWebImageManager.h"
#if __has_include(<YYWebImage/YYWebImage>)
#import <YYWebImage/YYWebImage.h>
#else
#import "YYWebImage.h"
#endif
@implementation GKYYWebImageManager
- (Class)imageViewClass {
return YYAnimatedImageView.class;
}
- (void)setImageForImageView:(UIImageView *)imageView url:(NSURL *)url placeholderImage:(UIImage *)placeholderImage progress:(GKWebImageProgressBlock)progressBlock completion:(GKWebImageCompletionBlock)completionBlock {
[imageView yy_setImageWithURL:url placeholder:placeholderImage options:kNilOptions progress:^(NSInteger receivedSize, NSInteger expectedSize) {
!progressBlock ? : progressBlock(receivedSize, expectedSize);
} transform:nil completion:^(UIImage * _Nullable image, NSURL * _Nonnull url, YYWebImageFromType from, YYWebImageStage stage, NSError * _Nullable error) {
BOOL success = (stage == YYWebImageStageFinished) && !error;
!completionBlock ? : completionBlock(image, url, success, error);
}];
}
- (UIImage *)imageWithData:(NSData *)data {
return [UIImage yy_imageWithSmallGIFData:data scale:UIScreen.mainScreen.scale];
}
- (void)cancelImageRequestWithImageView:(UIImageView *)imageView {
[imageView yy_cancelCurrentImageRequest];
}
- (UIImage *)imageFromMemoryForURL:(NSURL *)url {
YYWebImageManager *manager = [YYWebImageManager sharedManager];
NSString *key = [manager cacheKeyForURL:url];
return [manager.cache getImageForKey:key withType:YYImageCacheTypeAll];
}
- (void)clearMemory {
[[YYImageCache sharedCache].memoryCache removeAllObjects];
}
@end
//
// YYAnimatedImageView+Fix.h
// DreamSleep
//
// Created by peter on 2022/4/29.
//
NS_ASSUME_NONNULL_BEGIN
/// 解决iOS14 YYImage 无法正常显示图片
@interface YYAnimatedImageView (Fix)
@end
NS_ASSUME_NONNULL_END
//
// YYAnimatedImageView+Fix.m
// DreamSleep
//
// Created by peter on 2022/4/29.
//
#import "YYAnimationImageView+Fix.h"
@implementation YYAnimatedImageView (Fix)
+ (void)load {
Method a = class_getInstanceMethod(self, @selector(displayLayer:));
Method b = class_getInstanceMethod(self, @selector(swizzing_displayLayer:));
method_exchangeImplementations(a, b);
}
- (void)swizzing_displayLayer:(CALayer *)layer {
// 通过变量名称获取类中的实例成员变量
Ivar ivar = class_getInstanceVariable(self.class, "_curFrame");
UIImage *_curFrame = object_getIvar(self, ivar);
if (_curFrame) {
layer.contents = (__bridge id)_curFrame.CGImage;
} else {
if (@available(iOS 14.0, *)) {
[super displayLayer:layer];
}
}
}
@end
...@@ -35,9 +35,9 @@ static const CGFloat kLayoutImageScrollViewAnimationDuration = 0.25; ...@@ -35,9 +35,9 @@ static const CGFloat kLayoutImageScrollViewAnimationDuration = 0.25;
// K is a constant such that the accumulated error of our floating-point computations is definitely bounded by K units in the last place. // K is a constant such that the accumulated error of our floating-point computations is definitely bounded by K units in the last place.
#ifdef CGFLOAT_IS_DOUBLE #ifdef CGFLOAT_IS_DOUBLE
static const CGFloat kK = 9; static const CGFloat kK = 9;
#else #else
static const CGFloat kK = 0; static const CGFloat kK = 0;
#endif #endif
@interface RSKImageCropViewController () <UIGestureRecognizerDelegate> @interface RSKImageCropViewController () <UIGestureRecognizerDelegate>
...@@ -137,7 +137,9 @@ static const CGFloat kLayoutImageScrollViewAnimationDuration = 0.25; ...@@ -137,7 +137,9 @@ static const CGFloat kLayoutImageScrollViewAnimationDuration = 0.25;
if ([self respondsToSelector:@selector(edgesForExtendedLayout)]) { if ([self respondsToSelector:@selector(edgesForExtendedLayout)]) {
self.edgesForExtendedLayout = UIRectEdgeNone; self.edgesForExtendedLayout = UIRectEdgeNone;
self.automaticallyAdjustsScrollViewInsets = NO; if (@available(iOS 11.0, *)) {
self.imageScrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
} }
self.view.backgroundColor = [UIColor blackColor]; self.view.backgroundColor = [UIColor blackColor];
...@@ -157,12 +159,6 @@ static const CGFloat kLayoutImageScrollViewAnimationDuration = 0.25; ...@@ -157,12 +159,6 @@ static const CGFloat kLayoutImageScrollViewAnimationDuration = 0.25;
{ {
[super viewWillAppear:animated]; [super viewWillAppear:animated];
UIApplication *application = [UIApplication rsk_sharedApplication];
if (application) {
self.originalStatusBarHidden = application.statusBarHidden;
[application setStatusBarHidden:YES];
}
self.originalNavigationControllerNavigationBarHidden = self.navigationController.navigationBarHidden; self.originalNavigationControllerNavigationBarHidden = self.navigationController.navigationBarHidden;
[self.navigationController setNavigationBarHidden:YES animated:NO]; [self.navigationController setNavigationBarHidden:YES animated:NO];
...@@ -181,12 +177,7 @@ static const CGFloat kLayoutImageScrollViewAnimationDuration = 0.25; ...@@ -181,12 +177,7 @@ static const CGFloat kLayoutImageScrollViewAnimationDuration = 0.25;
- (void)viewWillDisappear:(BOOL)animated - (void)viewWillDisappear:(BOOL)animated
{ {
[super viewWillDisappear:animated]; [super viewWillDisappear:animated];
UIApplication *application = [UIApplication rsk_sharedApplication];
if (application) {
[application setStatusBarHidden:self.originalStatusBarHidden];
}
[self.navigationController setNavigationBarHidden:self.originalNavigationControllerNavigationBarHidden animated:animated]; [self.navigationController setNavigationBarHidden:self.originalNavigationControllerNavigationBarHidden animated:animated];
self.navigationController.navigationBar.shadowImage = self.originalNavigationControllerNavigationBarShadowImage; self.navigationController.navigationBar.shadowImage = self.originalNavigationControllerNavigationBarShadowImage;
self.navigationController.view.backgroundColor = self.originalNavigationControllerViewBackgroundColor; self.navigationController.view.backgroundColor = self.originalNavigationControllerViewBackgroundColor;
...@@ -561,8 +552,8 @@ static const CGFloat kLayoutImageScrollViewAnimationDuration = 0.25; ...@@ -561,8 +552,8 @@ static const CGFloat kLayoutImageScrollViewAnimationDuration = 0.25;
delay:0.0 delay:0.0
options:UIViewAnimationOptionBeginFromCurrentState options:UIViewAnimationOptionBeginFromCurrentState
animations:^{ animations:^{
[self layoutImageScrollView]; [self layoutImageScrollView];
} }
completion:nil]; completion:nil];
} }
} }
......
...@@ -188,11 +188,11 @@ static CGFloat itemMargin = 5; ...@@ -188,11 +188,11 @@ static CGFloat itemMargin = 5;
- (void)configBottomToolBar { - (void)configBottomToolBar {
TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController; TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
if (!tzImagePickerVc.showSelectBtn) return; if (!tzImagePickerVc.showSelectBtn) return;
_bottomToolBar = [[UIView alloc] initWithFrame:CGRectZero]; _bottomToolBar = [[UIView alloc] initWithFrame:CGRectZero];
CGFloat rgb = 253 / 255.0; CGFloat rgb = 253 / 255.0;
_bottomToolBar.backgroundColor = [UIColor colorWithRed:rgb green:rgb blue:rgb alpha:1.0]; _bottomToolBar.backgroundColor = [UIColor colorWithRed:rgb green:rgb blue:rgb alpha:1.0];
_previewButton = [UIButton buttonWithType:UIButtonTypeCustom]; _previewButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_previewButton addTarget:self action:@selector(previewButtonClick) forControlEvents:UIControlEventTouchUpInside]; [_previewButton addTarget:self action:@selector(previewButtonClick) forControlEvents:UIControlEventTouchUpInside];
_previewButton.titleLabel.font = [UIFont systemFontOfSize:16]; _previewButton.titleLabel.font = [UIFont systemFontOfSize:16];
...@@ -266,7 +266,7 @@ static CGFloat itemMargin = 5; ...@@ -266,7 +266,7 @@ static CGFloat itemMargin = 5;
- (void)viewDidLayoutSubviews { - (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews]; [super viewDidLayoutSubviews];
TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController; TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
CGFloat top = 0; CGFloat top = 0;
...@@ -614,13 +614,13 @@ static CGFloat itemMargin = 5; ...@@ -614,13 +614,13 @@ static CGFloat itemMargin = 5;
if (!appName) appName = [infoDict valueForKey:@"CFBundleName"]; if (!appName) appName = [infoDict valueForKey:@"CFBundleName"];
NSString *message = [NSString stringWithFormat:[NSBundle tz_localizedStringForKey:@"Please allow %@ to access your camera in \"Settings -> Privacy -> Camera\""],appName]; NSString *message = [NSString stringWithFormat:[NSBundle tz_localizedStringForKey:@"Please allow %@ to access your camera in \"Settings -> Privacy -> Camera\""],appName];
if (iOS8Later) { UIAlertController *alertController = [UIAlertController alertControllerWithTitle:[NSBundle tz_localizedStringForKey:@"Can not use camera"] message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[NSBundle tz_localizedStringForKey:@"Can not use camera"] message:message delegate:self cancelButtonTitle:[NSBundle tz_localizedStringForKey:@"Cancel"] otherButtonTitles:[NSBundle tz_localizedStringForKey:@"Setting"], nil]; [alertController addAction:[UIAlertAction actionWithTitle:[NSBundle tz_localizedStringForKey:@"Cancel"] style:UIAlertActionStyleCancel handler:nil]];
[alert show]; [alertController addAction:[UIAlertAction actionWithTitle:[NSBundle tz_localizedStringForKey:@"Setting"] style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
} else { // 去设置界面
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[NSBundle tz_localizedStringForKey:@"Can not use camera"] message:message delegate:self cancelButtonTitle:[NSBundle tz_localizedStringForKey:@"OK"] otherButtonTitles:nil]; [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
[alert show]; }]];
} [self presentViewController:alertController animated:YES completion:nil];
} else if (authStatus == AVAuthorizationStatusNotDetermined) { } else if (authStatus == AVAuthorizationStatusNotDetermined) {
// fix issue 466, 防止用户首次拍照拒绝授权时相机页黑屏 // fix issue 466, 防止用户首次拍照拒绝授权时相机页黑屏
if (iOS7Later) { if (iOS7Later) {
...@@ -755,16 +755,6 @@ static CGFloat itemMargin = 5; ...@@ -755,16 +755,6 @@ static CGFloat itemMargin = 5;
} }
} }
#pragma mark - UIAlertViewDelegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 1) { // 去设置界面,开启相机访问权限
if (iOS8Later) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
}
}
}
#pragma mark - UIImagePickerControllerDelegate #pragma mark - UIImagePickerControllerDelegate
- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { - (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
......
...@@ -389,7 +389,7 @@ ...@@ -389,7 +389,7 @@
CMTime currentTime = _player.currentItem.currentTime; CMTime currentTime = _player.currentItem.currentTime;
CMTime durationTime = _player.currentItem.duration; CMTime durationTime = _player.currentItem.duration;
if (_player.rate == 0.0f) { if (_player.rate == 0.0f) {
if (currentTime.value == durationTime.value) [_player.currentItem seekToTime:CMTimeMake(0, 1)]; if (currentTime.value == durationTime.value) [_player.currentItem seekToTime:CMTimeMake(0, 1) completionHandler:nil];
[_player play]; [_player play];
[_playButton setImage:nil forState:UIControlStateNormal]; [_playButton setImage:nil forState:UIControlStateNormal];
if (iOS7Later) [UIApplication sharedApplication].statusBarHidden = YES; if (iOS7Later) [UIApplication sharedApplication].statusBarHidden = YES;
......
...@@ -25,3 +25,4 @@ end ...@@ -25,3 +25,4 @@ end
# YYWebImage (1.0.5) # YYWebImage (1.0.5)
# YYImage/WebP(模拟器上目前无法运行) # YYImage/WebP(模拟器上目前无法运行)
# YYModel (1.0.4) # YYModel (1.0.4)
# SDWebImage (5.12.5)(去掉)
...@@ -78,6 +78,6 @@ SPEC CHECKSUMS: ...@@ -78,6 +78,6 @@ SPEC CHECKSUMS:
YYModel: 2a7fdd96aaa4b86a824e26d0c517de8928c04b30 YYModel: 2a7fdd96aaa4b86a824e26d0c517de8928c04b30
YYWebImage: 5f7f36aee2ae293f016d418c7d6ba05c4863e928 YYWebImage: 5f7f36aee2ae293f016d418c7d6ba05c4863e928
PODFILE CHECKSUM: b3d9e0300e1732ba6a625a3cac34c1a05fcefc19 PODFILE CHECKSUM: 5f273d0f03f58db41d7f0a6d3d96a8bd054ab744
COCOAPODS: 1.11.3 COCOAPODS: 1.11.3
...@@ -78,6 +78,6 @@ SPEC CHECKSUMS: ...@@ -78,6 +78,6 @@ SPEC CHECKSUMS:
YYModel: 2a7fdd96aaa4b86a824e26d0c517de8928c04b30 YYModel: 2a7fdd96aaa4b86a824e26d0c517de8928c04b30
YYWebImage: 5f7f36aee2ae293f016d418c7d6ba05c4863e928 YYWebImage: 5f7f36aee2ae293f016d418c7d6ba05c4863e928
PODFILE CHECKSUM: b3d9e0300e1732ba6a625a3cac34c1a05fcefc19 PODFILE CHECKSUM: 5f273d0f03f58db41d7f0a6d3d96a8bd054ab744
COCOAPODS: 1.11.3 COCOAPODS: 1.11.3
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!