Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
GeliBusinessPlatform
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
CI / CD Analytics
Repository Analytics
Value Stream Analytics
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ljy
GeliBusinessPlatform
Commits
5c1b463a
Commit
5c1b463a
authored
May 08, 2020
by
刘俊宏
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
添加JXPhotoBrowser(图片浏览器)
parent
31ddb37d
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
1573 additions
and
0 deletions
+1573
-0
GeliBusinessPlatform.xcodeproj/project.pbxproj
GeliBusinessPlatform.xcodeproj/project.pbxproj
+64
-0
GeliBusinessPlatform.xcworkspace/xcuserdata/liujunhong.xcuserdatad/UserInterfaceState.xcuserstate
...ata/liujunhong.xcuserdatad/UserInterfaceState.xcuserstate
+0
-0
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowser.swift
...usinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowser.swift
+327
-0
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserAnimatedTransitioning.swift
.../JXPhotoBrowser/JXPhotoBrowserAnimatedTransitioning.swift
+64
-0
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserCell.swift
...essPlatform/Other/JXPhotoBrowser/JXPhotoBrowserCell.swift
+14
-0
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserDefaultPageIndicator.swift
...r/JXPhotoBrowser/JXPhotoBrowserDefaultPageIndicator.swift
+41
-0
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserFadeAnimator.swift
...orm/Other/JXPhotoBrowser/JXPhotoBrowserFadeAnimator.swift
+55
-0
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserImageCell.swift
...atform/Other/JXPhotoBrowser/JXPhotoBrowserImageCell.swift
+321
-0
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserLog.swift
...nessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserLog.swift
+41
-0
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserNoneAnimator.swift
...orm/Other/JXPhotoBrowser/JXPhotoBrowserNoneAnimator.swift
+19
-0
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserNumberPageIndicator.swift
...er/JXPhotoBrowser/JXPhotoBrowserNumberPageIndicator.swift
+67
-0
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserPageIndicator.swift
...rm/Other/JXPhotoBrowser/JXPhotoBrowserPageIndicator.swift
+18
-0
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserSmoothZoomAnimator.swift
...her/JXPhotoBrowser/JXPhotoBrowserSmoothZoomAnimator.swift
+121
-0
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserView.swift
...essPlatform/Other/JXPhotoBrowser/JXPhotoBrowserView.swift
+261
-0
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserZoomAnimator.swift
...orm/Other/JXPhotoBrowser/JXPhotoBrowserZoomAnimator.swift
+145
-0
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserZoomSupportedCell.swift
...ther/JXPhotoBrowser/JXPhotoBrowserZoomSupportedCell.swift
+15
-0
No files found.
GeliBusinessPlatform.xcodeproj/project.pbxproj
View file @
5c1b463a
...
@@ -302,6 +302,20 @@
...
@@ -302,6 +302,20 @@
F950FDE624518B9500C40530
/* FSCalendarAppearance.m in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
F950FDD624518B9500C40530
/* FSCalendarAppearance.m */
;
};
F950FDE624518B9500C40530
/* FSCalendarAppearance.m in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
F950FDD624518B9500C40530
/* FSCalendarAppearance.m */
;
};
F950FDE824518CD800C40530
/* TimeSelectView.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
F950FDE724518CD800C40530
/* TimeSelectView.swift */
;
};
F950FDE824518CD800C40530
/* TimeSelectView.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
F950FDE724518CD800C40530
/* TimeSelectView.swift */
;
};
F950FDEA2451920200C40530
/* DIYCalendarCell.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
F950FDE92451920200C40530
/* DIYCalendarCell.swift */
;
};
F950FDEA2451920200C40530
/* DIYCalendarCell.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
F950FDE92451920200C40530
/* DIYCalendarCell.swift */
;
};
F9531F392465108800724BEE
/* JXPhotoBrowserPageIndicator.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
F9531F2B2465108800724BEE
/* JXPhotoBrowserPageIndicator.swift */
;
};
F9531F3A2465108800724BEE
/* JXPhotoBrowserNoneAnimator.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
F9531F2C2465108800724BEE
/* JXPhotoBrowserNoneAnimator.swift */
;
};
F9531F3B2465108800724BEE
/* JXPhotoBrowserZoomSupportedCell.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
F9531F2D2465108800724BEE
/* JXPhotoBrowserZoomSupportedCell.swift */
;
};
F9531F3C2465108800724BEE
/* JXPhotoBrowserSmoothZoomAnimator.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
F9531F2E2465108800724BEE
/* JXPhotoBrowserSmoothZoomAnimator.swift */
;
};
F9531F3D2465108800724BEE
/* JXPhotoBrowserAnimatedTransitioning.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
F9531F2F2465108800724BEE
/* JXPhotoBrowserAnimatedTransitioning.swift */
;
};
F9531F3E2465108800724BEE
/* JXPhotoBrowserCell.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
F9531F302465108800724BEE
/* JXPhotoBrowserCell.swift */
;
};
F9531F3F2465108800724BEE
/* JXPhotoBrowserNumberPageIndicator.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
F9531F312465108800724BEE
/* JXPhotoBrowserNumberPageIndicator.swift */
;
};
F9531F402465108800724BEE
/* JXPhotoBrowserZoomAnimator.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
F9531F322465108800724BEE
/* JXPhotoBrowserZoomAnimator.swift */
;
};
F9531F412465108800724BEE
/* JXPhotoBrowserView.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
F9531F332465108800724BEE
/* JXPhotoBrowserView.swift */
;
};
F9531F422465108800724BEE
/* JXPhotoBrowserDefaultPageIndicator.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
F9531F342465108800724BEE
/* JXPhotoBrowserDefaultPageIndicator.swift */
;
};
F9531F432465108800724BEE
/* JXPhotoBrowserImageCell.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
F9531F352465108800724BEE
/* JXPhotoBrowserImageCell.swift */
;
};
F9531F442465108800724BEE
/* JXPhotoBrowserFadeAnimator.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
F9531F362465108800724BEE
/* JXPhotoBrowserFadeAnimator.swift */
;
};
F9531F452465108800724BEE
/* JXPhotoBrowserLog.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
F9531F372465108800724BEE
/* JXPhotoBrowserLog.swift */
;
};
F9531F462465108800724BEE
/* JXPhotoBrowser.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
F9531F382465108800724BEE
/* JXPhotoBrowser.swift */
;
};
F95567A72453DA86009674AB
/* WarehoseMangementListVC.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
F95567A52453DA86009674AB
/* WarehoseMangementListVC.swift */
;
};
F95567A72453DA86009674AB
/* WarehoseMangementListVC.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
F95567A52453DA86009674AB
/* WarehoseMangementListVC.swift */
;
};
F95567A82453DA86009674AB
/* WarehoseMangementListVC.xib in Resources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
F95567A62453DA86009674AB
/* WarehoseMangementListVC.xib */
;
};
F95567A82453DA86009674AB
/* WarehoseMangementListVC.xib in Resources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
F95567A62453DA86009674AB
/* WarehoseMangementListVC.xib */
;
};
F95567AB2453E40B009674AB
/* OrderListViewController.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
F95567A92453E40B009674AB
/* OrderListViewController.swift */
;
};
F95567AB2453E40B009674AB
/* OrderListViewController.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
F95567A92453E40B009674AB
/* OrderListViewController.swift */
;
};
...
@@ -689,6 +703,20 @@
...
@@ -689,6 +703,20 @@
F950FDD624518B9500C40530
/* FSCalendarAppearance.m */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.c.objc
;
path
=
FSCalendarAppearance.m
;
sourceTree
=
"<group>"
;
};
F950FDD624518B9500C40530
/* FSCalendarAppearance.m */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.c.objc
;
path
=
FSCalendarAppearance.m
;
sourceTree
=
"<group>"
;
};
F950FDE724518CD800C40530
/* TimeSelectView.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
TimeSelectView.swift
;
sourceTree
=
"<group>"
;
};
F950FDE724518CD800C40530
/* TimeSelectView.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
TimeSelectView.swift
;
sourceTree
=
"<group>"
;
};
F950FDE92451920200C40530
/* DIYCalendarCell.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
DIYCalendarCell.swift
;
sourceTree
=
"<group>"
;
};
F950FDE92451920200C40530
/* DIYCalendarCell.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
DIYCalendarCell.swift
;
sourceTree
=
"<group>"
;
};
F9531F2B2465108800724BEE
/* JXPhotoBrowserPageIndicator.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
JXPhotoBrowserPageIndicator.swift
;
sourceTree
=
"<group>"
;
};
F9531F2C2465108800724BEE
/* JXPhotoBrowserNoneAnimator.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
JXPhotoBrowserNoneAnimator.swift
;
sourceTree
=
"<group>"
;
};
F9531F2D2465108800724BEE
/* JXPhotoBrowserZoomSupportedCell.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
JXPhotoBrowserZoomSupportedCell.swift
;
sourceTree
=
"<group>"
;
};
F9531F2E2465108800724BEE
/* JXPhotoBrowserSmoothZoomAnimator.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
JXPhotoBrowserSmoothZoomAnimator.swift
;
sourceTree
=
"<group>"
;
};
F9531F2F2465108800724BEE
/* JXPhotoBrowserAnimatedTransitioning.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
JXPhotoBrowserAnimatedTransitioning.swift
;
sourceTree
=
"<group>"
;
};
F9531F302465108800724BEE
/* JXPhotoBrowserCell.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
JXPhotoBrowserCell.swift
;
sourceTree
=
"<group>"
;
};
F9531F312465108800724BEE
/* JXPhotoBrowserNumberPageIndicator.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
JXPhotoBrowserNumberPageIndicator.swift
;
sourceTree
=
"<group>"
;
};
F9531F322465108800724BEE
/* JXPhotoBrowserZoomAnimator.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
JXPhotoBrowserZoomAnimator.swift
;
sourceTree
=
"<group>"
;
};
F9531F332465108800724BEE
/* JXPhotoBrowserView.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
JXPhotoBrowserView.swift
;
sourceTree
=
"<group>"
;
};
F9531F342465108800724BEE
/* JXPhotoBrowserDefaultPageIndicator.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
JXPhotoBrowserDefaultPageIndicator.swift
;
sourceTree
=
"<group>"
;
};
F9531F352465108800724BEE
/* JXPhotoBrowserImageCell.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
JXPhotoBrowserImageCell.swift
;
sourceTree
=
"<group>"
;
};
F9531F362465108800724BEE
/* JXPhotoBrowserFadeAnimator.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
JXPhotoBrowserFadeAnimator.swift
;
sourceTree
=
"<group>"
;
};
F9531F372465108800724BEE
/* JXPhotoBrowserLog.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
JXPhotoBrowserLog.swift
;
sourceTree
=
"<group>"
;
};
F9531F382465108800724BEE
/* JXPhotoBrowser.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
JXPhotoBrowser.swift
;
sourceTree
=
"<group>"
;
};
F95567A52453DA86009674AB
/* WarehoseMangementListVC.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
WarehoseMangementListVC.swift
;
sourceTree
=
"<group>"
;
};
F95567A52453DA86009674AB
/* WarehoseMangementListVC.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
WarehoseMangementListVC.swift
;
sourceTree
=
"<group>"
;
};
F95567A62453DA86009674AB
/* WarehoseMangementListVC.xib */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
file.xib
;
path
=
WarehoseMangementListVC.xib
;
sourceTree
=
"<group>"
;
};
F95567A62453DA86009674AB
/* WarehoseMangementListVC.xib */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
file.xib
;
path
=
WarehoseMangementListVC.xib
;
sourceTree
=
"<group>"
;
};
F95567A92453E40B009674AB
/* OrderListViewController.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
OrderListViewController.swift
;
sourceTree
=
"<group>"
;
};
F95567A92453E40B009674AB
/* OrderListViewController.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
OrderListViewController.swift
;
sourceTree
=
"<group>"
;
};
...
@@ -1083,6 +1111,7 @@
...
@@ -1083,6 +1111,7 @@
E088CC882446FFA1000DAA8A
/* Other */
=
{
E088CC882446FFA1000DAA8A
/* Other */
=
{
isa
=
PBXGroup
;
isa
=
PBXGroup
;
children
=
(
children
=
(
F9531F2A2465108800724BEE
/* JXPhotoBrowser */
,
F9DDBE932457D3CB00A32CB2
/* Web */
,
F9DDBE932457D3CB00A32CB2
/* Web */
,
F95A9ED324551DDC00867849
/* Parchment */
,
F95A9ED324551DDC00867849
/* Parchment */
,
F933F6D02452DAC300189561
/* TabBarVc */
,
F933F6D02452DAC300189561
/* TabBarVc */
,
...
@@ -1661,6 +1690,27 @@
...
@@ -1661,6 +1690,27 @@
path
=
FSCalendar
;
path
=
FSCalendar
;
sourceTree
=
"<group>"
;
sourceTree
=
"<group>"
;
};
};
F9531F2A2465108800724BEE
/* JXPhotoBrowser */
=
{
isa
=
PBXGroup
;
children
=
(
F9531F2B2465108800724BEE
/* JXPhotoBrowserPageIndicator.swift */
,
F9531F2C2465108800724BEE
/* JXPhotoBrowserNoneAnimator.swift */
,
F9531F2D2465108800724BEE
/* JXPhotoBrowserZoomSupportedCell.swift */
,
F9531F2E2465108800724BEE
/* JXPhotoBrowserSmoothZoomAnimator.swift */
,
F9531F2F2465108800724BEE
/* JXPhotoBrowserAnimatedTransitioning.swift */
,
F9531F302465108800724BEE
/* JXPhotoBrowserCell.swift */
,
F9531F312465108800724BEE
/* JXPhotoBrowserNumberPageIndicator.swift */
,
F9531F322465108800724BEE
/* JXPhotoBrowserZoomAnimator.swift */
,
F9531F332465108800724BEE
/* JXPhotoBrowserView.swift */
,
F9531F342465108800724BEE
/* JXPhotoBrowserDefaultPageIndicator.swift */
,
F9531F352465108800724BEE
/* JXPhotoBrowserImageCell.swift */
,
F9531F362465108800724BEE
/* JXPhotoBrowserFadeAnimator.swift */
,
F9531F372465108800724BEE
/* JXPhotoBrowserLog.swift */
,
F9531F382465108800724BEE
/* JXPhotoBrowser.swift */
,
);
path
=
JXPhotoBrowser
;
sourceTree
=
"<group>"
;
};
F95A9ED324551DDC00867849
/* Parchment */
=
{
F95A9ED324551DDC00867849
/* Parchment */
=
{
isa
=
PBXGroup
;
isa
=
PBXGroup
;
children
=
(
children
=
(
...
@@ -2099,13 +2149,16 @@
...
@@ -2099,13 +2149,16 @@
files
=
(
files
=
(
E0A409C32463F31600CFF109
/* ShouZhiTongJiViewController.swift in Sources */
,
E0A409C32463F31600CFF109
/* ShouZhiTongJiViewController.swift in Sources */
,
F950FDE624518B9500C40530
/* FSCalendarAppearance.m in Sources */
,
F950FDE624518B9500C40530
/* FSCalendarAppearance.m in Sources */
,
F9531F392465108800724BEE
/* JXPhotoBrowserPageIndicator.swift in Sources */
,
F9023F6D2449A9B100DD5A63
/* TitleAndTFCell.swift in Sources */
,
F9023F6D2449A9B100DD5A63
/* TitleAndTFCell.swift in Sources */
,
F933F6D22452DAE100189561
/* TabBarContentClassView.swift in Sources */
,
F933F6D22452DAE100189561
/* TabBarContentClassView.swift in Sources */
,
F933F6C82452C68B00189561
/* PKHUDTextView.swift in Sources */
,
F933F6C82452C68B00189561
/* PKHUDTextView.swift in Sources */
,
E0A409C82464010D00CFF109
/* FirstCell.swift in Sources */
,
E0A409C82464010D00CFF109
/* FirstCell.swift in Sources */
,
F9531F422465108800724BEE
/* JXPhotoBrowserDefaultPageIndicator.swift in Sources */
,
E0B6036E244D376900A56B38
/* KuWeiCell.swift in Sources */
,
E0B6036E244D376900A56B38
/* KuWeiCell.swift in Sources */
,
E0D197BA2448431C002B080C
/* BabyDefine.m in Sources */
,
E0D197BA2448431C002B080C
/* BabyDefine.m in Sources */
,
F94A314924624FA400FEC38E
/* ShopAdministratorInfoModel.swift in Sources */
,
F94A314924624FA400FEC38E
/* ShopAdministratorInfoModel.swift in Sources */
,
F9531F3E2465108800724BEE
/* JXPhotoBrowserCell.swift in Sources */
,
F961D264244FD744007FBE70
/* SearchBarView.swift in Sources */
,
F961D264244FD744007FBE70
/* SearchBarView.swift in Sources */
,
F950FDE124518B9500C40530
/* FSCalendarConstants.m in Sources */
,
F950FDE124518B9500C40530
/* FSCalendarConstants.m in Sources */
,
F9023F712449ACA800DD5A63
/* TitleAndSwitchCell.swift in Sources */
,
F9023F712449ACA800DD5A63
/* TitleAndSwitchCell.swift in Sources */
,
...
@@ -2124,6 +2177,7 @@
...
@@ -2124,6 +2177,7 @@
E0B94623245671E100FBEC9A
/* DaiKeXiaDanGouWuViewController.swift in Sources */
,
E0B94623245671E100FBEC9A
/* DaiKeXiaDanGouWuViewController.swift in Sources */
,
E0A320C52456D01300AF321C
/* DaiKeXiaDanFooterView.swift in Sources */
,
E0A320C52456D01300AF321C
/* DaiKeXiaDanFooterView.swift in Sources */
,
E0336DD5244EC40000380BE9
/* CreatNewSpecsViewController.swift in Sources */
,
E0336DD5244EC40000380BE9
/* CreatNewSpecsViewController.swift in Sources */
,
F9531F3F2465108800724BEE
/* JXPhotoBrowserNumberPageIndicator.swift in Sources */
,
E09F4CA22452D18800BE033D
/* ZengZhiServicesViewController.swift in Sources */
,
E09F4CA22452D18800BE033D
/* ZengZhiServicesViewController.swift in Sources */
,
F94A315B24628C7E00FEC38E
/* WorkItemTableViewCell.swift in Sources */
,
F94A315B24628C7E00FEC38E
/* WorkItemTableViewCell.swift in Sources */
,
E0DDCB18244AE2AC00DF54C7
/* XiuGaiYuShouJiaViewController.swift in Sources */
,
E0DDCB18244AE2AC00DF54C7
/* XiuGaiYuShouJiaViewController.swift in Sources */
,
...
@@ -2151,6 +2205,8 @@
...
@@ -2151,6 +2205,8 @@
E0A2E82B24555D8600D6DB34
/* KuCunXiangQingCell.swift in Sources */
,
E0A2E82B24555D8600D6DB34
/* KuCunXiangQingCell.swift in Sources */
,
F933F6C22452C68B00189561
/* PKHUDAnimating.swift in Sources */
,
F933F6C22452C68B00189561
/* PKHUDAnimating.swift in Sources */
,
E00E48C62457C99900F16545
/* KuCunShangPinXQViewController.swift in Sources */
,
E00E48C62457C99900F16545
/* KuCunShangPinXQViewController.swift in Sources */
,
F9531F3C2465108800724BEE
/* JXPhotoBrowserSmoothZoomAnimator.swift in Sources */
,
F9531F402465108800724BEE
/* JXPhotoBrowserZoomAnimator.swift in Sources */
,
E0BE8A9C245A9E5900E80134
/* YingFuZhangKuanXQCell.swift in Sources */
,
E0BE8A9C245A9E5900E80134
/* YingFuZhangKuanXQCell.swift in Sources */
,
E02C882A2456B4BA00925766
/* WLGZCell.swift in Sources */
,
E02C882A2456B4BA00925766
/* WLGZCell.swift in Sources */
,
F950FDE824518CD800C40530
/* TimeSelectView.swift in Sources */
,
F950FDE824518CD800C40530
/* TimeSelectView.swift in Sources */
,
...
@@ -2158,6 +2214,7 @@
...
@@ -2158,6 +2214,7 @@
F94A314B246250DB00FEC38E
/* GoodsDetailModel.swift in Sources */
,
F94A314B246250DB00FEC38E
/* GoodsDetailModel.swift in Sources */
,
E02DDD85244FDC6A00ABB707
/* TitleAndSwitchHeaderView.swift in Sources */
,
E02DDD85244FDC6A00ABB707
/* TitleAndSwitchHeaderView.swift in Sources */
,
E0F3C2CB24590C86006F0D1F
/* XinZengAndBianJiKeHuViewController.swift in Sources */
,
E0F3C2CB24590C86006F0D1F
/* XinZengAndBianJiKeHuViewController.swift in Sources */
,
F9531F412465108800724BEE
/* JXPhotoBrowserView.swift in Sources */
,
E0D197C02448431C002B080C
/* BabyCentralManager.m in Sources */
,
E0D197C02448431C002B080C
/* BabyCentralManager.m in Sources */
,
F95D9CA424493E840080D6E3
/* ShopInfoViewController.swift in Sources */
,
F95D9CA424493E840080D6E3
/* ShopInfoViewController.swift in Sources */
,
F9171EFC245128B200359C2B
/* Interface.swift in Sources */
,
F9171EFC245128B200359C2B
/* Interface.swift in Sources */
,
...
@@ -2213,6 +2270,7 @@
...
@@ -2213,6 +2270,7 @@
F933F6C02452C68B00189561
/* PKHUDSystemActivityIndicatorView.swift in Sources */
,
F933F6C02452C68B00189561
/* PKHUDSystemActivityIndicatorView.swift in Sources */
,
E08B0674244A98B2001D2E01
/* WareHouseSpCell.swift in Sources */
,
E08B0674244A98B2001D2E01
/* WareHouseSpCell.swift in Sources */
,
E0A2E81E24552F0A00D6DB34
/* TilteAndTextViewCell.swift in Sources */
,
E0A2E81E24552F0A00D6DB34
/* TilteAndTextViewCell.swift in Sources */
,
F9531F3D2465108800724BEE
/* JXPhotoBrowserAnimatedTransitioning.swift in Sources */
,
E0D197CA24484D90002B080C
/* PersonCenterCell.swift in Sources */
,
E0D197CA24484D90002B080C
/* PersonCenterCell.swift in Sources */
,
E0C4F4B5244EE9EE00CC7E2F
/* YuShouCell.swift in Sources */
,
E0C4F4B5244EE9EE00CC7E2F
/* YuShouCell.swift in Sources */
,
F933F6C52452C68B00189561
/* PKHUDSuccessView.swift in Sources */
,
F933F6C52452C68B00189561
/* PKHUDSuccessView.swift in Sources */
,
...
@@ -2222,8 +2280,10 @@
...
@@ -2222,8 +2280,10 @@
E042F74024528CD500CDFA12
/* TitleAndOnlyBtnCell.swift in Sources */
,
E042F74024528CD500CDFA12
/* TitleAndOnlyBtnCell.swift in Sources */
,
F969BF07244EC38000C79953
/* GoodsCollectionViewCell.swift in Sources */
,
F969BF07244EC38000C79953
/* GoodsCollectionViewCell.swift in Sources */
,
E02FD9F12455705F00E10E27
/* ChuRuKuJiLuCell.swift in Sources */
,
E02FD9F12455705F00E10E27
/* ChuRuKuJiLuCell.swift in Sources */
,
F9531F462465108800724BEE
/* JXPhotoBrowser.swift in Sources */
,
E0A2E82724555B4400D6DB34
/* KuCunShangPinCell.swift in Sources */
,
E0A2E82724555B4400D6DB34
/* KuCunShangPinCell.swift in Sources */
,
F950FDA72451494500C40530
/* GeliPayInfoModel.swift in Sources */
,
F950FDA72451494500C40530
/* GeliPayInfoModel.swift in Sources */
,
F9531F432465108800724BEE
/* JXPhotoBrowserImageCell.swift in Sources */
,
E07B1E6B245926330055BA3C
/* GYSGLCell.swift in Sources */
,
E07B1E6B245926330055BA3C
/* GYSGLCell.swift in Sources */
,
E09B03C02445B96500211A51
/* FgPassViewController.swift in Sources */
,
E09B03C02445B96500211A51
/* FgPassViewController.swift in Sources */
,
F950FDAB2451634B00C40530
/* LocationGeliPayModel.swift in Sources */
,
F950FDAB2451634B00C40530
/* LocationGeliPayModel.swift in Sources */
,
...
@@ -2244,6 +2304,7 @@
...
@@ -2244,6 +2304,7 @@
E06524F524580BB600CA22E2
/* BaoZhiQiCell.swift in Sources */
,
E06524F524580BB600CA22E2
/* BaoZhiQiCell.swift in Sources */
,
E0BE8AA4245AA31400E80134
/* YingFuZhangKuanXQViewController.swift in Sources */
,
E0BE8AA4245AA31400E80134
/* YingFuZhangKuanXQViewController.swift in Sources */
,
F94A315324626D7800FEC38E
/* WorkCViewController.swift in Sources */
,
F94A315324626D7800FEC38E
/* WorkCViewController.swift in Sources */
,
F9531F3A2465108800724BEE
/* JXPhotoBrowserNoneAnimator.swift in Sources */
,
E07B1E62245921A60055BA3C
/* KeHuXQCell.swift in Sources */
,
E07B1E62245921A60055BA3C
/* KeHuXQCell.swift in Sources */
,
E0DDCB1D244AE81800DF54C7
/* GuanLianKeHuCell.swift in Sources */
,
E0DDCB1D244AE81800DF54C7
/* GuanLianKeHuCell.swift in Sources */
,
E0D197BF2448431C002B080C
/* BabyBluetooth.m in Sources */
,
E0D197BF2448431C002B080C
/* BabyBluetooth.m in Sources */
,
...
@@ -2265,7 +2326,9 @@
...
@@ -2265,7 +2326,9 @@
E0516F772448003D00E373CE
/* PayViewController.swift in Sources */
,
E0516F772448003D00E373CE
/* PayViewController.swift in Sources */
,
E02DDD952450106C00ABB707
/* PuTongJieTiCell.swift in Sources */
,
E02DDD952450106C00ABB707
/* PuTongJieTiCell.swift in Sources */
,
E0BE8A8B245A7D3300E80134
/* BtmBtnCell.swift in Sources */
,
E0BE8A8B245A7D3300E80134
/* BtmBtnCell.swift in Sources */
,
F9531F452465108800724BEE
/* JXPhotoBrowserLog.swift in Sources */
,
F9956B1E2463D94E001A617D
/* WorkSelectTimeView.swift in Sources */
,
F9956B1E2463D94E001A617D
/* WorkSelectTimeView.swift in Sources */
,
F9531F3B2465108800724BEE
/* JXPhotoBrowserZoomSupportedCell.swift in Sources */
,
F950FDE024518B9500C40530
/* FSCalendarExtensions.m in Sources */
,
F950FDE024518B9500C40530
/* FSCalendarExtensions.m in Sources */
,
E09B03A32445AF9500211A51
/* NetworkRequest.swift in Sources */
,
E09B03A32445AF9500211A51
/* NetworkRequest.swift in Sources */
,
E0D46C5624503EC50087B564
/* TitleAndSelectCell.swift in Sources */
,
E0D46C5624503EC50087B564
/* TitleAndSelectCell.swift in Sources */
,
...
@@ -2280,6 +2343,7 @@
...
@@ -2280,6 +2343,7 @@
E0B9461E24566B3100FBEC9A
/* TitleAndTFAndBtnCell.swift in Sources */
,
E0B9461E24566B3100FBEC9A
/* TitleAndTFAndBtnCell.swift in Sources */
,
E042F74324529B7B00CDFA12
/* JiTuoWuXinXiView.swift in Sources */
,
E042F74324529B7B00CDFA12
/* JiTuoWuXinXiView.swift in Sources */
,
F933F6CC2452C68B00189561
/* WindowRootViewController.swift in Sources */
,
F933F6CC2452C68B00189561
/* WindowRootViewController.swift in Sources */
,
F9531F442465108800724BEE
/* JXPhotoBrowserFadeAnimator.swift in Sources */
,
E088CC8D24470BF0000DAA8A
/* CodeView.swift in Sources */
,
E088CC8D24470BF0000DAA8A
/* CodeView.swift in Sources */
,
E01EA1A4245A60E000F019D5
/* XiaDanChengGongViewController.swift in Sources */
,
E01EA1A4245A60E000F019D5
/* XiaDanChengGongViewController.swift in Sources */
,
F94A314D2462582F00FEC38E
/* GeneralInfoModel.swift in Sources */
,
F94A314D2462582F00FEC38E
/* GeneralInfoModel.swift in Sources */
,
...
...
GeliBusinessPlatform.xcworkspace/xcuserdata/liujunhong.xcuserdatad/UserInterfaceState.xcuserstate
View file @
5c1b463a
No preview for this file type
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowser.swift
0 → 100755
View file @
5c1b463a
//
// JXPhotoBrowser.swift
// JXPhotoBrowser
//
// Created by JiongXing on 2019/11/11.
// Copyright © 2019 JiongXing. All rights reserved.
//
import
UIKit
/// 图片浏览器
/// - 不支持复用,每次使用请新建实例
open
class
JXPhotoBrowser
:
UIViewController
,
UIViewControllerTransitioningDelegate
,
UINavigationControllerDelegate
{
/// 通过本回调,把图片浏览器嵌套在导航控制器里
public
typealias
PresentEmbedClosure
=
(
JXPhotoBrowser
)
->
UINavigationController
/// 打开方式类型
public
enum
ShowMethod
{
case
push
(
inNC
:
UINavigationController
?)
case
present
(
fromVC
:
UIViewController
?,
embed
:
PresentEmbedClosure
?)
}
/// 滑动方向类型
public
enum
ScrollDirection
{
case
horizontal
case
vertical
}
/// 自实现转场动画
open
lazy
var
transitionAnimator
:
JXPhotoBrowserAnimatedTransitioning
=
JXPhotoBrowserFadeAnimator
()
/// 滑动方向
open
var
scrollDirection
:
JXPhotoBrowser
.
ScrollDirection
{
set
{
browserView
.
scrollDirection
=
newValue
}
get
{
return
browserView
.
scrollDirection
}
}
/// 项间距
open
var
itemSpacing
:
CGFloat
{
set
{
browserView
.
itemSpacing
=
newValue
}
get
{
return
browserView
.
itemSpacing
}
}
/// 当前页码
open
var
pageIndex
:
Int
{
set
{
browserView
.
pageIndex
=
newValue
}
get
{
return
browserView
.
pageIndex
}
}
/// 浏览过程中实时获取数据总量
open
var
numberOfItems
:
()
->
Int
{
set
{
browserView
.
numberOfItems
=
newValue
}
get
{
return
browserView
.
numberOfItems
}
}
/// 返回可复用的Cell类。用户可根据index返回不同的类。本闭包将在每次复用Cell时实时调用。
open
var
cellClassAtIndex
:
(
_
index
:
Int
)
->
JXPhotoBrowserCell
.
Type
{
set
{
browserView
.
cellClassAtIndex
=
newValue
}
get
{
return
browserView
.
cellClassAtIndex
}
}
/// Cell刷新时用的上下文。index: 刷新的Cell对应的index;currentIndex: 当前显示的页
public
typealias
ReloadCellContext
=
(
cell
:
JXPhotoBrowserCell
,
index
:
Int
,
currentIndex
:
Int
)
/// 刷新Cell数据。本闭包将在Cell完成位置布局后调用。
open
var
reloadCellAtIndex
:
(
ReloadCellContext
)
->
Void
{
set
{
browserView
.
reloadCellAtIndex
=
newValue
}
get
{
return
browserView
.
reloadCellAtIndex
}
}
/// 自然滑动引起的页码改变时回调
open
lazy
var
didChangedPageIndex
:
(
_
index
:
Int
)
->
Void
=
{
_
in
}
/// Cell将显示
open
var
cellWillAppear
:
(
JXPhotoBrowserCell
,
Int
)
->
Void
{
set
{
browserView
.
cellWillAppear
=
newValue
}
get
{
return
browserView
.
cellWillAppear
}
}
/// Cell将不显示
open
var
cellWillDisappear
:
(
JXPhotoBrowserCell
,
Int
)
->
Void
{
set
{
browserView
.
cellWillDisappear
=
newValue
}
get
{
return
browserView
.
cellWillDisappear
}
}
/// Cell已显示
open
var
cellDidAppear
:
(
JXPhotoBrowserCell
,
Int
)
->
Void
{
set
{
browserView
.
cellDidAppear
=
newValue
}
get
{
return
browserView
.
cellDidAppear
}
}
/// 主视图
open
lazy
var
browserView
=
JXPhotoBrowserView
()
/// 页码指示
open
var
pageIndicator
:
JXPhotoBrowserPageIndicator
?
/// 背景蒙版
open
lazy
var
maskView
:
UIView
=
{
let
view
=
UIView
()
view
.
backgroundColor
=
.
black
return
view
}()
open
weak
var
previousNavigationControllerDelegate
:
UINavigationControllerDelegate
?
public
init
()
{
super
.
init
(
nibName
:
nil
,
bundle
:
nil
)
}
required
public
init
?(
coder
:
NSCoder
)
{
fatalError
(
"init(coder:) has not been implemented"
)
}
/// 显示图片浏览器
open
func
show
(
method
:
ShowMethod
=
.
present
(
fromVC
:
nil
,
embed
:
nil
))
{
switch
method
{
case
.
push
(
let
inNC
):
let
nav
=
inNC
??
JXPhotoBrowser
.
topMost
?
.
navigationController
previousNavigationControllerDelegate
=
nav
?
.
delegate
nav
?
.
delegate
=
self
nav
?
.
pushViewController
(
self
,
animated
:
true
)
case
.
present
(
let
fromVC
,
let
embed
):
let
toVC
=
embed
?(
self
)
??
self
toVC
.
modalPresentationStyle
=
.
custom
toVC
.
modalPresentationCapturesStatusBarAppearance
=
true
toVC
.
transitioningDelegate
=
self
let
from
=
fromVC
??
JXPhotoBrowser
.
topMost
from
?
.
present
(
toVC
,
animated
:
true
,
completion
:
nil
)
}
}
/// 刷新
open
func
reloadData
()
{
browserView
.
reloadData
()
pageIndicator
?
.
reloadData
(
numberOfItems
:
numberOfItems
(),
pageIndex
:
pageIndex
)
}
open
override
func
viewDidLoad
()
{
super
.
viewDidLoad
()
automaticallyAdjustsScrollViewInsets
=
false
hideNavigationBar
(
true
)
browserView
.
photoBrowser
=
self
transitionAnimator
.
photoBrowser
=
self
view
.
backgroundColor
=
.
clear
view
.
addSubview
(
maskView
)
view
.
addSubview
(
browserView
)
browserView
.
didChangedPageIndex
=
{
[
weak
self
]
index
in
guard
let
`
self
`
=
self
else
{
return
}
self
.
pageIndicator
?
.
didChanged
(
pageIndex
:
index
)
self
.
didChangedPageIndex
(
index
)
}
view
.
setNeedsLayout
()
view
.
layoutIfNeeded
()
}
open
override
func
viewWillLayoutSubviews
()
{
super
.
viewWillLayoutSubviews
()
maskView
.
frame
=
view
.
bounds
browserView
.
frame
=
view
.
bounds
pageIndicator
?
.
reloadData
(
numberOfItems
:
numberOfItems
(),
pageIndex
:
pageIndex
)
}
open
override
func
viewWillAppear
(
_
animated
:
Bool
)
{
super
.
viewWillAppear
(
animated
)
hideNavigationBar
(
true
)
}
open
override
func
viewDidAppear
(
_
animated
:
Bool
)
{
super
.
viewDidAppear
(
animated
)
navigationController
?
.
delegate
=
previousNavigationControllerDelegate
if
let
indicator
=
pageIndicator
{
view
.
addSubview
(
indicator
)
indicator
.
setup
(
with
:
self
)
}
}
open
override
func
viewWillDisappear
(
_
animated
:
Bool
)
{
super
.
viewWillDisappear
(
animated
)
hideNavigationBar
(
false
)
}
open
override
func
viewWillTransition
(
to
size
:
CGSize
,
with
coordinator
:
UIViewControllerTransitionCoordinator
)
{
super
.
viewWillTransition
(
to
:
size
,
with
:
coordinator
)
browserView
.
isRotating
=
true
}
//
// MARK: - Navigation Bar
//
/// 在PhotoBrowser打开之前,导航栏是否隐藏
open
var
isPreviousNavigationBarHidden
:
Bool
?
private
func
hideNavigationBar
(
_
hide
:
Bool
)
{
if
hide
{
if
isPreviousNavigationBarHidden
==
nil
{
isPreviousNavigationBarHidden
=
navigationController
?
.
isNavigationBarHidden
}
navigationController
?
.
setNavigationBarHidden
(
true
,
animated
:
false
)
}
else
{
if
let
barHidden
=
isPreviousNavigationBarHidden
{
navigationController
?
.
setNavigationBarHidden
(
barHidden
,
animated
:
false
)
}
}
}
//
// MARK: - Status Bar
//
private
lazy
var
isPreviousStatusBarHidden
:
Bool
=
{
var
previousVC
:
UIViewController
?
if
let
vc
=
self
.
presentingViewController
{
previousVC
=
vc
}
else
{
if
let
navVCs
=
self
.
navigationController
?
.
viewControllers
,
navVCs
.
count
>=
2
{
previousVC
=
navVCs
[
navVCs
.
count
-
2
]
}
}
return
previousVC
?
.
prefersStatusBarHidden
??
false
}()
private
lazy
var
isStatusBarHidden
=
self
.
isPreviousStatusBarHidden
open
override
var
prefersStatusBarHidden
:
Bool
{
return
isStatusBarHidden
}
open
func
setStatusBar
(
hidden
:
Bool
)
{
if
hidden
{
isStatusBarHidden
=
true
}
else
{
isStatusBarHidden
=
isPreviousStatusBarHidden
}
setNeedsStatusBarAppearanceUpdate
()
}
//
// MARK: - 转场
//
public
func
animationController
(
forPresented
presented
:
UIViewController
,
presenting
:
UIViewController
,
source
:
UIViewController
)
->
UIViewControllerAnimatedTransitioning
?
{
transitionAnimator
.
isForShow
=
true
transitionAnimator
.
photoBrowser
=
self
return
transitionAnimator
}
public
func
animationController
(
forDismissed
dismissed
:
UIViewController
)
->
UIViewControllerAnimatedTransitioning
?
{
transitionAnimator
.
isForShow
=
false
transitionAnimator
.
photoBrowser
=
self
return
transitionAnimator
}
public
func
navigationController
(
_
navigationController
:
UINavigationController
,
animationControllerFor
operation
:
UINavigationController
.
Operation
,
from
fromVC
:
UIViewController
,
to
toVC
:
UIViewController
)
->
UIViewControllerAnimatedTransitioning
?
{
transitionAnimator
.
isForShow
=
(
operation
==
.
push
)
transitionAnimator
.
photoBrowser
=
self
transitionAnimator
.
isNavigationAnimation
=
true
return
transitionAnimator
}
/// 关闭PhotoBrowser
open
func
dismiss
()
{
setStatusBar
(
hidden
:
false
)
pageIndicator
?
.
removeFromSuperview
()
if
presentingViewController
!=
nil
{
dismiss
(
animated
:
true
,
completion
:
nil
)
}
else
{
navigationController
?
.
delegate
=
self
navigationController
?
.
popViewController
(
animated
:
true
)
}
}
deinit
{
JXPhotoBrowserLog
.
low
(
"deinit -
\(
self
.
classForCoder
)
"
)
navigationController
?
.
delegate
=
previousNavigationControllerDelegate
}
//
// MARK: - 取顶层控制器
//
/// 取最顶层的ViewController
open
class
var
topMost
:
UIViewController
?
{
return
topMost
(
of
:
UIApplication
.
shared
.
keyWindow
?
.
rootViewController
)
}
open
class
func
topMost
(
of
viewController
:
UIViewController
?)
->
UIViewController
?
{
// presented view controller
if
let
presentedViewController
=
viewController
?
.
presentedViewController
{
return
self
.
topMost
(
of
:
presentedViewController
)
}
// UITabBarController
if
let
tabBarController
=
viewController
as?
UITabBarController
,
let
selectedViewController
=
tabBarController
.
selectedViewController
{
return
self
.
topMost
(
of
:
selectedViewController
)
}
// UINavigationController
if
let
navigationController
=
viewController
as?
UINavigationController
,
let
visibleViewController
=
navigationController
.
visibleViewController
{
return
self
.
topMost
(
of
:
visibleViewController
)
}
// UIPageController
if
let
pageViewController
=
viewController
as?
UIPageViewController
,
pageViewController
.
viewControllers
?
.
count
==
1
{
return
self
.
topMost
(
of
:
pageViewController
.
viewControllers
?
.
first
)
}
// child view controller
for
subview
in
viewController
?
.
view
?
.
subviews
??
[]
{
if
let
childViewController
=
subview
.
next
as?
UIViewController
{
return
self
.
topMost
(
of
:
childViewController
)
}
}
return
viewController
}
}
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserAnimatedTransitioning.swift
0 → 100755
View file @
5c1b463a
//
// JXPhotoBrowserAnimatedTransitioning.swift
// JXPhotoBrowser
//
// Created by JiongXing on 2019/11/25.
// Copyright © 2019 JiongXing. All rights reserved.
//
import
UIKit
public
protocol
JXPhotoBrowserAnimatedTransitioning
:
UIViewControllerAnimatedTransitioning
{
var
isForShow
:
Bool
{
get
set
}
var
photoBrowser
:
JXPhotoBrowser
?
{
get
set
}
var
isNavigationAnimation
:
Bool
{
get
set
}
}
private
var
isForShowKey
=
"isForShowKey"
private
var
photoBrowserKey
=
"photoBrowserKey"
extension
JXPhotoBrowserAnimatedTransitioning
{
public
var
isForShow
:
Bool
{
get
{
if
let
value
=
objc_getAssociatedObject
(
self
,
&
isForShowKey
)
as?
Bool
{
return
value
}
return
true
}
set
{
objc_setAssociatedObject
(
self
,
&
isForShowKey
,
newValue
,
.
OBJC_ASSOCIATION_ASSIGN
)
}
}
public
weak
var
photoBrowser
:
JXPhotoBrowser
?
{
get
{
return
objc_getAssociatedObject
(
self
,
&
photoBrowserKey
)
as?
JXPhotoBrowser
}
set
{
objc_setAssociatedObject
(
self
,
&
photoBrowserKey
,
newValue
,
.
OBJC_ASSOCIATION_ASSIGN
)
}
}
public
var
isNavigationAnimation
:
Bool
{
get
{
return
false
}
set
{
}
}
public
func
fastSnapshot
(
with
view
:
UIView
)
->
UIView
?
{
UIGraphicsBeginImageContextWithOptions
(
view
.
bounds
.
size
,
false
,
UIScreen
.
main
.
scale
)
view
.
drawHierarchy
(
in
:
view
.
bounds
,
afterScreenUpdates
:
false
)
let
image
=
UIGraphicsGetImageFromCurrentImageContext
()
UIGraphicsEndImageContext
()
return
UIImageView
(
image
:
image
)
}
public
func
snapshot
(
with
view
:
UIView
)
->
UIView
?
{
UIGraphicsBeginImageContextWithOptions
(
view
.
bounds
.
size
,
false
,
UIScreen
.
main
.
scale
)
guard
let
context
=
UIGraphicsGetCurrentContext
()
else
{
return
nil
}
view
.
layer
.
render
(
in
:
context
)
let
image
=
UIGraphicsGetImageFromCurrentImageContext
()
UIGraphicsEndImageContext
()
return
UIImageView
(
image
:
image
)
}
}
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserCell.swift
0 → 100755
View file @
5c1b463a
//
// JXPhotoBrowserCell.swift
// JXPhotoBrowser
//
// Created by JiongXing on 2019/11/26.
// Copyright © 2019 JiongXing. All rights reserved.
//
import
UIKit
public
protocol
JXPhotoBrowserCell
:
UIView
{
static
func
generate
(
with
browser
:
JXPhotoBrowser
)
->
Self
}
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserDefaultPageIndicator.swift
0 → 100755
View file @
5c1b463a
//
// JXPhotoBrowserDefaultPageIndicator.swift
// JXPhotoBrowser
//
// Created by JiongXing on 2019/11/25.
// Copyright © 2019 JiongXing. All rights reserved.
//
import
UIKit
open
class
JXPhotoBrowserDefaultPageIndicator
:
UIPageControl
,
JXPhotoBrowserPageIndicator
{
/// 页码与底部的距离
open
lazy
var
bottomPadding
:
CGFloat
=
{
if
#available(iOS 11.0, *)
,
let
window
=
UIApplication
.
shared
.
keyWindow
,
window
.
safeAreaInsets
.
bottom
>
0
{
return
20
}
return
15
}()
open
func
setup
(
with
browser
:
JXPhotoBrowser
)
{
isEnabled
=
false
}
open
func
reloadData
(
numberOfItems
:
Int
,
pageIndex
:
Int
)
{
numberOfPages
=
numberOfItems
currentPage
=
min
(
pageIndex
,
numberOfPages
-
1
)
sizeToFit
()
isHidden
=
numberOfPages
<=
1
if
let
view
=
superview
{
center
.
x
=
view
.
bounds
.
width
/
2
frame
.
origin
.
y
=
view
.
bounds
.
maxY
-
bottomPadding
-
bounds
.
height
}
}
open
func
didChanged
(
pageIndex
:
Int
)
{
currentPage
=
pageIndex
}
}
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserFadeAnimator.swift
0 → 100755
View file @
5c1b463a
//
// JXPhotoBrowserFadeAnimator.swift
// JXPhotoBrowser
//
// Created by JiongXing on 2019/11/25.
// Copyright © 2019 JiongXing. All rights reserved.
//
import
UIKit
open
class
JXPhotoBrowserFadeAnimator
:
NSObject
,
JXPhotoBrowserAnimatedTransitioning
{
open
var
showDuration
:
TimeInterval
=
0.25
open
var
dismissDuration
:
TimeInterval
=
0.25
public
var
isNavigationAnimation
:
Bool
=
false
public
func
transitionDuration
(
using
transitionContext
:
UIViewControllerContextTransitioning
?)
->
TimeInterval
{
return
isForShow
?
showDuration
:
dismissDuration
}
public
func
animateTransition
(
using
transitionContext
:
UIViewControllerContextTransitioning
)
{
guard
let
browser
=
photoBrowser
else
{
transitionContext
.
completeTransition
(
!
transitionContext
.
transitionWasCancelled
)
return
}
if
isNavigationAnimation
,
isForShow
,
let
fromView
=
transitionContext
.
view
(
forKey
:
.
from
),
let
fromViewSnapshot
=
snapshot
(
with
:
fromView
),
let
toView
=
transitionContext
.
view
(
forKey
:
.
to
)
{
toView
.
insertSubview
(
fromViewSnapshot
,
at
:
0
)
}
if
isForShow
{
browser
.
maskView
.
alpha
=
0
browser
.
browserView
.
alpha
=
0
if
let
toView
=
transitionContext
.
view
(
forKey
:
.
to
)
{
transitionContext
.
containerView
.
addSubview
(
toView
)
}
}
else
{
if
isNavigationAnimation
,
let
fromView
=
transitionContext
.
view
(
forKey
:
.
from
),
let
toView
=
transitionContext
.
view
(
forKey
:
.
to
)
{
transitionContext
.
containerView
.
insertSubview
(
toView
,
belowSubview
:
fromView
)
}
}
browser
.
browserView
.
isHidden
=
true
UIView
.
animate
(
withDuration
:
transitionDuration
(
using
:
transitionContext
),
animations
:
{
browser
.
browserView
.
isHidden
=
false
browser
.
maskView
.
alpha
=
self
.
isForShow
?
1.0
:
0
browser
.
browserView
.
alpha
=
self
.
isForShow
?
1.0
:
0
})
{
_
in
transitionContext
.
completeTransition
(
!
transitionContext
.
transitionWasCancelled
)
}
}
}
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserImageCell.swift
0 → 100755
View file @
5c1b463a
//
// JXPhotoBrowserImageCell.swift
// JXPhotoBrowser
//
// Created by JiongXing on 2019/11/12.
// Copyright © 2019 JiongXing. All rights reserved.
//
import
UIKit
open
class
JXPhotoBrowserImageCell
:
UIView
,
UIScrollViewDelegate
,
UIGestureRecognizerDelegate
,
JXPhotoBrowserCell
,
JXPhotoBrowserZoomSupportedCell
{
/// 弱引用PhotoBrowser
open
weak
var
photoBrowser
:
JXPhotoBrowser
?
open
var
index
:
Int
=
0
open
var
scrollDirection
:
JXPhotoBrowser
.
ScrollDirection
=
.
horizontal
{
didSet
{
if
scrollDirection
==
.
horizontal
{
addPanGesture
()
}
else
if
let
existed
=
existedPan
{
scrollView
.
removeGestureRecognizer
(
existed
)
}
}
}
open
var
imageView
:
UIImageView
=
{
let
view
=
UIImageView
()
view
.
clipsToBounds
=
true
return
view
}()
open
var
scrollView
:
UIScrollView
=
{
let
view
=
UIScrollView
()
view
.
maximumZoomScale
=
2.0
view
.
showsVerticalScrollIndicator
=
false
view
.
showsHorizontalScrollIndicator
=
false
if
#available(iOS 11.0, *)
{
view
.
contentInsetAdjustmentBehavior
=
.
never
}
return
view
}()
deinit
{
JXPhotoBrowserLog
.
low
(
"deinit -
\(
self
.
classForCoder
)
"
)
}
public
required
override
init
(
frame
:
CGRect
)
{
super
.
init
(
frame
:
frame
)
setup
()
}
public
required
init
?(
coder
:
NSCoder
)
{
super
.
init
(
coder
:
coder
)
setup
()
}
/// 生成实例
public
static
func
generate
(
with
browser
:
JXPhotoBrowser
)
->
Self
{
let
cell
=
Self
.
init
(
frame
:
.
zero
)
cell
.
photoBrowser
=
browser
cell
.
scrollDirection
=
browser
.
scrollDirection
return
cell
}
open
func
setup
()
{
backgroundColor
=
.
clear
scrollView
.
delegate
=
self
addSubview
(
scrollView
)
scrollView
.
addSubview
(
imageView
)
/// 拖动手势
addPanGesture
()
// 双击手势
let
doubleTap
=
UITapGestureRecognizer
(
target
:
self
,
action
:
#selector(
onDoubleTap(_:)
)
)
doubleTap
.
numberOfTapsRequired
=
2
addGestureRecognizer
(
doubleTap
)
// 单击手势
let
singleTap
=
UITapGestureRecognizer
(
target
:
self
,
action
:
#selector(
onSingleTap(_:)
)
)
singleTap
.
require
(
toFail
:
doubleTap
)
addGestureRecognizer
(
singleTap
)
}
// 长按事件
public
typealias
LongPressAction
=
(
JXPhotoBrowserImageCell
,
UILongPressGestureRecognizer
)
->
Void
/// 长按时回调。赋值时自动添加手势,赋值为nil时移除手势
open
var
longPressedAction
:
LongPressAction
?
{
didSet
{
if
oldValue
!=
nil
&&
longPressedAction
==
nil
{
removeGestureRecognizer
(
longPress
)
}
else
if
oldValue
==
nil
&&
longPressedAction
!=
nil
{
addGestureRecognizer
(
longPress
)
}
}
}
/// 已添加的长按手势
private
lazy
var
longPress
:
UILongPressGestureRecognizer
=
{
return
UILongPressGestureRecognizer
(
target
:
self
,
action
:
#selector(
onLongPress(_:)
)
)
}()
private
weak
var
existedPan
:
UIPanGestureRecognizer
?
/// 添加拖动手势
open
func
addPanGesture
()
{
guard
existedPan
==
nil
else
{
return
}
let
pan
=
UIPanGestureRecognizer
(
target
:
self
,
action
:
#selector(
onPan(_:)
)
)
pan
.
delegate
=
self
// 必须加在图片容器上,否则长图下拉不能触发
scrollView
.
addGestureRecognizer
(
pan
)
existedPan
=
pan
}
open
override
func
layoutSubviews
()
{
super
.
layoutSubviews
()
scrollView
.
frame
=
bounds
scrollView
.
setZoomScale
(
1.0
,
animated
:
false
)
let
size
=
computeImageLayoutSize
(
for
:
imageView
.
image
,
in
:
scrollView
)
let
origin
=
computeImageLayoutOrigin
(
for
:
size
,
in
:
scrollView
)
imageView
.
frame
=
CGRect
(
origin
:
origin
,
size
:
size
)
scrollView
.
setZoomScale
(
1.0
,
animated
:
false
)
}
open
func
viewForZooming
(
in
scrollView
:
UIScrollView
)
->
UIView
?
{
return
imageView
}
open
func
scrollViewDidZoom
(
_
scrollView
:
UIScrollView
)
{
imageView
.
center
=
computeImageLayoutCenter
(
in
:
scrollView
)
}
open
func
computeImageLayoutSize
(
for
image
:
UIImage
?,
in
scrollView
:
UIScrollView
)
->
CGSize
{
guard
let
imageSize
=
image
?
.
size
,
imageSize
.
width
>
0
&&
imageSize
.
height
>
0
else
{
return
.
zero
}
var
width
:
CGFloat
var
height
:
CGFloat
let
containerSize
=
scrollView
.
bounds
.
size
if
scrollDirection
==
.
horizontal
{
// 横竖屏判断
if
containerSize
.
width
<
containerSize
.
height
{
width
=
containerSize
.
width
height
=
imageSize
.
height
/
imageSize
.
width
*
width
}
else
{
height
=
containerSize
.
height
width
=
imageSize
.
width
/
imageSize
.
height
*
height
if
width
>
containerSize
.
width
{
width
=
containerSize
.
width
height
=
imageSize
.
height
/
imageSize
.
width
*
width
}
}
}
else
{
width
=
containerSize
.
width
height
=
imageSize
.
height
/
imageSize
.
width
*
width
if
height
>
containerSize
.
height
{
height
=
containerSize
.
height
width
=
imageSize
.
width
/
imageSize
.
height
*
height
}
}
return
CGSize
(
width
:
width
,
height
:
height
)
}
open
func
computeImageLayoutOrigin
(
for
imageSize
:
CGSize
,
in
scrollView
:
UIScrollView
)
->
CGPoint
{
let
containerSize
=
scrollView
.
bounds
.
size
var
y
=
(
containerSize
.
height
-
imageSize
.
height
)
*
0.5
y
=
max
(
0
,
y
)
var
x
=
(
containerSize
.
width
-
imageSize
.
width
)
*
0.5
x
=
max
(
0
,
x
)
return
CGPoint
(
x
:
x
,
y
:
y
)
}
open
func
computeImageLayoutCenter
(
in
scrollView
:
UIScrollView
)
->
CGPoint
{
var
x
=
scrollView
.
contentSize
.
width
*
0.5
var
y
=
scrollView
.
contentSize
.
height
*
0.5
let
offsetX
=
(
bounds
.
width
-
scrollView
.
contentSize
.
width
)
*
0.5
if
offsetX
>
0
{
x
+=
offsetX
}
let
offsetY
=
(
bounds
.
height
-
scrollView
.
contentSize
.
height
)
*
0.5
if
offsetY
>
0
{
y
+=
offsetY
}
return
CGPoint
(
x
:
x
,
y
:
y
)
}
/// 单击
@objc
open
func
onSingleTap
(
_
tap
:
UITapGestureRecognizer
)
{
photoBrowser
?
.
dismiss
()
}
/// 双击
@objc
open
func
onDoubleTap
(
_
tap
:
UITapGestureRecognizer
)
{
// 如果当前没有任何缩放,则放大到目标比例,否则重置到原比例
if
scrollView
.
zoomScale
<
1.1
{
// 以点击的位置为中心,放大
let
pointInView
=
tap
.
location
(
in
:
imageView
)
let
width
=
scrollView
.
bounds
.
size
.
width
/
scrollView
.
maximumZoomScale
let
height
=
scrollView
.
bounds
.
size
.
height
/
scrollView
.
maximumZoomScale
let
x
=
pointInView
.
x
-
(
width
/
2.0
)
let
y
=
pointInView
.
y
-
(
height
/
2.0
)
scrollView
.
zoom
(
to
:
CGRect
(
x
:
x
,
y
:
y
,
width
:
width
,
height
:
height
),
animated
:
true
)
}
else
{
scrollView
.
setZoomScale
(
1.0
,
animated
:
true
)
}
}
/// 长按
@objc
open
func
onLongPress
(
_
press
:
UILongPressGestureRecognizer
)
{
if
press
.
state
==
.
began
{
longPressedAction
?(
self
,
press
)
}
}
/// 记录pan手势开始时imageView的位置
private
var
beganFrame
=
CGRect
.
zero
/// 记录pan手势开始时,手势位置
private
var
beganTouch
=
CGPoint
.
zero
/// 响应拖动
@objc
open
func
onPan
(
_
pan
:
UIPanGestureRecognizer
)
{
guard
imageView
.
image
!=
nil
else
{
return
}
switch
pan
.
state
{
case
.
began
:
beganFrame
=
imageView
.
frame
beganTouch
=
pan
.
location
(
in
:
scrollView
)
case
.
changed
:
let
result
=
panResult
(
pan
)
imageView
.
frame
=
result
.
frame
photoBrowser
?
.
maskView
.
alpha
=
result
.
scale
*
result
.
scale
photoBrowser
?
.
setStatusBar
(
hidden
:
result
.
scale
>
0.99
)
photoBrowser
?
.
pageIndicator
?
.
isHidden
=
result
.
scale
<
0.99
case
.
ended
,
.
cancelled
:
imageView
.
frame
=
panResult
(
pan
)
.
frame
let
isDown
=
pan
.
velocity
(
in
:
self
)
.
y
>
0
if
isDown
{
photoBrowser
?
.
dismiss
()
}
else
{
photoBrowser
?
.
maskView
.
alpha
=
1.0
photoBrowser
?
.
setStatusBar
(
hidden
:
true
)
photoBrowser
?
.
pageIndicator
?
.
isHidden
=
false
resetImageViewPosition
()
}
default
:
resetImageViewPosition
()
}
}
/// 计算拖动时图片应调整的frame和scale值
private
func
panResult
(
_
pan
:
UIPanGestureRecognizer
)
->
(
frame
:
CGRect
,
scale
:
CGFloat
)
{
// 拖动偏移量
let
translation
=
pan
.
translation
(
in
:
scrollView
)
let
currentTouch
=
pan
.
location
(
in
:
scrollView
)
// 由下拉的偏移值决定缩放比例,越往下偏移,缩得越小。scale值区间[0.3, 1.0]
let
scale
=
min
(
1.0
,
max
(
0.3
,
1
-
translation
.
y
/
bounds
.
height
))
let
width
=
beganFrame
.
size
.
width
*
scale
let
height
=
beganFrame
.
size
.
height
*
scale
// 计算x和y。保持手指在图片上的相对位置不变。
// 即如果手势开始时,手指在图片X轴三分之一处,那么在移动图片时,保持手指始终位于图片X轴的三分之一处
let
xRate
=
(
beganTouch
.
x
-
beganFrame
.
origin
.
x
)
/
beganFrame
.
size
.
width
let
currentTouchDeltaX
=
xRate
*
width
let
x
=
currentTouch
.
x
-
currentTouchDeltaX
let
yRate
=
(
beganTouch
.
y
-
beganFrame
.
origin
.
y
)
/
beganFrame
.
size
.
height
let
currentTouchDeltaY
=
yRate
*
height
let
y
=
currentTouch
.
y
-
currentTouchDeltaY
return
(
CGRect
(
x
:
x
.
isNaN
?
0
:
x
,
y
:
y
.
isNaN
?
0
:
y
,
width
:
width
,
height
:
height
),
scale
)
}
/// 复位ImageView
private
func
resetImageViewPosition
()
{
// 如果图片当前显示的size小于原size,则重置为原size
let
size
=
computeImageLayoutSize
(
for
:
imageView
.
image
,
in
:
scrollView
)
let
needResetSize
=
imageView
.
bounds
.
size
.
width
<
size
.
width
||
imageView
.
bounds
.
size
.
height
<
size
.
height
UIView
.
animate
(
withDuration
:
0.25
)
{
self
.
imageView
.
center
=
self
.
computeImageLayoutCenter
(
in
:
self
.
scrollView
)
if
needResetSize
{
self
.
imageView
.
bounds
.
size
=
size
}
}
}
open
override
func
gestureRecognizerShouldBegin
(
_
gestureRecognizer
:
UIGestureRecognizer
)
->
Bool
{
// 只处理pan手势
guard
let
pan
=
gestureRecognizer
as?
UIPanGestureRecognizer
else
{
return
true
}
let
velocity
=
pan
.
velocity
(
in
:
self
)
// 向上滑动时,不响应手势
if
velocity
.
y
<
0
{
return
false
}
// 横向滑动时,不响应pan手势
if
abs
(
Int
(
velocity
.
x
))
>
Int
(
velocity
.
y
)
{
return
false
}
// 向下滑动,如果图片顶部超出可视区域,不响应手势
if
scrollView
.
contentOffset
.
y
>
0
{
return
false
}
// 响应允许范围内的下滑手势
return
true
}
open
var
showContentView
:
UIView
{
return
imageView
}
}
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserLog.swift
0 → 100755
View file @
5c1b463a
//
// JXPhotoBrowserLog.swift
// JXPhotoBrowser
//
// Created by JiongXing on 2019/11/12.
// Copyright © 2019 JiongXing. All rights reserved.
//
import
Foundation
public
struct
JXPhotoBrowserLog
{
/// 日志重要程度等级
public
enum
Level
:
Int
{
case
low
=
0
case
middle
case
high
case
forbidden
}
/// 允许输出日志的最低等级。`forbidden`为禁止所有日志
public
static
var
level
:
Level
=
.
forbidden
public
static
func
low
(
_
item
:
@autoclosure
()
->
Any
)
{
if
level
.
rawValue
<=
Level
.
low
.
rawValue
{
print
(
"[JXPhotoBrowser] [low]"
,
item
())
}
}
public
static
func
middle
(
_
item
:
@autoclosure
()
->
Any
)
{
if
level
.
rawValue
<=
Level
.
middle
.
rawValue
{
print
(
"[JXPhotoBrowser] [middle]"
,
item
())
}
}
public
static
func
high
(
_
item
:
@autoclosure
()
->
Any
)
{
if
level
.
rawValue
<=
Level
.
high
.
rawValue
{
print
(
"[JXPhotoBrowser] [high]"
,
item
())
}
}
}
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserNoneAnimator.swift
0 → 100755
View file @
5c1b463a
//
// JXPhotoBrowserNoneAnimator.swift
// JXPhotoBrowser
//
// Created by JiongXing on 2019/11/26.
// Copyright © 2019 JiongXing. All rights reserved.
//
import
UIKit
/// 使用本类以实现不出现转场动画的需求
open
class
JXPhotoBrowserNoneAnimator
:
JXPhotoBrowserFadeAnimator
{
public
override
init
()
{
super
.
init
()
showDuration
=
0
dismissDuration
=
0
}
}
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserNumberPageIndicator.swift
0 → 100755
View file @
5c1b463a
//
// JXPhotoBrowserNumberPageIndicator.swift
// JXPhotoBrowser
//
// Created by JiongXing on 2019/11/25.
// Copyright © 2019 JiongXing. All rights reserved.
//
import
UIKit
open
class
JXPhotoBrowserNumberPageIndicator
:
UILabel
,
JXPhotoBrowserPageIndicator
{
/// 页码与顶部的距离
open
lazy
var
topPadding
:
CGFloat
=
{
if
#available(iOS 11.0, *)
,
let
window
=
UIApplication
.
shared
.
keyWindow
{
return
window
.
safeAreaInsets
.
top
}
return
20
}()
public
convenience
init
()
{
self
.
init
(
frame
:
.
zero
)
}
public
override
init
(
frame
:
CGRect
)
{
super
.
init
(
frame
:
frame
)
config
()
}
required
public
init
?(
coder
:
NSCoder
)
{
super
.
init
(
coder
:
coder
)
config
()
}
private
func
config
()
{
font
=
UIFont
.
systemFont
(
ofSize
:
17
)
textAlignment
=
.
center
textColor
=
UIColor
.
white
backgroundColor
=
UIColor
(
red
:
0
,
green
:
0
,
blue
:
0
,
alpha
:
0.4
)
layer
.
masksToBounds
=
true
}
public
func
setup
(
with
browser
:
JXPhotoBrowser
)
{
}
private
var
total
:
Int
=
0
public
func
reloadData
(
numberOfItems
:
Int
,
pageIndex
:
Int
)
{
total
=
numberOfItems
text
=
"
\(
pageIndex
+
1
)
/
\(
total
)
"
sizeToFit
()
frame
.
size
.
width
+=
frame
.
height
layer
.
cornerRadius
=
frame
.
height
/
2
if
let
view
=
superview
{
center
.
x
=
view
.
bounds
.
width
/
2
frame
.
origin
.
y
=
topPadding
}
isHidden
=
numberOfItems
<=
1
}
public
func
didChanged
(
pageIndex
:
Int
)
{
text
=
"
\(
pageIndex
+
1
)
/
\(
total
)
"
}
}
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserPageIndicator.swift
0 → 100755
View file @
5c1b463a
//
// JXPhotoBrowserPageIndicator.swift
// JXPhotoBrowser
//
// Created by JiongXing on 2019/11/25.
// Copyright © 2019 JiongXing. All rights reserved.
//
import
UIKit
public
protocol
JXPhotoBrowserPageIndicator
:
UIView
{
func
setup
(
with
browser
:
JXPhotoBrowser
)
func
reloadData
(
numberOfItems
:
Int
,
pageIndex
:
Int
)
func
didChanged
(
pageIndex
:
Int
)
}
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserSmoothZoomAnimator.swift
0 → 100755
View file @
5c1b463a
//
// JXPhotoBrowserSmoothZoomAnimator.swift
// JXPhotoBrowser
//
// Created by JiongXing on 2019/11/26.
// Copyright © 2019 JiongXing. All rights reserved.
//
import
UIKit
/// 更丝滑的Zoom动画
open
class
JXPhotoBrowserSmoothZoomAnimator
:
NSObject
,
JXPhotoBrowserAnimatedTransitioning
{
open
var
showDuration
:
TimeInterval
=
0.25
open
var
dismissDuration
:
TimeInterval
=
0.25
open
var
isNavigationAnimation
=
false
public
typealias
TransitionViewAndFrame
=
(
transitionView
:
UIView
,
thumbnailFrame
:
CGRect
)
public
typealias
TransitionViewAndFrameProvider
=
(
_
index
:
Int
,
_
destinationView
:
UIView
)
->
TransitionViewAndFrame
?
/// 获取转场缩放的视图与前置Frame
open
var
transitionViewAndFrameProvider
:
TransitionViewAndFrameProvider
=
{
_
,
_
in
return
nil
}
/// 替补的动画方案
open
lazy
var
substituteAnimator
:
JXPhotoBrowserAnimatedTransitioning
=
JXPhotoBrowserFadeAnimator
()
public
init
(
transitionViewAndFrame
:
@escaping
TransitionViewAndFrameProvider
)
{
transitionViewAndFrameProvider
=
transitionViewAndFrame
}
public
func
transitionDuration
(
using
transitionContext
:
UIViewControllerContextTransitioning
?)
->
TimeInterval
{
return
isForShow
?
showDuration
:
dismissDuration
}
public
func
animateTransition
(
using
transitionContext
:
UIViewControllerContextTransitioning
)
{
if
isForShow
{
playShowAnimation
(
context
:
transitionContext
)
}
else
{
playDismissAnimation
(
context
:
transitionContext
)
}
}
private
func
playShowAnimation
(
context
:
UIViewControllerContextTransitioning
)
{
guard
let
browser
=
photoBrowser
else
{
context
.
completeTransition
(
!
context
.
transitionWasCancelled
)
return
}
if
isNavigationAnimation
,
let
fromView
=
context
.
view
(
forKey
:
.
from
),
let
fromViewSnapshot
=
snapshot
(
with
:
fromView
),
let
toView
=
context
.
view
(
forKey
:
.
to
)
{
toView
.
insertSubview
(
fromViewSnapshot
,
at
:
0
)
}
context
.
containerView
.
addSubview
(
browser
.
view
)
guard
let
(
transitionView
,
thumbnailFrame
,
destinationFrame
)
=
transitionViewAndFrames
(
with
:
browser
)
else
{
// 转为执行替补动画
substituteAnimator
.
isForShow
=
isForShow
substituteAnimator
.
photoBrowser
=
photoBrowser
substituteAnimator
.
isNavigationAnimation
=
isNavigationAnimation
substituteAnimator
.
animateTransition
(
using
:
context
)
return
}
browser
.
maskView
.
alpha
=
0
browser
.
browserView
.
isHidden
=
true
transitionView
.
frame
=
thumbnailFrame
context
.
containerView
.
addSubview
(
transitionView
)
UIView
.
animate
(
withDuration
:
showDuration
,
animations
:
{
browser
.
maskView
.
alpha
=
1.0
transitionView
.
frame
=
destinationFrame
})
{
_
in
browser
.
browserView
.
isHidden
=
false
browser
.
view
.
insertSubview
(
browser
.
maskView
,
belowSubview
:
browser
.
browserView
)
transitionView
.
removeFromSuperview
()
context
.
completeTransition
(
!
context
.
transitionWasCancelled
)
}
}
private
func
playDismissAnimation
(
context
:
UIViewControllerContextTransitioning
)
{
guard
let
browser
=
photoBrowser
else
{
return
}
guard
let
(
transitionView
,
thumbnailFrame
,
destinationFrame
)
=
transitionViewAndFrames
(
with
:
browser
)
else
{
// 转为执行替补动画
substituteAnimator
.
isForShow
=
isForShow
substituteAnimator
.
photoBrowser
=
photoBrowser
substituteAnimator
.
isNavigationAnimation
=
isNavigationAnimation
substituteAnimator
.
animateTransition
(
using
:
context
)
return
}
browser
.
browserView
.
isHidden
=
true
transitionView
.
frame
=
destinationFrame
context
.
containerView
.
addSubview
(
transitionView
)
UIView
.
animate
(
withDuration
:
showDuration
,
animations
:
{
browser
.
maskView
.
alpha
=
0
transitionView
.
frame
=
thumbnailFrame
})
{
_
in
if
let
toView
=
context
.
view
(
forKey
:
.
to
)
{
context
.
containerView
.
addSubview
(
toView
)
}
transitionView
.
removeFromSuperview
()
context
.
completeTransition
(
!
context
.
transitionWasCancelled
)
}
}
private
func
transitionViewAndFrames
(
with
browser
:
JXPhotoBrowser
)
->
(
UIView
,
CGRect
,
CGRect
)?
{
let
browserView
=
browser
.
browserView
let
destinationView
=
browser
.
view
!
guard
let
transitionContext
=
transitionViewAndFrameProvider
(
browser
.
pageIndex
,
destinationView
)
else
{
return
nil
}
guard
let
cell
=
browserView
.
visibleCells
[
browserView
.
pageIndex
]
as?
JXPhotoBrowserZoomSupportedCell
else
{
return
nil
}
let
showContentView
=
cell
.
showContentView
let
destinationFrame
=
showContentView
.
convert
(
showContentView
.
bounds
,
to
:
destinationView
)
return
(
transitionContext
.
transitionView
,
transitionContext
.
thumbnailFrame
,
destinationFrame
)
}
}
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserView.swift
0 → 100755
View file @
5c1b463a
//
// JXPhotoBrowserView.swift
// JXPhotoBrowser
//
// Created by JiongXing on 2019/11/14.
// Copyright © 2019 JiongXing. All rights reserved.
//
import
UIKit
open
class
JXPhotoBrowserView
:
UIView
,
UIScrollViewDelegate
{
/// 弱引用PhotoBrowser
open
weak
var
photoBrowser
:
JXPhotoBrowser
?
/// 询问当前数据总量
open
lazy
var
numberOfItems
:
()
->
Int
=
{
0
}
/// 返回可复用的Cell类。用户可根据index返回不同的类。本闭包将在每次复用Cell时实时调用。
open
lazy
var
cellClassAtIndex
:
(
_
index
:
Int
)
->
JXPhotoBrowserCell
.
Type
=
{
_
in
JXPhotoBrowserImageCell
.
self
}
/// 刷新Cell数据。本闭包将在Cell完成位置布局后调用。
open
lazy
var
reloadCellAtIndex
:
(
JXPhotoBrowser
.
ReloadCellContext
)
->
Void
=
{
_
in
}
/// 自然滑动引起的页码改变时回调
open
lazy
var
didChangedPageIndex
:
(
_
index
:
Int
)
->
Void
=
{
_
in
}
/// Cell将显示
open
lazy
var
cellWillAppear
:
(
JXPhotoBrowserCell
,
Int
)
->
Void
=
{
_
,
_
in
}
/// Cell将不显示
open
lazy
var
cellWillDisappear
:
(
JXPhotoBrowserCell
,
Int
)
->
Void
=
{
_
,
_
in
}
/// Cell已显示
open
lazy
var
cellDidAppear
:
(
JXPhotoBrowserCell
,
Int
)
->
Void
=
{
_
,
_
in
}
/// 滑动方向
open
var
scrollDirection
:
JXPhotoBrowser
.
ScrollDirection
=
.
horizontal
/// 项间距
open
var
itemSpacing
:
CGFloat
=
30
/// 当前页码。给本属性赋值不会触发`didChangedPageIndex`闭包。
open
var
pageIndex
=
0
{
didSet
{
if
pageIndex
!=
oldValue
{
isPageIndexChanged
=
true
}
}
}
/// 页码是否已改变
public
var
isPageIndexChanged
=
true
/// 容器
open
lazy
var
scrollView
:
UIScrollView
=
{
let
sv
=
UIScrollView
()
sv
.
backgroundColor
=
.
clear
sv
.
showsVerticalScrollIndicator
=
false
sv
.
showsHorizontalScrollIndicator
=
false
sv
.
isPagingEnabled
=
true
sv
.
isScrollEnabled
=
true
sv
.
delegate
=
self
if
#available(iOS 11.0, *)
{
sv
.
contentInsetAdjustmentBehavior
=
.
never
}
return
sv
}()
var
isRotating
=
false
deinit
{
JXPhotoBrowserLog
.
low
(
"deinit -
\(
self
.
classForCoder
)
"
)
}
public
convenience
init
()
{
self
.
init
(
frame
:
.
zero
)
}
public
override
init
(
frame
:
CGRect
)
{
super
.
init
(
frame
:
frame
)
setup
()
}
public
required
init
?(
coder
:
NSCoder
)
{
super
.
init
(
coder
:
coder
)
setup
()
}
open
func
setup
()
{
backgroundColor
=
.
clear
addSubview
(
scrollView
)
}
open
override
func
layoutSubviews
()
{
super
.
layoutSubviews
()
if
scrollDirection
==
.
horizontal
{
scrollView
.
frame
=
CGRect
(
x
:
0
,
y
:
0
,
width
:
bounds
.
width
+
itemSpacing
,
height
:
bounds
.
height
)
}
else
{
scrollView
.
frame
=
CGRect
(
x
:
0
,
y
:
0
,
width
:
bounds
.
width
,
height
:
bounds
.
height
+
itemSpacing
)
}
reloadData
()
}
open
func
resetContentSize
()
{
let
maxIndex
=
CGFloat
(
numberOfItems
())
if
scrollDirection
==
.
horizontal
{
scrollView
.
contentSize
=
CGSize
(
width
:
scrollView
.
frame
.
width
*
maxIndex
,
height
:
scrollView
.
frame
.
height
)
}
else
{
scrollView
.
contentSize
=
CGSize
(
width
:
scrollView
.
frame
.
width
,
height
:
scrollView
.
frame
.
height
*
maxIndex
)
}
}
/// 刷新数据,同时刷新Cell布局
open
func
reloadData
()
{
// 修正pageIndex,同步数据源的变更
pageIndex
=
max
(
0
,
pageIndex
)
pageIndex
=
min
(
pageIndex
,
numberOfItems
())
resetContentSize
()
resetCells
()
layoutCells
()
reloadItems
()
refreshContentOffset
()
}
/// 根据页码更新滑动位置
open
func
refreshContentOffset
()
{
if
scrollDirection
==
.
horizontal
{
scrollView
.
contentOffset
=
CGPoint
(
x
:
CGFloat
(
pageIndex
)
*
scrollView
.
bounds
.
width
,
y
:
0
)
}
else
{
scrollView
.
contentOffset
=
CGPoint
(
x
:
0
,
y
:
CGFloat
(
pageIndex
)
*
scrollView
.
bounds
.
height
)
}
}
open
func
scrollViewDidScroll
(
_
scrollView
:
UIScrollView
)
{
// 屏幕旋转时会触发本方法。此时不可更改pageIndex
if
isRotating
{
isRotating
=
false
return
}
if
scrollDirection
==
.
horizontal
&&
scrollView
.
bounds
.
width
>
0
{
pageIndex
=
Int
(
round
(
scrollView
.
contentOffset
.
x
/
(
scrollView
.
bounds
.
width
)))
}
else
if
scrollDirection
==
.
vertical
&&
scrollView
.
bounds
.
height
>
0
{
pageIndex
=
Int
(
round
(
scrollView
.
contentOffset
.
y
/
(
scrollView
.
bounds
.
height
)))
}
if
isPageIndexChanged
{
isPageIndexChanged
=
false
resetCells
()
layoutCells
()
reloadItems
()
didChangedPageIndex
(
pageIndex
)
}
}
public
func
scrollViewDidEndDecelerating
(
_
scrollView
:
UIScrollView
)
{
if
let
cell
=
visibleCells
[
pageIndex
]
{
cellDidAppear
(
cell
,
pageIndex
)
}
}
//
// MARK: - 复用Cell
//
/// 显示中的Cell
open
var
visibleCells
=
[
Int
:
JXPhotoBrowserCell
]()
/// 缓存中的Cell
open
var
reusableCells
=
[
String
:
[
JXPhotoBrowserCell
]]()
/// 入队
private
func
enqueue
(
cell
:
JXPhotoBrowserCell
)
{
let
name
=
String
(
describing
:
cell
.
classForCoder
)
if
var
array
=
reusableCells
[
name
]
{
array
.
append
(
cell
)
reusableCells
[
name
]
=
array
}
else
{
reusableCells
[
name
]
=
[
cell
]
}
}
/// 出队,没缓存则新建
private
func
dequeue
(
cellType
:
JXPhotoBrowserCell
.
Type
,
browser
:
JXPhotoBrowser
)
->
JXPhotoBrowserCell
{
var
cell
:
JXPhotoBrowserCell
let
name
=
String
(
describing
:
cellType
.
classForCoder
())
if
var
array
=
reusableCells
[
name
],
array
.
count
>
0
{
JXPhotoBrowserLog
.
middle
(
"命中缓存!
\(
name
)
"
)
cell
=
array
.
removeFirst
()
reusableCells
[
name
]
=
array
}
else
{
JXPhotoBrowserLog
.
middle
(
"新建Cell!
\(
name
)
"
)
cell
=
cellType
.
generate
(
with
:
browser
)
}
return
cell
}
/// 重置所有Cell的位置。更新 visibleCells 和 reusableCells
open
func
resetCells
()
{
guard
let
browser
=
photoBrowser
else
{
return
}
var
removeFromVisibles
=
[
Int
]()
for
(
index
,
cell
)
in
visibleCells
{
if
index
==
pageIndex
{
continue
}
cellWillDisappear
(
cell
,
index
)
cell
.
removeFromSuperview
()
enqueue
(
cell
:
cell
)
removeFromVisibles
.
append
(
index
)
}
removeFromVisibles
.
forEach
{
visibleCells
.
removeValue
(
forKey
:
$0
)
}
// 添加要显示的cell
let
itemsTotalCount
=
numberOfItems
()
for
index
in
(
pageIndex
-
1
)
...
(
pageIndex
+
1
)
{
if
index
<
0
||
index
>
itemsTotalCount
-
1
{
continue
}
if
index
==
pageIndex
&&
visibleCells
[
index
]
!=
nil
{
continue
}
let
clazz
=
cellClassAtIndex
(
index
)
JXPhotoBrowserLog
.
middle
(
"Required class name:
\(
String
(
describing
:
clazz
)
)
"
)
JXPhotoBrowserLog
.
middle
(
"index:
\(
index
)
出队!"
)
let
cell
=
dequeue
(
cellType
:
clazz
,
browser
:
browser
)
visibleCells
[
index
]
=
cell
scrollView
.
addSubview
(
cell
)
}
}
/// 刷新所有显示中的Cell位置
open
func
layoutCells
()
{
let
cellWidth
=
bounds
.
width
let
cellHeight
=
bounds
.
height
for
(
index
,
cell
)
in
visibleCells
{
if
scrollDirection
==
.
horizontal
{
cell
.
frame
=
CGRect
(
x
:
CGFloat
(
index
)
*
(
cellWidth
+
itemSpacing
),
y
:
0
,
width
:
cellWidth
,
height
:
cellHeight
)
}
else
{
cell
.
frame
=
CGRect
(
x
:
0
,
y
:
CGFloat
(
index
)
*
(
cellHeight
+
itemSpacing
),
width
:
cellWidth
,
height
:
cellHeight
)
}
}
}
/// 刷新所有Cell的数据
open
func
reloadItems
()
{
visibleCells
.
forEach
{
[
weak
self
]
index
,
cell
in
guard
let
`
self
`
=
self
else
{
return
}
self
.
reloadCellAtIndex
((
cell
,
index
,
self
.
pageIndex
))
cell
.
setNeedsLayout
()
}
if
let
cell
=
visibleCells
[
pageIndex
]
{
cellWillAppear
(
cell
,
pageIndex
)
}
}
}
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserZoomAnimator.swift
0 → 100755
View file @
5c1b463a
//
// JXPhotoBrowserZoomAnimator.swift
// JXPhotoBrowser
//
// Created by JiongXing on 2019/11/26.
// Copyright © 2019 JiongXing. All rights reserved.
//
import
UIKit
/// Zoom动画
open
class
JXPhotoBrowserZoomAnimator
:
NSObject
,
JXPhotoBrowserAnimatedTransitioning
{
open
var
showDuration
:
TimeInterval
=
0.25
open
var
dismissDuration
:
TimeInterval
=
0.25
open
var
isNavigationAnimation
=
false
public
typealias
PreviousViewAtIndexClosure
=
(
_
index
:
Int
)
->
UIView
?
/// 转场动画的前向视图
open
var
previousViewProvider
:
PreviousViewAtIndexClosure
=
{
_
in
return
nil
}
/// 替补的动画方案
open
lazy
var
substituteAnimator
:
JXPhotoBrowserAnimatedTransitioning
=
JXPhotoBrowserFadeAnimator
()
public
init
(
previousView
:
@escaping
PreviousViewAtIndexClosure
)
{
previousViewProvider
=
previousView
}
public
func
transitionDuration
(
using
transitionContext
:
UIViewControllerContextTransitioning
?)
->
TimeInterval
{
return
isForShow
?
showDuration
:
dismissDuration
}
public
func
animateTransition
(
using
transitionContext
:
UIViewControllerContextTransitioning
)
{
if
isForShow
{
playShowAnimation
(
context
:
transitionContext
)
}
else
{
playDismissAnimation
(
context
:
transitionContext
)
}
}
private
func
playShowAnimation
(
context
:
UIViewControllerContextTransitioning
)
{
guard
let
browser
=
photoBrowser
else
{
context
.
completeTransition
(
!
context
.
transitionWasCancelled
)
return
}
if
isNavigationAnimation
,
let
fromView
=
context
.
view
(
forKey
:
.
from
),
let
fromViewSnapshot
=
snapshot
(
with
:
fromView
),
let
toView
=
context
.
view
(
forKey
:
.
to
)
{
toView
.
insertSubview
(
fromViewSnapshot
,
at
:
0
)
}
context
.
containerView
.
addSubview
(
browser
.
view
)
guard
let
(
snap1
,
snap2
,
thumbnailFrame
,
destinationFrame
)
=
snapshotsAndFrames
(
browser
:
browser
)
else
{
// 转为执行替补动画
substituteAnimator
.
isForShow
=
isForShow
substituteAnimator
.
photoBrowser
=
photoBrowser
substituteAnimator
.
isNavigationAnimation
=
isNavigationAnimation
substituteAnimator
.
animateTransition
(
using
:
context
)
return
}
snap1
.
frame
=
thumbnailFrame
snap2
.
frame
=
thumbnailFrame
snap2
.
alpha
=
0
browser
.
maskView
.
alpha
=
0
browser
.
browserView
.
isHidden
=
true
context
.
containerView
.
addSubview
(
snap1
)
context
.
containerView
.
addSubview
(
snap2
)
UIView
.
animate
(
withDuration
:
showDuration
,
animations
:
{
browser
.
maskView
.
alpha
=
1.0
snap1
.
frame
=
destinationFrame
snap1
.
alpha
=
0
snap2
.
frame
=
destinationFrame
snap2
.
alpha
=
1.0
})
{
_
in
browser
.
browserView
.
isHidden
=
false
browser
.
view
.
insertSubview
(
browser
.
maskView
,
belowSubview
:
browser
.
browserView
)
snap1
.
removeFromSuperview
()
snap2
.
removeFromSuperview
()
context
.
completeTransition
(
!
context
.
transitionWasCancelled
)
}
}
private
func
playDismissAnimation
(
context
:
UIViewControllerContextTransitioning
)
{
guard
let
browser
=
photoBrowser
else
{
return
}
guard
let
(
snap1
,
snap2
,
thumbnailFrame
,
destinationFrame
)
=
snapshotsAndFrames
(
browser
:
browser
)
else
{
// 转为执行替补动画
substituteAnimator
.
isForShow
=
isForShow
substituteAnimator
.
photoBrowser
=
photoBrowser
substituteAnimator
.
isNavigationAnimation
=
isNavigationAnimation
substituteAnimator
.
animateTransition
(
using
:
context
)
return
}
snap1
.
frame
=
destinationFrame
snap1
.
alpha
=
0
snap2
.
frame
=
destinationFrame
context
.
containerView
.
addSubview
(
snap1
)
context
.
containerView
.
addSubview
(
snap2
)
browser
.
browserView
.
isHidden
=
true
UIView
.
animate
(
withDuration
:
showDuration
,
animations
:
{
browser
.
maskView
.
alpha
=
0
snap1
.
frame
=
thumbnailFrame
snap1
.
alpha
=
0
snap2
.
frame
=
thumbnailFrame
snap2
.
alpha
=
1.0
})
{
_
in
if
let
toView
=
context
.
view
(
forKey
:
.
to
)
{
context
.
containerView
.
addSubview
(
toView
)
}
snap1
.
removeFromSuperview
()
snap2
.
removeFromSuperview
()
context
.
completeTransition
(
!
context
.
transitionWasCancelled
)
}
}
private
func
snapshotsAndFrames
(
browser
:
JXPhotoBrowser
)
->
(
UIView
,
UIView
,
CGRect
,
CGRect
)?
{
let
browserView
=
browser
.
browserView
let
view
=
browser
.
view
let
closure
=
previousViewProvider
guard
let
previousView
=
closure
(
browserView
.
pageIndex
)
else
{
return
nil
}
guard
let
cell
=
browserView
.
visibleCells
[
browserView
.
pageIndex
]
as?
JXPhotoBrowserZoomSupportedCell
else
{
return
nil
}
let
thumbnailFrame
=
previousView
.
convert
(
previousView
.
bounds
,
to
:
view
)
let
showContentView
=
cell
.
showContentView
// 两Rect求交集,得出显示中的区域
let
destinationFrame
=
cell
.
convert
(
cell
.
bounds
.
intersection
(
showContentView
.
frame
),
to
:
view
)
guard
let
snap1
=
fastSnapshot
(
with
:
previousView
)
else
{
JXPhotoBrowserLog
.
high
(
"取不到前截图!"
)
return
nil
}
guard
let
snap2
=
snapshot
(
with
:
cell
.
showContentView
)
else
{
JXPhotoBrowserLog
.
high
(
"取不到后截图!"
)
return
nil
}
return
(
snap1
,
snap2
,
thumbnailFrame
,
destinationFrame
)
}
}
GeliBusinessPlatform/Other/JXPhotoBrowser/JXPhotoBrowserZoomSupportedCell.swift
0 → 100755
View file @
5c1b463a
//
// JXPhotoBrowserZoomSupportedCell.swift
// JXPhotoBrowser
//
// Created by JiongXing on 2019/11/22.
// Copyright © 2019 JiongXing. All rights reserved.
//
import
UIKit
/// 在Zoom转场时使用
protocol
JXPhotoBrowserZoomSupportedCell
:
UIView
{
/// 内容视图
var
showContentView
:
UIView
{
get
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment