Commit b7a3c78e authored by 谢俊毅's avatar 谢俊毅
Browse files

init

Showing with 2255 additions and 0 deletions
+2255 -0
//
// BMAppConfigModule.h
// BM-JYT
//
// Created by XHY on 2017/3/13.
// Copyright © 2017年 XHY. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <WeexSDK.h>
@interface BMAppConfigModule : NSObject <WXModuleProtocol>
@end
//
// BMAppConfigModule.m
// BM-JYT
//
// Created by XHY on 2017/3/13.
// Copyright © 2017年 XHY. All rights reserved.
//
#import "BMAppConfigModule.h"
@implementation BMAppConfigModule
@synthesize weexInstance;
WX_EXPORT_METHOD(@selector(changeFontSize:callback:))
WX_EXPORT_METHOD(@selector(getFontSize:))
- (void)changeFontSize:(NSDictionary *)info callback:(WXModuleCallback)callback
{
NSString *fontSize = info[@"fontSize"];
NSString *scale = @"1";
if (!fontSize || [fontSize isEqualToString:@"NORM"]) {
[self _changeFontSizeWithSize:K_FONT_SIZE_NORM];
} else if ([fontSize isEqualToString:@"BIG"]) {
[self _changeFontSizeWithSize:K_FONT_SIZE_BIG];
scale = [NSString stringWithFormat:@"%f",K_FontSizeBig_Scale];
} else if ([fontSize isEqualToString:@"EXTRALARGE"]) {
[self _changeFontSizeWithSize:k_FONT_SIZE_EXTRALARGE];
scale = [NSString stringWithFormat:@"%f",K_FontSizeExtralarge_Scale];
} else {
WXLogError(@"fontSize 字段错误 %@",info[@"fontSize"]);
}
if (callback) {
NSDictionary *data = @{@"fontSize": fontSize, @"scale": scale};
NSDictionary *resultDic = [NSDictionary configCallbackDataWithResCode:BMResCodeSuccess msg:nil data:data];
callback(resultDic);
}
}
- (void)getFontSize:(WXModuleCallback)callback
{
NSString *currentFontSize = [[NSUserDefaults standardUserDefaults] valueForKey:K_FONT_SIZE_KEY];
NSString *fontSize = @"NORM";
NSString *scale = @"1";
if ([currentFontSize isEqualToString:K_FONT_SIZE_BIG]) {
fontSize = @"BIG";
scale = [NSString stringWithFormat:@"%f",K_FontSizeBig_Scale];
} else if ([currentFontSize isEqualToString:k_FONT_SIZE_EXTRALARGE]) {
fontSize = @"EXTRALARGE";
scale = [NSString stringWithFormat:@"%f",K_FontSizeExtralarge_Scale];
}
NSDictionary *data = @{@"fontSize": fontSize, @"scale": scale};
NSDictionary *resultDic = [NSDictionary configCallbackDataWithResCode:BMResCodeSuccess msg:nil data:data];
if (callback) {
callback(resultDic);
}
}
- (void)_changeFontSizeWithSize:(NSString *)size
{
[[NSUserDefaults standardUserDefaults] setValue:size forKey:K_FONT_SIZE_KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
[[NSNotificationCenter defaultCenter] postNotificationName:K_CHANGE_FONT_SIZE_NOTIFICATION object:nil];
}
@end
//
// BMAuthorLoginModule.h
// Pods
//
// Created by XHY on 2017/5/5.
//
//
#import <Foundation/Foundation.h>
#import <WeexSDK.h>
@interface BMAuthorLoginModule : NSObject <WXModuleProtocol>
@end
//
// BMAuthorLoginModule.m
// Pods
//
// Created by XHY on 2017/5/5.
//
//
#import "BMAuthorLoginModule.h"
#import <LocalAuthentication/LocalAuthentication.h>
@interface BMAuthorLoginModule()
@end
@implementation BMAuthorLoginModule
@synthesize weexInstance;
WX_EXPORT_METHOD_SYNC(@selector(canUseTouchId))
WX_EXPORT_METHOD(@selector(touchId:callback:))
- (NSDictionary *)canUseTouchId
{
LAContext *context = [[LAContext alloc] init];
NSError *error = nil;
BMResCode code = BMResCodeSuccess;
NSString *msg = @"此设备支持使用 Touch ID";
if (![context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) {
code = BMResCodeError;
//不支持指纹识别
switch (error.code) {
case LAErrorTouchIDNotEnrolled:
{
msg = @"TouchID is not enrolled";
break;
}
case LAErrorPasscodeNotSet:
{
msg = @"A passcode has not been set";
break;
}
default:
{
msg = @"TouchID not available";
break;
}
}
}
WXLogInfo(@"%@",msg);
return [NSDictionary configCallbackDataWithResCode:code msg:msg data:nil];
}
- (void)touchId:(NSDictionary *)info callback:(WXModuleCallback)callback
{
NSDictionary *resData = [self canUseTouchId];
if ([[resData objectForKey:@"resData"] integerValue] == 9) {
if (callback) {
callback(resData);
}
return;
}
LAContext *context = [[LAContext alloc] init];
NSError *error = nil;
NSString *title = [info objectForKey:@"title"];
[context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason: title?:@"指纹解锁" reply:^(BOOL success, NSError * _Nullable error) {
if (success) {
if (callback) {
NSDictionary *resData = [NSDictionary configCallbackDataWithResCode:BMResCodeSuccess msg:@"指纹验证成功" data:nil];
callback(resData);
}
}else{
NSString *msg = @"";
switch (error.code) {
case LAErrorSystemCancel:
{
msg = @"系统取消授权";
break;
}
case LAErrorUserCancel:
{
msg = @"用户取消验证";
break;
}
case LAErrorAuthenticationFailed:
{
msg = @"授权失败";
break;
}
case LAErrorPasscodeNotSet:
{
msg = @"系统未设置密码";
break;
}
default:
{
msg = @"设备Touch ID不可用";
break;
}
}
if (callback) {
NSDictionary *resData = [NSDictionary configCallbackDataWithResCode:BMResCodeError msg:msg data:nil];
callback(resData);
}
}
}];
}
@end
//
// BMAxiosNetworkModule.h
// WeexDemo
//
// Created by XHY on 2017/1/13.
// Copyright © 2017年 taobao. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <WeexSDK.h>
@interface BMAxiosNetworkModule : NSObject <WXModuleProtocol>
@end
//
// BMAxiosNetworkModule.m
// WeexDemo
//
// Created by XHY on 2017/1/13.
// Copyright © 2017年 taobao. All rights reserved.
//
#import "BMAxiosNetworkModule.h"
#import "BMAxiosRequestModel.h"
#import "BMCommonRequest.h"
#import "BMBaseViewController.h"
#import "BMUserInfoModel.h"
#import "BMImageManager.h"
@implementation BMAxiosNetworkModule
@synthesize weexInstance;
WX_EXPORT_METHOD(@selector(fetch:callback:))
WX_EXPORT_METHOD(@selector(uploadImage::))
- (void)fetch:(NSDictionary *)info callback:(WXModuleCallback)callback
{
/* 添加判断 */
if (![info isKindOfClass:[NSDictionary class]]) {
WXLogError(@"js request info Error");
return;
}
WXLogInfo(@"js request info: %@",info);
BMAxiosRequestModel *requestModel = [BMAxiosRequestModel yy_modelWithJSON:info];
BMCommonRequest *api = [[BMCommonRequest alloc] initWithRequestModel:requestModel];
[((BMBaseViewController *)weexInstance.viewController) addRequest:api];
[api startRequestResult:^(id data) {
WXLogInfo(@"request data: %@",data);
if (callback) {
callback(data);
}
}];
WXLogInfo(@"%@",api.originalRequest);
}
- (void)uploadImage:(NSDictionary *)info :(WXModuleCallback)callback
{
BMUploadImageModel *model = [BMUploadImageModel yy_modelWithJSON:info];
NSArray *images = info[@"images"];
if (!images || !images.count) {
if (callback) {
NSDictionary *resData = [NSDictionary configCallbackDataWithResCode:BMResCodeError msg:@"上传图片参数错误" data:nil];
callback(resData);
}
return;
}
[BMImageManager uploadImage:images uploadImageModel:model callback:callback];
}
@end
//
// BMAxiosRequestModel.h
// WeexDemo
//
// Created by XHY on 2017/1/13.
// Copyright © 2017年 taobao. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "YYModel.h"
@interface BMAxiosRequestModel : NSObject
@property (nonatomic, copy) NSString *method; // 请求类型 GET or POST
@property (nonatomic, copy) NSString *url; // 请求路径
@property (nonatomic, strong) NSDictionary *header; // 请求头
@property (nonatomic, strong) NSMutableDictionary *data; // 请求参数
@property (nonatomic, strong) NSDictionary *params; // post 请求 url 添加参数
@property (nonatomic, assign) CGFloat timeout; // 请求超时时间
@end
//
// BMAxiosRequestModel.m
// WeexDemo
//
// Created by XHY on 2017/1/13.
// Copyright © 2017年 taobao. All rights reserved.
//
#import "BMAxiosRequestModel.h"
@implementation BMAxiosRequestModel
@end
//
// BMBrowserImgModule.h
// BM-JYT
//
// Created by 窦静轩 on 2017/4/1.
// Copyright © 2017年 XHY. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <WeexSDK.h>
@interface BMBrowserImgModule : NSObject<WXModuleProtocol>
@end
//
// BMBrowserImgModule.m
// BM-JYT
//
// Created by 窦静轩 on 2017/4/1.
// Copyright © 2017年 XHY. All rights reserved.
//
#import "BMBrowserImgModule.h"
#import <SDWebImage/SDImageCache.h>
#import "PBViewController.h"
#import <objc/runtime.h>
#import <SDWebImage/UIImageView+WebCache.h>
static NSString * indexKey = @"index";
static NSString * imagesKey = @"images";
static NSString * typeKey = @"type";
static NSString * localKey = @"local";
static NSString * networkKey = @"network";
@interface BMBrowserImgModule()<PBViewControllerDelegate,PBViewControllerDataSource>
{
PBViewController * _photoBrowser;
}
@property (nonatomic,strong)NSMutableArray * images;
@end
@implementation BMBrowserImgModule
@synthesize weexInstance;
WX_EXPORT_METHOD(@selector(open:callback:))
WX_EXPORT_METHOD(@selector(close))
-(void)open:(NSDictionary*)info callback:(WXModuleCallback)callback
{
if ([info isKindOfClass:[NSDictionary class]]) {
NSArray * images = [(NSDictionary*)info objectForKey:imagesKey];
NSNumber * index = [(NSDictionary*)info objectForKey:indexKey];
NSString * type = [(NSDictionary*)info objectForKey:typeKey];
NSMutableArray * imagsArray = [[NSMutableArray alloc] initWithCapacity:0];
BOOL isLocal = NO;
if ([images isKindOfClass:[NSArray class]]) {
for (int i = 0; i < images.count; i++) {
NSString * url = [images objectAtIndex:i];
if ([type isEqualToString:localKey]) {
isLocal = YES;
UIImage * image = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:[url md5]];
if (nil != image) {
[imagsArray addObject:image];
}
}
if ([type isEqualToString:networkKey]) {
isLocal = NO;
if (nil != url) {
[imagsArray addObject:url];
}
}
}
if (nil != self.images) {
[self.images removeAllObjects];
self.images = nil;
}
self.images = [[NSMutableArray alloc] initWithArray:imagsArray];
if (nil != _photoBrowser) {
_photoBrowser = nil;
}
_photoBrowser = [PBViewController new];
_photoBrowser.pb_dataSource = self;
_photoBrowser.pb_delegate = self;
_photoBrowser.pb_startPage = [index integerValue];
[weexInstance.viewController presentViewController:_photoBrowser animated:YES completion:^{
if (callback) {
callback([NSDictionary dictionary]);
}
}];
}
}
}
-(void)close
{
if (_photoBrowser) {
dispatch_async(dispatch_get_main_queue(), ^{
[_photoBrowser dismissViewControllerAnimated:YES completion:nil];
});
}
}
#pragma mark - PBViewControllerDataSource
- (NSInteger)numberOfPagesInViewController:(PBViewController *)viewController {
return self.images.count;
}
- (void)viewController:(PBViewController *)viewController presentImageView:(UIImageView *)imageView forPageAtIndex:(NSInteger)index progressHandler:(void (^)(NSInteger, NSInteger))progressHandler {
NSString *url = self.images[index]?:@"";
UIImage *placeholder = nil;
[imageView sd_setImageWithURL:[NSURL URLWithString:url] placeholderImage:placeholder options:SDWebImageRetryFailed progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {
if (progressHandler)
{
progressHandler(receivedSize,expectedSize);
}
} completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
}];
}
- (UIView *)thumbViewForPageAtIndex:(NSInteger)index {
return nil;
}
#pragma mark - PBViewControllerDelegate
- (void)viewController:(PBViewController *)viewController didSingleTapedPageAtIndex:(NSInteger)index presentedImage:(UIImage *)presentedImage {
[_photoBrowser dismissViewControllerAnimated:YES completion:nil];
}
- (void)viewController:(PBViewController *)viewController didLongPressedPageAtIndex:(NSInteger)index presentedImage:(UIImage *)presentedImage {
NSLog(@"didLongPressedPageAtIndex: %@", @(index));
}
@end
//
// PBImageScrollView+internal.h
// PhotoBrowser
//
// Created by Moch Xiao on 5/13/16.
// Copyright © 2016 Moch Xiao (http://mochxiao.com).
//
// 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.
//
#ifndef PBImageScrollView_internal_h
#define PBImageScrollView_internal_h
#ifndef NSLog
#if DEBUG
#define NSLog(FORMAT, ...) \
do { \
fprintf(stderr,"<%s> %s %s [%d] %s\n", \
(NSThread.isMainThread ? "UI" : "BG"), \
(sel_getName(_cmd)),\
[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], \
__LINE__, \
[[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]); \
} while(0)
#else
#define NSLog(FORMAT, ...)
#endif
#endif
#import "PBImageScrollView.h"
@interface PBImageScrollView()
- (void)_handleZoomForLocation:(CGPoint)location;
- (void)_scrollToTopAnimated:(BOOL)animated;
/// Scrolling content offset'y percent.
@property (nonatomic, copy) void(^contentOffSetVerticalPercentHandler)(CGFloat);
/// loosen hand with decelerate
/// velocity: > 0 up, < 0 dwon, == 0 others(no swipe, e.g. tap).
@property (nonatomic, copy) void(^didEndDraggingInProperpositionHandler)(CGFloat velocity);
@end
#endif /* PBImageScrollView_internal_h */
//
// PBImageScrollView.h
// PhotoBrowser
//
// Created by Moch Xiao on 5/12/16.
// Copyright © 2016 Moch Xiao (http://mochxiao.com).
//
// 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.
//
#import <UIKit/UIKit.h>
@interface PBImageScrollView : UIScrollView <UIScrollViewDelegate>
@property (nonatomic, strong, readonly) UIImageView *imageView;
@end
//
// PBImageScrollView.m
// PhotoBrowser
//
// Created by Moch Xiao on 5/12/16.
// Copyright © 2016 Moch Xiao (http://mochxiao.com).
//
// 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.
//
#import "PBImageScrollView.h"
#import "PBImageScrollView+internal.h"
#define system_version ([UIDevice currentDevice].systemVersion.doubleValue)
#define observe_keypath_image @"image"
@interface PBImageScrollView ()
@property (nonatomic, strong, readwrite) UIImageView *imageView;
@property (nonatomic, weak) id <NSObject> notification;
/// velocity: > 0 up, < 0 dwon, == 0 others(no swipe, e.g. tap).
@property (nonatomic, assign) CGFloat velocity;
@property (nonatomic, assign) BOOL dismissing;
@end
@implementation PBImageScrollView
- (void)dealloc {
[self _removeObserver];
[self _removeNotificationIfNeeded];
NSLog(@"~~~~~~~~~~~%s~~~~~~~~~~~", __FUNCTION__);
}
#pragma mark - respondsToSelector
- (instancetype)init {
self = [super init];
if (!self) {
return nil;
}
self.frame = [UIScreen mainScreen].bounds;
self.multipleTouchEnabled = YES;
self.showsVerticalScrollIndicator = YES;
self.showsHorizontalScrollIndicator = YES;
self.alwaysBounceVertical = NO;
self.minimumZoomScale = 1.0f;
self.maximumZoomScale = 1.0f;
self.delegate = self;
[self addSubview:self.imageView];
[self _addObserver];
[self _addNotificationIfNeeded];
return self;
}
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
[super traitCollectionDidChange:previousTraitCollection];
[self _updateFrame];
[self _recenterImage];
}
- (void)didMoveToWindow {
[super didMoveToWindow];
if (!self.window) {
[self _updateUserInterfaces];
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
if (![keyPath isEqualToString:observe_keypath_image]) {
return;
}
if (![object isEqual:self.imageView]) {
return;
}
if (!self.imageView.image) {
return;
}
[self _updateUserInterfaces];
}
#pragma mark - Internal Methods
- (void)_handleZoomForLocation:(CGPoint)location {
CGPoint touchPoint = [self.superview convertPoint:location toView:self.imageView];
if (self.zoomScale > 1) {
[self setZoomScale:1 animated:YES];
} else if (self.maximumZoomScale > 1) {
CGFloat newZoomScale = self.maximumZoomScale;
CGFloat horizontalSize = CGRectGetWidth(self.bounds) / newZoomScale;
CGFloat verticalSize = CGRectGetHeight(self.bounds) / newZoomScale;
[self zoomToRect:CGRectMake(touchPoint.x - horizontalSize / 2.0f, touchPoint.y - verticalSize / 2.0f, horizontalSize, verticalSize) animated:YES];
}
}
- (void)_scrollToTopAnimated:(BOOL)animated {
CGPoint offset = self.contentOffset;
offset.y = -self.contentInset.top;
[self setContentOffset:offset animated:animated];
}
#pragma mark - Private methods
- (void)_addObserver {
[self.imageView addObserver:self forKeyPath:observe_keypath_image options:NSKeyValueObservingOptionNew context:nil];
}
- (void)_removeObserver {
[self.imageView removeObserver:self forKeyPath:observe_keypath_image];
}
- (void)_addNotificationIfNeeded {
if (system_version >= 8.0) {
return;
}
__weak typeof(self) weak_self = self;
self.notification = [[NSNotificationCenter defaultCenter] addObserverForName:UIDeviceOrientationDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
__strong typeof(weak_self) strong_self = weak_self;
[strong_self _updateFrame];
[strong_self _recenterImage];
}];
}
- (void)_removeNotificationIfNeeded {
if (system_version >= 8.0) {
return;
}
[[NSNotificationCenter defaultCenter] removeObserver:self.notification];
}
- (void)_updateUserInterfaces {
[self setZoomScale:1.0f animated:YES];
[self _updateFrame];
[self _recenterImage];
[self _setMaximumZoomScale];
self.alwaysBounceVertical = YES;
}
- (void)_updateFrame {
self.frame = [UIScreen mainScreen].bounds;
UIImage *image = self.imageView.image;
if (!image) {
return;
}
CGSize properSize = [self _properPresentSizeForImage:image];
self.imageView.frame = CGRectMake(0, 0, properSize.width, properSize.height);
self.contentSize = properSize;
}
- (CGSize)_properPresentSizeForImage:(UIImage *)image {
CGFloat ratio = CGRectGetWidth(self.bounds) / image.size.width;
return CGSizeMake(CGRectGetWidth(self.bounds), ceil(ratio * image.size.height));
}
- (void)_recenterImage {
CGFloat contentWidth = self.contentSize.width;
CGFloat horizontalDiff = CGRectGetWidth(self.bounds) - contentWidth;
CGFloat horizontalAddition = horizontalDiff > 0.f ? horizontalDiff : 0.f;
CGFloat contentHeight = self.contentSize.height;
CGFloat verticalDiff = CGRectGetHeight(self.bounds) - contentHeight;
CGFloat verticalAdditon = verticalDiff > 0 ? verticalDiff : 0.f;
self.imageView.center = CGPointMake((contentWidth + horizontalAddition) / 2.0f, (contentHeight + verticalAdditon) / 2.0f);
}
- (void)_setMaximumZoomScale {
CGSize imageSize = self.imageView.image.size;
CGFloat selfWidth = CGRectGetWidth(self.bounds);
CGFloat selfHeight = CGRectGetHeight(self.bounds);
if (imageSize.width <= selfWidth && imageSize.height <= selfHeight) {
self.maximumZoomScale = 2.0f;
} else {
self.maximumZoomScale = MAX(MIN(imageSize.width / selfWidth, imageSize.height / selfHeight), 3.0f);
}
}
/// Only + percent.
- (CGFloat)_contentOffSetVerticalPercent {
return fabs([self _rawContentOffSetVerticalPercent]);
}
/// +/- percent.
- (CGFloat)_rawContentOffSetVerticalPercent {
CGFloat percent = 0;
CGFloat contentHeight = self.contentSize.height;
CGFloat scrollViewHeight = CGRectGetHeight(self.bounds);
CGFloat offsetY = self.contentOffset.y;
CGFloat factor = 1.3;
if (offsetY < 0) {
percent = MIN(offsetY / (scrollViewHeight * factor), 1.0f);
} else {
if (contentHeight < scrollViewHeight) {
percent = MIN(offsetY / (scrollViewHeight * factor), 1.0f);
} else {
offsetY += scrollViewHeight;
CGFloat contentHeight = self.contentSize.height;
if (offsetY > contentHeight) {
percent = MIN((offsetY - contentHeight) / (scrollViewHeight * factor), 1.0f);
}
}
}
return percent;
}
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (self.dismissing) {
return;
}
if (!self.contentOffSetVerticalPercentHandler) {
return;
}
self.contentOffSetVerticalPercentHandler([self _contentOffSetVerticalPercent]);
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
[self _recenterImage];
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
if (!decelerate) {
return;
}
// 停止时有加速度不够取消操作
// 如果距离够,不取消
CGFloat rawPercent = [self _rawContentOffSetVerticalPercent];
CGFloat velocity = self.velocity;
if (fabs(rawPercent) <= 0) {
return;
}
NSLog(@"rawPercent: %@", @(rawPercent));
NSLog(@"velocity: %@", @(velocity));
if (fabs(rawPercent) < 0.15f && fabs(velocity) < 1) {
return;
}
// 停止时有相反方向滑动操作时取消退出操作
if (rawPercent * velocity < 0) {
return;
}
// 如果是长图,并且是向上滑动,需要滑到底部以下才能结束
if (self.contentSize.height > CGRectGetHeight(self.bounds)) {
if (velocity > 0) {
// 向上滑动
// 速度过快且滑过区域较小,防止误操作,取消
if (velocity > 2.8 && rawPercent < 0.1) {
return;
}
if (self.contentOffset.y + CGRectGetHeight(self.bounds) <= self.contentSize.height) {
return;
}
} else {
// 向下滑动
// 速度过快,防止误操作,取消
if (fabs(velocity) > 2.8) {
return;
}
if (self.contentOffset.y > 0) {
return;
}
}
}
if (self.didEndDraggingInProperpositionHandler) {
// 取消回弹效果,所以计算 imageView 的 frame 的时候需要注意 contentInset.
scrollView.bounces = NO;
scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
self.didEndDraggingInProperpositionHandler(self.velocity);
self.dismissing = YES;
}
}
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
self.velocity = velocity.y;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
if (self.dismissing) {
return;
}
if (scrollView.zoomScale < 1) {
[scrollView setZoomScale:1.0f animated:YES];
}
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return self.imageView;
}
#pragma mark - Accessor
- (UIImageView *)imageView {
if (!_imageView) {
_imageView = [UIImageView new];
_imageView.contentMode = UIViewContentModeScaleAspectFill;
_imageView.clipsToBounds = YES;
}
return _imageView;
}
@end
//
// PBImageScrollerViewController.h
// PhotoBrowser
//
// Created by Moch Xiao on 8/24/15.
// Copyright (c) 2015 Moch Xiao (https://github.com/cuzv).
//
// 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.
//
#import <UIKit/UIKit.h>
@class PBImageScrollView;
typedef void(^PBImageDownloadProgressHandler)(NSInteger receivedSize, NSInteger expectedSize);
@interface PBImageScrollerViewController : UIViewController
@property (nonatomic, assign) NSInteger page;
/// Return the image for current imageView
@property (nonatomic, copy) UIImage *(^fetchImageHandler)(void);
/// Configure image for current imageView
@property (nonatomic, copy) void (^configureImageViewHandler)(UIImageView *imageView);
/// Configure image for current imageView with progress
@property (nonatomic, copy) void (^configureImageViewWithDownloadProgressHandler)(UIImageView *imageView, PBImageDownloadProgressHandler handler);
@property (nonatomic, strong, readonly) PBImageScrollView *imageScrollView;
- (void)reloadData;
@end
//
// PBImageScrollerViewController.m
// PhotoBrowser
//
// Created by Moch Xiao on 8/24/15.
// Copyright (c) 2015 Moch Xiao (https://github.com/cuzv).
//
// 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.
//
#import "PBImageScrollerViewController.h"
#import "PBImageScrollView.h"
#import "PBImageScrollView+internal.h"
@interface PBImageScrollerViewController ()
@property (nonatomic, strong, readwrite) PBImageScrollView *imageScrollView;
@property (nonatomic, weak, readwrite) UIImageView *imageView;
@property (nonatomic, strong, readwrite) CAShapeLayer *progressLayer;
@property (nonatomic, assign) BOOL dismissing;
@end
@implementation PBImageScrollerViewController
- (void)dealloc {
NSLog(@"~~~~~~~~~~~%s~~~~~~~~~~~", __FUNCTION__);
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.imageScrollView];
[self.view.layer addSublayer:self.progressLayer];
}
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
CGPoint center = CGPointMake(CGRectGetWidth(self.view.bounds) / 2.0, CGRectGetHeight(self.view.bounds) / 2.0);
CGRect frame = self.progressLayer.frame;
frame.origin.x = center.x - CGRectGetWidth(frame) / 2.0f;
frame.origin.y = center.y - CGRectGetHeight(frame) / 2.0f;
self.progressLayer.frame = frame;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self reloadData];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
// 干掉加载动画。
self.progressLayer.hidden = YES;
self.dismissing = YES;
}
- (void)reloadData {
[self _prepareForReuse];
[self _loadData];
}
#pragma mark - Private methods
- (void)_prepareForReuse {
self.imageView.image = nil;
self.progressLayer.hidden = YES;
self.progressLayer.strokeStart = 0;
self.progressLayer.strokeEnd = 0;
self.dismissing = NO;
}
- (void)_loadData {
if (self.fetchImageHandler) {
self.imageView.image = self.fetchImageHandler();
} else if (self.configureImageViewWithDownloadProgressHandler) {
__weak typeof(self) weak_self = self;
self.configureImageViewWithDownloadProgressHandler(self.imageView, ^(NSInteger receivedSize, NSInteger expectedSize) {
__strong typeof(weak_self) strong_self = weak_self;
if (strong_self.dismissing || !strong_self.view.window) {
strong_self.progressLayer.hidden = YES;
return;
}
CGFloat progress = (receivedSize * 1.0f) / (expectedSize * 1.0f);
if (0.0f >= progress || progress >= 1.0f) {
strong_self.progressLayer.hidden = YES;
return;
}
strong_self.progressLayer.hidden = NO;
strong_self.progressLayer.strokeEnd = progress;
});
} else if (self.configureImageViewHandler) {
self.configureImageViewHandler(self.imageView);
}
}
#pragma mark - Accessor
- (PBImageScrollView *)imageScrollView {
if (!_imageScrollView) {
_imageScrollView = [PBImageScrollView new];
}
return _imageScrollView;
}
- (UIImageView *)imageView {
return self.imageScrollView.imageView;
}
- (CAShapeLayer *)progressLayer {
if (!_progressLayer) {
_progressLayer = [CAShapeLayer layer];
_progressLayer.frame = CGRectMake(0, 0, 40, 40);
_progressLayer.cornerRadius = MIN(CGRectGetWidth(_progressLayer.bounds) / 2.0f, CGRectGetHeight(_progressLayer.bounds) / 2.0f);
_progressLayer.lineWidth = 4;
_progressLayer.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5].CGColor;
_progressLayer.fillColor = [UIColor clearColor].CGColor;
_progressLayer.strokeColor = [UIColor whiteColor].CGColor;
_progressLayer.lineCap = kCALineCapRound;
_progressLayer.strokeStart = 0;
_progressLayer.strokeEnd = 0;
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(_progressLayer.bounds, 7, 7) cornerRadius:_progressLayer.cornerRadius - 7];
_progressLayer.path = path.CGPath;
_progressLayer.hidden = YES;
}
return _progressLayer;
}
@end
//
// PBPresentAnimatedTransitioningController.h
// PhotoBrowser
//
// Created by Moch Xiao on 5/17/16.
// Copyright © 2016 Moch Xiao (http://mochxiao.com).
//
// 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.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
typedef void(^PBContextBlock)(UIView * __nonnull fromView, UIView * __nonnull toView);
@interface PBPresentAnimatedTransitioningController : NSObject <UIViewControllerAnimatedTransitioning>
@property (nonatomic, copy, nullable) PBContextBlock willPresentActionHandler;
@property (nonatomic, copy, nullable) PBContextBlock onPresentActionHandler;
@property (nonatomic, copy, nullable) PBContextBlock didPresentActionHandler;
@property (nonatomic, copy, nullable) PBContextBlock willDismissActionHandler;
@property (nonatomic, copy, nullable) PBContextBlock onDismissActionHandler;
@property (nonatomic, copy, nullable) PBContextBlock didDismissActionHandler;
/// Default cover is a dim view, you could override this property to your preferred style view.
@property (nonatomic, strong, nonnull) UIView *coverView;
- (nonnull PBPresentAnimatedTransitioningController *)prepareForPresent;
- (nonnull PBPresentAnimatedTransitioningController *)prepareForDismiss;
@end
//
// PBPresentAnimatedTransitioningController.m
// PhotoBrowser
//
// Created by Moch Xiao on 5/17/16.
// Copyright © 2016 Moch Xiao (http://mochxiao.com).
//
// 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.
//
#import "PBPresentAnimatedTransitioningController.h"
@interface PBPresentAnimatedTransitioningController ()
@property (nonatomic, assign) BOOL isPresenting;
@end
@implementation PBPresentAnimatedTransitioningController
#pragma mark - Public methods
- (nonnull PBPresentAnimatedTransitioningController *)prepareForPresent {
self.isPresenting = YES;
return self;
}
- (nonnull PBPresentAnimatedTransitioningController *)prepareForDismiss {
self.isPresenting = NO;
return self;
}
#pragma mark - Private methods
- (UIViewAnimationOptions)_animationOptions {
return 7 << 16;
}
- (void)_animateWithTransition:(nullable id <UIViewControllerContextTransitioning>)transitionContext
animations:(void (^)(void))animations
completion:(void (^)(BOOL flag))completion {
// Prevent other interactions disturb.
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
[UIView animateWithDuration:[self transitionDuration:transitionContext]
delay:0
options:[self _animationOptions]
animations:animations
completion:^(BOOL finished) {
completion(finished);
[[UIApplication sharedApplication] endIgnoringInteractionEvents];
}];
}
- (void)_presentWithTransition:(id <UIViewControllerContextTransitioning>)transitionContext
container:(UIView *)container
from:(UIView *)fromView
to:(UIView *)toView
completion:(void (^)(BOOL flag))completion {
self.coverView.frame = container.frame;
self.coverView.alpha = 0;
[container addSubview:self.coverView];
toView.frame = container.bounds;
[container addSubview:toView];
if (self.willPresentActionHandler) {
self.willPresentActionHandler(fromView, toView);
}
__weak typeof(self) weak_self = self;
[self _animateWithTransition:transitionContext
animations:^{
__strong typeof(weak_self) strong_self = weak_self;
strong_self.coverView.alpha = 1;
if (strong_self.onPresentActionHandler) {
strong_self.onPresentActionHandler(fromView, toView);
}
}
completion:^(BOOL flag) {
__strong typeof(weak_self) strong_self = weak_self;
if (strong_self.didPresentActionHandler) {
strong_self.didPresentActionHandler(fromView, toView);
}
completion(flag);
}];
}
- (void)_dismissWithTransition:(id <UIViewControllerContextTransitioning>)transitionContext
container:(UIView *)container
from:(UIView *)fromView
to:(UIView *)toView
completion:(void (^)(BOOL flag))completion {
[container addSubview:fromView];
if (self.willDismissActionHandler) {
self.willDismissActionHandler(fromView, toView);
}
__weak typeof(self) weak_self = self;
[self _animateWithTransition:transitionContext
animations:^{
__strong typeof(weak_self) strong_self = weak_self;
strong_self.coverView.alpha = 0;
if (strong_self.onDismissActionHandler) {
strong_self.onDismissActionHandler(fromView, toView);
}
}
completion:^(BOOL flag) {
__strong typeof(weak_self) strong_self = weak_self;
if (strong_self.didDismissActionHandler) {
strong_self.didDismissActionHandler(fromView, toView);
}
completion(flag);
}];
}
#pragma mark - UIViewControllerAnimatedTransitioning
- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext {
return 0.25f;
}
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
UIView *container = [transitionContext containerView];
if (!container) {
return;
}
UIViewController *fromController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
if (!fromController) {
return;
}
UIViewController *toController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
if (!toController) {
return;
}
if (self.isPresenting) {
[self _presentWithTransition:transitionContext
container:container
from:fromController.view
to:toController.view
completion:^(BOOL flag) {
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
} else {
[self _dismissWithTransition:transitionContext
container:container
from:fromController.view
to:toController.view
completion:^(BOOL flag) {
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
}
#pragma mark - Accessor
- (UIView *)coverView {
if (!_coverView) {
_coverView = [UIView new];
_coverView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];
_coverView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
_coverView.clipsToBounds = YES;
_coverView.multipleTouchEnabled = NO;
_coverView.userInteractionEnabled = NO;
}
return _coverView;
}
@end
//
// PBViewController.h
// PhotoBrowser
//
// Created by Moch Xiao on 8/24/15.
// Copyright (c) 2015 Moch Xiao (https://github.com/cuzv).
//
// 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.
//
#import <UIKit/UIKit.h>
@class PBViewController;
#pragma mark - PBViewControllerDataSource
@protocol PBViewControllerDataSource <NSObject>
/// Return the pages count
- (NSInteger)numberOfPagesInViewController:(nonnull PBViewController *)viewController;
@optional
/// Return the image, implement one of this or follow method
- (nonnull UIImage *)viewController:(nonnull PBViewController *)viewController imageForPageAtIndex:(NSInteger)index;
/// Configure the imageView's image, implement one of this or upper method
- (void)viewController:(nonnull PBViewController *)viewController presentImageView:(nonnull UIImageView *)imageView forPageAtIndex:(NSInteger)index __attribute__((deprecated("use `viewController:presentImageView:forPageAtIndex:progressHandler` instead.")));
/// Configure the imageView's image, implement one of this or upper method
- (void)viewController:(nonnull PBViewController *)viewController presentImageView:(nonnull UIImageView *)imageView forPageAtIndex:(NSInteger)index progressHandler:(nullable void (^)(NSInteger receivedSize, NSInteger expectedSize))progressHandler;
/// Use for dismiss animation, will be an UIImageView in general.
- (nullable UIView *)thumbViewForPageAtIndex:(NSInteger)index;
@end
#pragma mark - PBViewControllerDelegate
@protocol PBViewControllerDelegate <NSObject>
@optional
/// Action call back for single tap, presentedImage will be nil untill loaded image
- (void)viewController:(nonnull PBViewController *)viewController didSingleTapedPageAtIndex:(NSInteger)index presentedImage:(nullable UIImage *)presentedImage;
/// Action call back for long press, presentedImage will be nil untill loaded image
- (void)viewController:(nonnull PBViewController *)viewController didLongPressedPageAtIndex:(NSInteger)index presentedImage:(nullable UIImage *)presentedImage;
@end
#pragma mark - PBViewController
@interface PBViewController : UIPageViewController
@property (nonatomic, weak, nullable) id<PBViewControllerDataSource> pb_dataSource;
@property (nonatomic, weak, nullable) id<PBViewControllerDelegate> pb_delegate;
@property (nonatomic, assign) NSInteger startPage;
@property (nonatomic, assign) NSInteger pb_startPage;
- (void)setInitializePageIndex:(NSInteger)pageIndex __attribute__((deprecated("use `pb_startPage` instead.")));
@property (nonatomic, assign, readonly) NSInteger numberOfPages;
@property (nonatomic, assign, readonly) NSInteger currentPage;
/// Will show first page.
- (void)reload;
/// Will show the specified page.
- (void)reloadWithCurrentPage:(NSInteger)index;
/// Default value is `YES`
@property (nonatomic, assign) BOOL blurBackground;
/// Default value is `YES`
@property (nonatomic, assign) BOOL hideThumb;
/// Custom exit method, if did not provide, use dismiss.
@property (nonatomic, copy, nullable) void (^exit)(PBViewController * _Nonnull sender);
@end
This diff is collapsed.
//
// PhotoBrowser.h
// PhotoBrowser
//
// Created by Moch Xiao on 8/24/15.
// Copyright (c) 2015 Moch Xiao (https://github.com/cuzv).
//
// 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.
//
#import <UIKit/UIKit.h>
//! Project version number for PhotoBrowser.
FOUNDATION_EXPORT double PhotoBrowserVersionNumber;
//! Project version string for PhotoBrowser.
FOUNDATION_EXPORT const unsigned char PhotoBrowserVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <PhotoBrowser/PublicHeader.h>
#import <PhotoBrowser/PBViewController.h>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment