Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
E
em_call
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Дмитрий Гребенников
em_call
Commits
27f01c03
Commit
27f01c03
authored
Mar 13, 2022
by
Дмитрий Гребенников
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
13.03.2022
13.03.2022
parent
43b3435e
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
1655 additions
and
383 deletions
+1655
-383
project.pbxproj
Em-call.xcodeproj/project.pbxproj
+72
-12
Breakpoints_v2.xcbkptlist
...a/alexsh.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
+8
-8
Breakpoints_v2.xcbkptlist
...a/alexsh.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
+82
-34
Main.storyboard
Em-call/Base.lproj/Main.storyboard
+113
-103
CollectionCell.swift
Em-call/CollectionCell/CollectionCell.swift
+14
-0
CollectionCell.xib
Em-call/CollectionCell/CollectionCell.xib
+31
-0
Extensions.swift
Em-call/Data/Extensions.swift
+0
-3
SettingCell.swift
Em-call/Data/SettingCell.swift
+0
-3
SettingsLauncher.swift
Em-call/Data/SettingsLauncher.swift
+1
-0
Collection.swift
Em-call/Extensions/Collection.swift
+14
-0
FileManager.swift
Em-call/Extensions/FileManager.swift
+32
-0
GlidingCollection.swift
Em-call/GlidingCollection.swift
+749
-0
GlidingConfig.swift
Em-call/GlidingConfig.swift
+46
-0
GlidingLayout.swift
Em-call/GlidingLayout.swift
+73
-0
GlidingCollectionDataSource.swift
Em-call/Protocols/GlidingCollectionDataSource.swift
+25
-0
GlidingCollectionDelegate.swift
Em-call/Protocols/GlidingCollectionDelegate.swift
+47
-0
ElectricTableViewController.swift
Em-call/VC/ElectricTableViewController.swift
+123
-80
HandmanViewController.swift
Em-call/VC/HandmanViewController.swift
+113
-12
PlumbersViewController.swift
Em-call/VC/PlumbersViewController.swift
+74
-124
StartNavigationVCViewController.swift
Em-call/VC/StartNavigationVCViewController.swift
+29
-0
StartViewController.swift
Em-call/VC/StartViewController.swift
+9
-4
No files found.
Em-call.xcodeproj/project.pbxproj
View file @
27f01c03
...
...
@@ -18,6 +18,15 @@
D51D340227BF98B9008D5065
/* CalendarViewController.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D51D340127BF98B9008D5065
/* CalendarViewController.swift */
;
};
D558EA5C27BE4A6C003C4578
/* HandmanViewController.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D558EA5B27BE4A6C003C4578
/* HandmanViewController.swift */
;
};
D558EA6127BE4C65003C4578
/* EmerHandViewController.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D558EA6027BE4C65003C4578
/* EmerHandViewController.swift */
;
};
D55E88F327DE124B00DB59E7
/* GlidingCollection.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D55E88E727DE124A00DB59E7
/* GlidingCollection.swift */
;
};
D55E88F427DE124B00DB59E7
/* CollectionCell.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D55E88E927DE124A00DB59E7
/* CollectionCell.swift */
;
};
D55E88F527DE124B00DB59E7
/* CollectionCell.xib in Resources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D55E88EA27DE124A00DB59E7
/* CollectionCell.xib */
;
};
D55E88F627DE124B00DB59E7
/* GlidingLayout.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D55E88EB27DE124B00DB59E7
/* GlidingLayout.swift */
;
};
D55E88F727DE124B00DB59E7
/* GlidingCollectionDataSource.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D55E88ED27DE124B00DB59E7
/* GlidingCollectionDataSource.swift */
;
};
D55E88F827DE124B00DB59E7
/* GlidingCollectionDelegate.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D55E88EE27DE124B00DB59E7
/* GlidingCollectionDelegate.swift */
;
};
D55E88F927DE124B00DB59E7
/* GlidingConfig.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D55E88EF27DE124B00DB59E7
/* GlidingConfig.swift */
;
};
D55E88FA27DE124B00DB59E7
/* Collection.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D55E88F127DE124B00DB59E7
/* Collection.swift */
;
};
D55E88FB27DE124B00DB59E7
/* FileManager.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D55E88F227DE124B00DB59E7
/* FileManager.swift */
;
};
D569AB6127B8E27A0013DCFE
/* AppDelegate.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D569AB6027B8E27A0013DCFE
/* AppDelegate.swift */
;
};
D569AB6327B8E27A0013DCFE
/* SceneDelegate.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D569AB6227B8E27A0013DCFE
/* SceneDelegate.swift */
;
};
D569AB6827B8E27A0013DCFE
/* Main.storyboard in Resources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D569AB6627B8E27A0013DCFE
/* Main.storyboard */
;
};
...
...
@@ -30,14 +39,12 @@
D56E5D7B27C2894300D0E4B9
/* MapKit.framework in Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D56E5D7927C2893800D0E4B9
/* MapKit.framework */
;
};
D59E3CE027D3B03F008A7E0C
/* SettingCell.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D59E3CDF27D3B03F008A7E0C
/* SettingCell.swift */
;
};
D59E3CE527D3B37B008A7E0C
/* Extensions.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D59E3CE427D3B37B008A7E0C
/* Extensions.swift */
;
};
D5A073D527D4B45A0033D455
/* PhotoCellCollectionViewCell.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D5A073D327D4B45A0033D455
/* PhotoCellCollectionViewCell.swift */
;
};
D5A073D627D4B45A0033D455
/* PhotoCellCollectionViewCell.xib in Resources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D5A073D427D4B45A0033D455
/* PhotoCellCollectionViewCell.xib */
;
};
D5B0201027C37BBE00C4BA4F
/* MainViewController.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D5B0200F27C37BBE00C4BA4F
/* MainViewController.swift */
;
};
D5B0201527C3826800C4BA4F
/* ArtworkViews.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D5B0201427C3826800C4BA4F
/* ArtworkViews.swift */
;
};
D5B0201A27C382A600C4BA4F
/* Artwork.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D5B0201927C382A600C4BA4F
/* Artwork.swift */
;
};
D5C001D027DA60CB0045F6BE
/* StartNavigationVCViewController.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D5C001CF27DA60CB0045F6BE
/* StartNavigationVCViewController.swift */
;
};
D5C59AF127CFD1810013EFBB
/* netwok.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D5C59AF027CFD1810013EFBB
/* netwok.swift */
;
};
D5D82C8D27D21B070068A5B9
/* SettingsLauncher.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D5D82C8C27D21B070068A5B9
/* SettingsLauncher.swift */
;
};
D5D82C9527D273030068A5B9
/* TabBarViewController.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D5D82C9427D273030068A5B9
/* TabBarViewController.swift */
;
};
D5E2042427CE2DD90063A514
/* ProfileViewController.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D5E2042327CE2DD90063A514
/* ProfileViewController.swift */
;
};
D5E2042927CE30E20063A514
/* DataProfileViewController.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D5E2042827CE30E20063A514
/* DataProfileViewController.swift */
;
};
D5E31B2A27BCE16700F5B87D
/* PlumViewController.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
D5E31B2927BCE16700F5B87D
/* PlumViewController.swift */
;
};
...
...
@@ -79,6 +86,15 @@
D51D340127BF98B9008D5065
/* CalendarViewController.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
CalendarViewController.swift
;
sourceTree
=
"<group>"
;
};
D558EA5B27BE4A6C003C4578
/* HandmanViewController.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
HandmanViewController.swift
;
sourceTree
=
"<group>"
;
};
D558EA6027BE4C65003C4578
/* EmerHandViewController.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
EmerHandViewController.swift
;
sourceTree
=
"<group>"
;
};
D55E88E727DE124A00DB59E7
/* GlidingCollection.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
GlidingCollection.swift
;
sourceTree
=
"<group>"
;
};
D55E88E927DE124A00DB59E7
/* CollectionCell.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
CollectionCell.swift
;
sourceTree
=
"<group>"
;
};
D55E88EA27DE124A00DB59E7
/* CollectionCell.xib */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
file.xib
;
path
=
CollectionCell.xib
;
sourceTree
=
"<group>"
;
};
D55E88EB27DE124B00DB59E7
/* GlidingLayout.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
GlidingLayout.swift
;
sourceTree
=
"<group>"
;
};
D55E88ED27DE124B00DB59E7
/* GlidingCollectionDataSource.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
GlidingCollectionDataSource.swift
;
sourceTree
=
"<group>"
;
};
D55E88EE27DE124B00DB59E7
/* GlidingCollectionDelegate.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
GlidingCollectionDelegate.swift
;
sourceTree
=
"<group>"
;
};
D55E88EF27DE124B00DB59E7
/* GlidingConfig.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
GlidingConfig.swift
;
sourceTree
=
"<group>"
;
};
D55E88F127DE124B00DB59E7
/* Collection.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
Collection.swift
;
sourceTree
=
"<group>"
;
};
D55E88F227DE124B00DB59E7
/* FileManager.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
FileManager.swift
;
sourceTree
=
"<group>"
;
};
D569AB5D27B8E27A0013DCFE
/* Em-call.app */
=
{
isa
=
PBXFileReference
;
explicitFileType
=
wrapper.application
;
includeInIndex
=
0
;
path
=
"Em-call.app"
;
sourceTree
=
BUILT_PRODUCTS_DIR
;
};
D569AB6027B8E27A0013DCFE
/* AppDelegate.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
AppDelegate.swift
;
sourceTree
=
"<group>"
;
};
D569AB6227B8E27A0013DCFE
/* SceneDelegate.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
SceneDelegate.swift
;
sourceTree
=
"<group>"
;
};
...
...
@@ -97,14 +113,12 @@
D56E5D7927C2893800D0E4B9
/* MapKit.framework */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
wrapper.framework
;
name
=
MapKit.framework
;
path
=
System/Library/Frameworks/MapKit.framework
;
sourceTree
=
SDKROOT
;
};
D59E3CDF27D3B03F008A7E0C
/* SettingCell.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
SettingCell.swift
;
sourceTree
=
"<group>"
;
};
D59E3CE427D3B37B008A7E0C
/* Extensions.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
Extensions.swift
;
sourceTree
=
"<group>"
;
};
D5A073D327D4B45A0033D455
/* PhotoCellCollectionViewCell.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
PhotoCellCollectionViewCell.swift
;
sourceTree
=
"<group>"
;
};
D5A073D427D4B45A0033D455
/* PhotoCellCollectionViewCell.xib */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
file.xib
;
path
=
PhotoCellCollectionViewCell.xib
;
sourceTree
=
"<group>"
;
};
D5B0200F27C37BBE00C4BA4F
/* MainViewController.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MainViewController.swift
;
sourceTree
=
"<group>"
;
};
D5B0201427C3826800C4BA4F
/* ArtworkViews.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
ArtworkViews.swift
;
sourceTree
=
"<group>"
;
};
D5B0201927C382A600C4BA4F
/* Artwork.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
Artwork.swift
;
sourceTree
=
"<group>"
;
};
D5C001CF27DA60CB0045F6BE
/* StartNavigationVCViewController.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
StartNavigationVCViewController.swift
;
sourceTree
=
"<group>"
;
};
D5C59AF027CFD1810013EFBB
/* netwok.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
netwok.swift
;
sourceTree
=
"<group>"
;
};
D5D82C8C27D21B070068A5B9
/* SettingsLauncher.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
SettingsLauncher.swift
;
sourceTree
=
"<group>"
;
};
D5D82C9427D273030068A5B9
/* TabBarViewController.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
TabBarViewController.swift
;
sourceTree
=
"<group>"
;
};
D5E2042327CE2DD90063A514
/* ProfileViewController.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
ProfileViewController.swift
;
sourceTree
=
"<group>"
;
};
D5E2042827CE30E20063A514
/* DataProfileViewController.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
DataProfileViewController.swift
;
sourceTree
=
"<group>"
;
};
D5E31B2927BCE16700F5B87D
/* PlumViewController.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
PlumViewController.swift
;
sourceTree
=
"<group>"
;
};
...
...
@@ -171,11 +185,38 @@
D5B0200F27C37BBE00C4BA4F
/* MainViewController.swift */
,
D5E2042327CE2DD90063A514
/* ProfileViewController.swift */
,
D5E2042827CE30E20063A514
/* DataProfileViewController.swift */
,
D5
D82C9427D273030068A5B9
/* TabBar
ViewController.swift */
,
D5
C001CF27DA60CB0045F6BE
/* StartNavigationVC
ViewController.swift */
,
);
path
=
VC
;
sourceTree
=
"<group>"
;
};
D55E88E827DE124A00DB59E7
/* CollectionCell */
=
{
isa
=
PBXGroup
;
children
=
(
D55E88E927DE124A00DB59E7
/* CollectionCell.swift */
,
D55E88EA27DE124A00DB59E7
/* CollectionCell.xib */
,
);
path
=
CollectionCell
;
sourceTree
=
"<group>"
;
};
D55E88EC27DE124B00DB59E7
/* Protocols */
=
{
isa
=
PBXGroup
;
children
=
(
D55E88ED27DE124B00DB59E7
/* GlidingCollectionDataSource.swift */
,
D55E88EE27DE124B00DB59E7
/* GlidingCollectionDelegate.swift */
,
);
path
=
Protocols
;
sourceTree
=
"<group>"
;
};
D55E88F027DE124B00DB59E7
/* Extensions */
=
{
isa
=
PBXGroup
;
children
=
(
D55E88F127DE124B00DB59E7
/* Collection.swift */
,
D55E88F227DE124B00DB59E7
/* FileManager.swift */
,
);
path
=
Extensions
;
sourceTree
=
"<group>"
;
};
D569AB5427B8E27A0013DCFE
=
{
isa
=
PBXGroup
;
children
=
(
...
...
@@ -201,12 +242,19 @@
D569AB5F27B8E27A0013DCFE
/* Em-call */
=
{
isa
=
PBXGroup
;
children
=
(
D5A9FBFA27DB92CB00AAB5EA
/* Addition */
,
D5F0237627C4DB76008F4146
/* Data */
,
D5F0236027C4DA8E008F4146
/* EnterVC */
,
D5057F9B27BA5E520015C0DC
/* VC */
,
D569AB6027B8E27A0013DCFE
/* AppDelegate.swift */
,
D569AB6227B8E27A0013DCFE
/* SceneDelegate.swift */
,
D569AB6627B8E27A0013DCFE
/* Main.storyboard */
,
D55E88E827DE124A00DB59E7
/* CollectionCell */
,
D55E88F027DE124B00DB59E7
/* Extensions */
,
D55E88E727DE124A00DB59E7
/* GlidingCollection.swift */
,
D55E88EF27DE124B00DB59E7
/* GlidingConfig.swift */
,
D55E88EB27DE124B00DB59E7
/* GlidingLayout.swift */
,
D55E88EC27DE124B00DB59E7
/* Protocols */
,
D569AB6C27B8E27B0013DCFE
/* Assets.xcassets */
,
D569AB6E27B8E27B0013DCFE
/* LaunchScreen.storyboard */
,
D569AB7127B8E27B0013DCFE
/* Info.plist */
,
...
...
@@ -242,6 +290,13 @@
name
=
Frameworks
;
sourceTree
=
"<group>"
;
};
D5A9FBFA27DB92CB00AAB5EA
/* Addition */
=
{
isa
=
PBXGroup
;
children
=
(
);
path
=
Addition
;
sourceTree
=
"<group>"
;
};
D5F0236027C4DA8E008F4146
/* EnterVC */
=
{
isa
=
PBXGroup
;
children
=
(
...
...
@@ -263,8 +318,6 @@
D5D82C8C27D21B070068A5B9
/* SettingsLauncher.swift */
,
D5F0238727C4E2AA008F4146
/* ShowAlert.swift */
,
D5C59AF027CFD1810013EFBB
/* netwok.swift */
,
D5A073D327D4B45A0033D455
/* PhotoCellCollectionViewCell.swift */
,
D5A073D427D4B45A0033D455
/* PhotoCellCollectionViewCell.xib */
,
);
path
=
Data
;
sourceTree
=
"<group>"
;
...
...
@@ -374,8 +427,8 @@
isa
=
PBXResourcesBuildPhase
;
buildActionMask
=
2147483647
;
files
=
(
D55E88F527DE124B00DB59E7
/* CollectionCell.xib in Resources */
,
D569AB7027B8E27B0013DCFE
/* LaunchScreen.storyboard in Resources */
,
D5A073D627D4B45A0033D455
/* PhotoCellCollectionViewCell.xib in Resources */
,
D569AB6D27B8E27B0013DCFE
/* Assets.xcassets in Resources */
,
D569AB6827B8E27A0013DCFE
/* Main.storyboard in Resources */
,
);
...
...
@@ -448,26 +501,33 @@
D5F0237B27C4DEC4008F4146
/* LocationMng.swift in Sources */
,
D5E31B3C27BD651C00F5B87D
/* EmerElecricianViewController.swift in Sources */
,
D5F0238827C4E2AA008F4146
/* ShowAlert.swift in Sources */
,
D5D82C9527D273030068A5B9
/* TabBarViewController.swift in Sources */
,
D5E31B3227BCEC0900F5B87D
/* CollectionViewCell.swift in Sources */
,
D558EA5C27BE4A6C003C4578
/* HandmanViewController.swift in Sources */
,
D55E88FA27DE124B00DB59E7
/* Collection.swift in Sources */
,
D5E2042427CE2DD90063A514
/* ProfileViewController.swift in Sources */
,
D55E88F327DE124B00DB59E7
/* GlidingCollection.swift in Sources */
,
D5E31B2A27BCE16700F5B87D
/* PlumViewController.swift in Sources */
,
D55E88F627DE124B00DB59E7
/* GlidingLayout.swift in Sources */
,
D569AB6B27B8E27A0013DCFE
/* Em_call.xcdatamodeld in Sources */
,
D569AB6127B8E27A0013DCFE
/* AppDelegate.swift in Sources */
,
D55E88F827DE124B00DB59E7
/* GlidingCollectionDelegate.swift in Sources */
,
D55E88F427DE124B00DB59E7
/* CollectionCell.swift in Sources */
,
D55E88FB27DE124B00DB59E7
/* FileManager.swift in Sources */
,
D5E31B3727BD578F00F5B87D
/* PlumbersViewController.swift in Sources */
,
D5D82C8D27D21B070068A5B9
/* SettingsLauncher.swift in Sources */
,
D55E88F727DE124B00DB59E7
/* GlidingCollectionDataSource.swift in Sources */
,
D514861927BBEFC8006830A3
/* Track.swift in Sources */
,
D59E3CE027D3B03F008A7E0C
/* SettingCell.swift in Sources */
,
D5B0201A27C382A600C4BA4F
/* Artwork.swift in Sources */
,
D55E88F927DE124B00DB59E7
/* GlidingConfig.swift in Sources */
,
D56E5D6D27C26F2500D0E4B9
/* StartViewController.swift in Sources */
,
D5F0236F27C4DAD8008F4146
/* ChangePswViewController.swift in Sources */
,
D5057F9D27BA5E940015C0DC
/* VKBookingViewController.swift in Sources */
,
D5F0236A27C4DAC2008F4146
/* RegistrationViewController.swift in Sources */
,
D558EA6127BE4C65003C4578
/* EmerHandViewController.swift in Sources */
,
D5A073D527D4B45A0033D455
/* PhotoCellCollectionViewCell.swift in Sources */
,
D514860727BB7FD7006830A3
/* ChatViewController.swift in Sources */
,
D5B0201527C3826800C4BA4F
/* ArtworkViews.swift in Sources */
,
D5C001D027DA60CB0045F6BE
/* StartNavigationVCViewController.swift in Sources */
,
D569AB6327B8E27A0013DCFE
/* SceneDelegate.swift in Sources */
,
D5B0201027C37BBE00C4BA4F
/* MainViewController.swift in Sources */
,
D59E3CE527D3B37B008A7E0C
/* Extensions.swift in Sources */
,
...
...
Em-call.xcodeproj/xcuserdata/alexsh.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
View file @
27f01c03
...
...
@@ -14,8 +14,8 @@
filePath =
"Em-call/VC/ElectricTableViewController.swift"
startingColumnNumber =
"9223372036854775807"
endingColumnNumber =
"9223372036854775807"
startingLineNumber =
"
26
"
endingLineNumber =
"
26
"
startingLineNumber =
"
39
"
endingLineNumber =
"
39
"
landmarkName =
"viewDidLoad()"
landmarkType =
"7"
>
</BreakpointContent>
...
...
@@ -78,8 +78,8 @@
filePath =
"Em-call/VC/HandmanViewController.swift"
startingColumnNumber =
"9223372036854775807"
endingColumnNumber =
"9223372036854775807"
startingLineNumber =
"
124
"
endingLineNumber =
"
124
"
startingLineNumber =
"
216
"
endingLineNumber =
"
216
"
landmarkName =
"delegateClick(text:)"
landmarkType =
"7"
>
</BreakpointContent>
...
...
@@ -94,8 +94,8 @@
filePath =
"Em-call/VC/HandmanViewController.swift"
startingColumnNumber =
"9223372036854775807"
endingColumnNumber =
"9223372036854775807"
startingLineNumber =
"
133
"
endingLineNumber =
"
133
"
startingLineNumber =
"
225
"
endingLineNumber =
"
225
"
landmarkName =
"calendarDelegateClick(text:flagData:)"
landmarkType =
"7"
>
</BreakpointContent>
...
...
@@ -334,8 +334,8 @@
filePath =
"Em-call/VC/ElectricTableViewController.swift"
startingColumnNumber =
"9223372036854775807"
endingColumnNumber =
"9223372036854775807"
startingLineNumber =
"1
25
"
endingLineNumber =
"1
25
"
startingLineNumber =
"1
73
"
endingLineNumber =
"1
73
"
landmarkName =
"delegateClick(text:)"
landmarkType =
"7"
>
</BreakpointContent>
...
...
Em-call.xcworkspace/xcuserdata/alexsh.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
View file @
27f01c03
...
...
@@ -126,8 +126,8 @@
filePath =
"Em-call/VC/StartViewController.swift"
startingColumnNumber =
"9223372036854775807"
endingColumnNumber =
"9223372036854775807"
startingLineNumber =
"
39
"
endingLineNumber =
"
39
"
startingLineNumber =
"
44
"
endingLineNumber =
"
44
"
landmarkName =
"pressEnter(_:)"
landmarkType =
"7"
>
</BreakpointContent>
...
...
@@ -135,96 +135,144 @@
<BreakpointProxy
BreakpointExtensionID =
"Xcode.Breakpoint.FileBreakpoint"
>
<BreakpointContent
uuid =
"
61557638-FAA5-4C76-85CE-8E55683A260D
"
uuid =
"
E9CD7D6F-E131-43FB-BCBA-2C3051248555
"
shouldBeEnabled =
"No"
ignoreCount =
"0"
continueAfterRunningActions =
"No"
filePath =
"Em-call/
VC/PlumbersViewControll
er.swift"
filePath =
"Em-call/
Data/SettingsLaunch
er.swift"
startingColumnNumber =
"9223372036854775807"
endingColumnNumber =
"9223372036854775807"
startingLineNumber =
"
75
"
endingLineNumber =
"
75
"
landmarkName =
"
PlumbersViewController
"
landmarkType =
"
3
"
>
startingLineNumber =
"
96
"
endingLineNumber =
"
96
"
landmarkName =
"
imagePickerController(_:didFinishPickingMediaWithInfo:)
"
landmarkType =
"
7
"
>
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID =
"Xcode.Breakpoint.FileBreakpoint"
>
<BreakpointContent
uuid =
"
87CFDADC-E1F7-4635-A386-5BCEB4888BEB
"
uuid =
"
961D3D3C-3B31-4E3B-A6DA-64F7E35755EC
"
shouldBeEnabled =
"No"
ignoreCount =
"0"
continueAfterRunningActions =
"No"
filePath =
"Em-call/VC/
Plumbers
ViewController.swift"
filePath =
"Em-call/VC/
Main
ViewController.swift"
startingColumnNumber =
"9223372036854775807"
endingColumnNumber =
"9223372036854775807"
startingLineNumber =
"
72
"
endingLineNumber =
"
72
"
landmarkName =
"
PlumbersViewController
"
landmarkType =
"
3
"
>
startingLineNumber =
"
86
"
endingLineNumber =
"
86
"
landmarkName =
"
viewDidLoad()
"
landmarkType =
"
7
"
>
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID =
"Xcode.Breakpoint.FileBreakpoint"
>
<BreakpointContent
uuid =
"
E9CD7D6F-E131-43FB-BCBA-2C3051248555
"
uuid =
"
251E8DE0-67D4-4737-A70B-7AE01636479E
"
shouldBeEnabled =
"No"
ignoreCount =
"0"
continueAfterRunningActions =
"No"
filePath =
"Em-call/
Data/SettingsLaunch
er.swift"
filePath =
"Em-call/
VC/MainViewControll
er.swift"
startingColumnNumber =
"9223372036854775807"
endingColumnNumber =
"9223372036854775807"
startingLineNumber =
"
96
"
endingLineNumber =
"
96
"
landmarkName =
"
imagePickerController(_:didFinishPickingMediaWithInfo
:)"
startingLineNumber =
"
132
"
endingLineNumber =
"
132
"
landmarkName =
"
viewWillAppear(_
:)"
landmarkType =
"7"
>
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID =
"Xcode.Breakpoint.FileBreakpoint"
>
<BreakpointContent
uuid =
"
2BCA10DE-E33E-4CA8-B536-B26D5ACBD23C
"
uuid =
"
621705DF-0F9C-487A-8B39-87A9E713D039
"
shouldBeEnabled =
"No"
ignoreCount =
"0"
continueAfterRunningActions =
"No"
filePath =
"Em-call/VC/
Plumbers
ViewController.swift"
filePath =
"Em-call/VC/
Start
ViewController.swift"
startingColumnNumber =
"9223372036854775807"
endingColumnNumber =
"9223372036854775807"
startingLineNumber =
"
191
"
endingLineNumber =
"
191
"
landmarkName =
"
settingsDelegateClick(img
:)"
startingLineNumber =
"
23
"
endingLineNumber =
"
23
"
landmarkName =
"
pressEnter(_
:)"
landmarkType =
"7"
>
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID =
"Xcode.Breakpoint.FileBreakpoint"
>
<BreakpointContent
uuid =
"
961D3D3C-3B31-4E3B-A6DA-64F7E35755EC
"
uuid =
"
ED9E13C6-B42E-4860-9191-BB5C44212E2E
"
shouldBeEnabled =
"No"
ignoreCount =
"0"
continueAfterRunningActions =
"No"
filePath =
"Em-call/VC/
Main
ViewController.swift"
filePath =
"Em-call/VC/
Start
ViewController.swift"
startingColumnNumber =
"9223372036854775807"
endingColumnNumber =
"9223372036854775807"
startingLineNumber =
"
86
"
endingLineNumber =
"
86
"
landmarkName =
"
viewDidLoad(
)"
startingLineNumber =
"
34
"
endingLineNumber =
"
34
"
landmarkName =
"
pressEnter(_:
)"
landmarkType =
"7"
>
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID =
"Xcode.Breakpoint.FileBreakpoint"
>
<BreakpointContent
uuid =
"251E8DE0-67D4-4737-A70B-7AE01636479E"
uuid =
"5B6BEC96-DAB7-4B10-AA15-EDB231A59C47"
shouldBeEnabled =
"Yes"
ignoreCount =
"0"
continueAfterRunningActions =
"No"
filePath =
"Em-call/Addition/BananaViewController.swift"
startingColumnNumber =
"9223372036854775807"
endingColumnNumber =
"9223372036854775807"
startingLineNumber =
"217"
endingLineNumber =
"217"
landmarkName =
"scrollViewTapped(_:)"
landmarkType =
"7"
>
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID =
"Xcode.Breakpoint.FileBreakpoint"
>
<BreakpointContent
uuid =
"0B5DDEC8-2549-483F-97AA-7CB3471CFBAE"
shouldBeEnabled =
"No"
ignoreCount =
"0"
continueAfterRunningActions =
"No"
filePath =
"Em-call/
VC/Main
ViewController.swift"
filePath =
"Em-call/
Addition/Banana
ViewController.swift"
startingColumnNumber =
"9223372036854775807"
endingColumnNumber =
"9223372036854775807"
startingLineNumber =
"132"
endingLineNumber =
"132"
landmarkName =
"viewWillAppear(_:)"
startingLineNumber =
"192"
endingLineNumber =
"192"
landmarkName =
"assignTouchGesture()"
landmarkType =
"7"
>
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID =
"Xcode.Breakpoint.FileBreakpoint"
>
<BreakpointContent
uuid =
"FC5A3F9B-B53A-48E6-B53D-ADCF39677E27"
shouldBeEnabled =
"No"
ignoreCount =
"0"
continueAfterRunningActions =
"No"
filePath =
"Em-call/VC/ElectricTableViewController.swift"
startingColumnNumber =
"9223372036854775807"
endingColumnNumber =
"9223372036854775807"
startingLineNumber =
"198"
endingLineNumber =
"198"
landmarkName =
"settingsDelegateClick(img:)"
landmarkType =
"7"
>
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID =
"Xcode.Breakpoint.FileBreakpoint"
>
<BreakpointContent
uuid =
"16148796-3411-4F8E-9120-7BFCFD6FFF7B"
shouldBeEnabled =
"No"
ignoreCount =
"0"
continueAfterRunningActions =
"No"
filePath =
"Em-call/VC/HandmanViewController.swift"
startingColumnNumber =
"9223372036854775807"
endingColumnNumber =
"9223372036854775807"
startingLineNumber =
"240"
endingLineNumber =
"240"
landmarkName =
"settingsDelegateClick(img:)"
landmarkType =
"7"
>
</BreakpointContent>
</BreakpointProxy>
...
...
Em-call/Base.lproj/Main.storyboard
View file @
27f01c03
This diff is collapsed.
Click to expand it.
Em-call/CollectionCell/CollectionCell.swift
0 → 100644
View file @
27f01c03
//
// CollectionCell.swift
// GlidingCollection
//
import
UIKit
class
CollectionCell
:
UICollectionViewCell
{
@IBOutlet
var
imageView
:
UIImageView
!
}
Em-call/CollectionCell/CollectionCell.xib
0 → 100644
View file @
27f01c03
<?xml version="1.0" encoding="UTF-8"?>
<document
type=
"com.apple.InterfaceBuilder3.CocoaTouch.XIB"
version=
"3.0"
toolsVersion=
"17506"
targetRuntime=
"iOS.CocoaTouch"
propertyAccessControl=
"none"
useAutolayout=
"YES"
useTraitCollections=
"YES"
colorMatched=
"YES"
>
<device
id=
"retina4_7"
orientation=
"portrait"
appearance=
"light"
/>
<dependencies>
<plugIn
identifier=
"com.apple.InterfaceBuilder.IBCocoaTouchPlugin"
version=
"17505"
/>
<capability
name=
"documents saved in the Xcode 8 format"
minToolsVersion=
"8.0"
/>
</dependencies>
<objects>
<placeholder
placeholderIdentifier=
"IBFilesOwner"
id=
"-1"
userLabel=
"File's Owner"
/>
<placeholder
placeholderIdentifier=
"IBFirstResponder"
id=
"-2"
customClass=
"UIResponder"
/>
<collectionViewCell
opaque=
"NO"
multipleTouchEnabled=
"YES"
contentMode=
"center"
id=
"03b-as-7h4"
customClass=
"CollectionCell"
customModule=
"Glide"
customModuleProvider=
"target"
>
<rect
key=
"frame"
x=
"0.0"
y=
"0.0"
width=
"155"
height=
"222"
/>
<autoresizingMask
key=
"autoresizingMask"
flexibleMaxX=
"YES"
flexibleMaxY=
"YES"
/>
<view
key=
"contentView"
opaque=
"NO"
clipsSubviews=
"YES"
multipleTouchEnabled=
"YES"
contentMode=
"center"
>
<rect
key=
"frame"
x=
"0.0"
y=
"0.0"
width=
"155"
height=
"222"
/>
<autoresizingMask
key=
"autoresizingMask"
/>
<subviews>
<imageView
clipsSubviews=
"YES"
userInteractionEnabled=
"NO"
tag=
"99"
contentMode=
"scaleAspectFill"
horizontalHuggingPriority=
"251"
verticalHuggingPriority=
"251"
fixedFrame=
"YES"
translatesAutoresizingMaskIntoConstraints=
"NO"
id=
"DpZ-0l-nTe"
>
<rect
key=
"frame"
x=
"0.0"
y=
"0.0"
width=
"155"
height=
"222"
/>
<autoresizingMask
key=
"autoresizingMask"
widthSizable=
"YES"
heightSizable=
"YES"
/>
</imageView>
</subviews>
</view>
<size
key=
"customSize"
width=
"65"
height=
"23"
/>
<connections>
<outlet
property=
"imageView"
destination=
"DpZ-0l-nTe"
id=
"30e-7A-Tsv"
/>
</connections>
<point
key=
"canvasLocation"
x=
"-44"
y=
"23.388305847076463"
/>
</collectionViewCell>
</objects>
</document>
Em-call/Data/Extensions.swift
View file @
27f01c03
...
...
@@ -2,9 +2,6 @@
// Extensions.swift
// youtube
//
// Created by Brian Voong on 6/3/16.
// Copyright © 2016 letsbuildthatapp. All rights reserved.
//
import
UIKit
...
...
Em-call/Data/SettingCell.swift
View file @
27f01c03
...
...
@@ -2,9 +2,6 @@
// SettingCell.swift
// youtube
//
// Created by Brian Voong on 6/18/16.
// Copyright © 2016 letsbuildthatapp. All rights reserved.
//
import
UIKit
...
...
Em-call/Data/SettingsLauncher.swift
View file @
27f01c03
...
...
@@ -149,6 +149,7 @@ class SettingsLauncher : UIViewController, UITableViewDelegate, UITableViewDataS
self
.
navController
?
.
present
(
self
.
imagePickerController
,
animated
:
true
,
completion
:
nil
)
// self.navController?.pushViewController(self.imagePickerController, animated: true)
case
3
:
handleDismiss
()
return
default
:
return
}
...
...
Em-call/Extensions/Collection.swift
0 → 100644
View file @
27f01c03
//
// Collection.swift
// GlidingCollection
//
import
Foundation
// :nodoc:
extension
Collection
{
subscript
(
safe
index
:
Index
)
->
Iterator
.
Element
?
{
return
index
>=
startIndex
&&
index
<
endIndex
?
self
[
index
]
:
nil
}
}
Em-call/Extensions/FileManager.swift
0 → 100644
View file @
27f01c03
//
// FileManager.swift
// GlidingCollection
//
import
Foundation
extension
FileManager
{
func
fileUrls
(
for
types
:
String
...
,
fileName
:
String
)
->
[
URL
]
{
let
bundlePath
=
Bundle
.
main
.
bundlePath
let
directoryEnumerator
=
enumerator
(
atPath
:
bundlePath
)
var
paths
=
[
URL
]()
while
let
path
=
directoryEnumerator
?
.
nextObject
()
as?
String
{
let
url
=
URL
(
fileURLWithPath
:
path
)
for
type
in
types
{
if
url
.
path
.
lowercased
()
.
contains
(
fileName
.
lowercased
())
&&
url
.
path
.
contains
(
type
)
{
let
url
=
Bundle
.
main
.
bundleURL
.
appendingPathComponent
(
path
)
paths
.
append
(
url
)
}
}
}
return
paths
}
}
Em-call/GlidingCollection.swift
0 → 100644
View file @
27f01c03
//
// GlidingCollection.swift
// GlidingCollection
//
import
UIKit
/// Parallax view tag
public
let
kGlidingCollectionParallaxViewTag
=
99
/// GlidingCollection control.
/// Add as subview to your view and implement `dataSource` protocol.
public
final
class
GlidingCollection
:
UIView
{
/// Delegate protocol.
public
var
delegate
:
GlidingCollectionDelegate
?
/// Data source protocol.
public
var
dataSource
:
GlidingCollectionDatasource
?
{
didSet
{
setupVerticalStack
()
}
}
/// Index of expanded item.
public
var
expandedItemIndex
=
0
{
didSet
{
guard
let
count
=
dataSource
?
.
numberOfItems
(
in
:
self
)
else
{
return
}
containerView
.
isScrollEnabled
=
expandedItemIndex
==
0
||
expandedItemIndex
==
count
-
1
}
}
/// Horizontal scrolling collectionView.
public
var
collectionView
:
UICollectionView
=
UICollectionView
(
frame
:
.
zero
,
collectionViewLayout
:
UICollectionViewLayout
())
// MARK: Private properties
fileprivate
var
containerView
=
UIScrollView
()
fileprivate
var
scaledTransform
:
CGAffineTransform
{
let
scale
=
config
.
buttonsScaleFactor
return
CGAffineTransform
(
scaleX
:
scale
,
y
:
scale
)
}
fileprivate
var
config
:
GlidingConfig
{
return
GlidingConfig
.
shared
}
// Gesture related properties.
fileprivate
var
gesture
:
UIPanGestureRecognizer
!
fileprivate
var
gestureStartPosition
:
CGPoint
=
.
zero
fileprivate
enum
Direction
{
case
up
,
down
}
fileprivate
var
lastDirection
=
Direction
.
down
fileprivate
let
layout
=
GlidingLayout
()
fileprivate
var
lastExpandedItemIndex
=
0
fileprivate
var
animationInProcess
=
false
fileprivate
var
animationViewsDictionary
:
[
String
:
AniView
]
=
[:]
fileprivate
var
topOverlayGradient
=
CAGradientLayer
()
fileprivate
var
bottomOverlayGradient
=
CAGradientLayer
()
fileprivate
var
topViews
:
[
UIButton
]
=
[]
fileprivate
var
bottomViews
:
[
UIButton
]
=
[]
// MARK: Snapshots
fileprivate
var
newRightSideSnapshot
:
UIView
?
// MARK: Constructor 🏗
/// :nodoc:
override
public
init
(
frame
:
CGRect
)
{
super
.
init
(
frame
:
frame
)
commonInit
()
}
/// :nodoc:
required
public
init
?(
coder
aDecoder
:
NSCoder
)
{
super
.
init
(
coder
:
aDecoder
)
commonInit
()
}
private
func
commonInit
()
{
setup
()
animateTopButtons
()
animateBottomButtons
()
}
}
// MARK: - Lifecycle 🌎
extension
GlidingCollection
:
UIGestureRecognizerDelegate
{
/// :nodoc:
public
override
func
layoutSubviews
()
{
super
.
layoutSubviews
()
containerView
.
frame
=
bounds
containerView
.
contentSize
=
bounds
.
size
let
cardSize
=
config
.
cardsSize
collectionView
.
frame
=
CGRect
(
x
:
0
,
y
:
bounds
.
height
/
2
-
cardSize
.
height
/
2
,
width
:
bounds
.
width
,
height
:
cardSize
.
height
)
/* collectionView.frame = CGRect(x: 0, y: bounds.height/4 - cardSize.height/3, width: bounds.width, height: cardSize.height/3)
*/
animateTopButtons
()
animateBottomButtons
()
let
topOverylayHeight
=
collectionView
.
frame
.
minY
// topOverlayGradient.frame = CGRect(x: 0, y: 0, width: bounds.width, height: topOverylayHeight)
topOverlayGradient
.
frame
=
CGRect
(
x
:
0
,
y
:
bounds
.
height
/
2
,
width
:
bounds
.
width
,
height
:
topOverylayHeight
/
2
)
let
bottomOverylayHeight
=
bounds
.
height
-
collectionView
.
frame
.
maxY
bottomOverlayGradient
.
frame
=
CGRect
(
x
:
0
,
y
:
collectionView
.
frame
.
maxY
,
width
:
bounds
.
width
,
height
:
bottomOverylayHeight
)
}
/// :nodoc:
public
func
gestureRecognizer
(
_
gestureRecognizer
:
UIGestureRecognizer
,
shouldRecognizeSimultaneouslyWith
otherGestureRecognizer
:
UIGestureRecognizer
)
->
Bool
{
if
otherGestureRecognizer
===
containerView
.
panGestureRecognizer
{
return
true
}
return
false
}
/// :nodoc:
public
override
func
didMoveToWindow
()
{
super
.
didMoveToWindow
()
// Can't find better way to force collectionView to apply custom attributes.
DispatchQueue
.
main
.
asyncAfter
(
deadline
:
DispatchTime
.
now
()
+
0.05
)
{
self
.
layout
.
invalidateLayout
()
}
}
}
// MARK: - Setup ⛏
fileprivate
extension
GlidingCollection
{
func
setup
()
{
setupContainerView
()
setupCollectionView
()
setupVerticalStack
()
setupPanGesture
()
setupGradientOverlays
()
}
private
func
setupContainerView
()
{
addSubview
(
containerView
)
containerView
.
alwaysBounceVertical
=
true
containerView
.
delegate
=
self
}
private
func
setupCollectionView
()
{
layout
.
itemSize
=
config
.
cardsSize
layout
.
minimumLineSpacing
=
config
.
cardsSpacing
layout
.
scrollDirection
=
.
horizontal
let
insets
=
config
.
sideInsets
let
rightInset
=
UIScreen
.
main
.
bounds
.
width
-
config
.
cardsSize
.
width
-
insets
.
left
layout
.
sectionInset
=
UIEdgeInsets
(
top
:
0
,
left
:
insets
.
left
,
bottom
:
0
,
right
:
rightInset
)
layout
.
delegate
=
self
collectionView
=
UICollectionView
(
frame
:
.
zero
,
collectionViewLayout
:
layout
)
containerView
.
insertSubview
(
collectionView
,
at
:
0
)
collectionView
.
translatesAutoresizingMaskIntoConstraints
=
false
collectionView
.
showsHorizontalScrollIndicator
=
false
collectionView
.
delaysContentTouches
=
true
collectionView
.
clipsToBounds
=
false
collectionView
.
collectionViewLayout
.
invalidateLayout
()
}
func
setupVerticalStack
()
{
guard
let
source
=
dataSource
,
source
.
numberOfItems
(
in
:
self
)
>
0
else
{
return
}
for
i
in
0
..<
source
.
numberOfItems
(
in
:
self
)
{
let
isTopTitle
=
i
<=
expandedItemIndex
let
title
=
source
.
glidingCollection
(
self
,
itemAtIndex
:
i
)
.
uppercased
()
let
button
=
UIButton
()
button
.
contentHorizontalAlignment
=
.
left
let
color
=
isTopTitle
?
config
.
activeButtonColor
:
config
.
inactiveButtonsColor
button
.
setTitleColor
(
color
,
for
:
.
normal
)
button
.
setTitle
(
title
,
for
:
.
normal
)
button
.
titleLabel
?
.
font
=
config
.
buttonsFont
button
.
layer
.
anchorPoint
=
CGPoint
(
x
:
0
,
y
:
0
)
button
.
transform
=
scaledTransform
isTopTitle
?
topViews
.
append
(
button
)
:
bottomViews
.
append
(
button
)
containerView
.
insertSubview
(
button
,
at
:
0
)
button
.
addTarget
(
self
,
action
:
#selector(
didTapped(_:)
)
,
for
:
.
touchUpInside
)
}
}
private
func
setupGradientOverlays
()
{
topOverlayGradient
.
colors
=
[
UIColor
.
white
.
cgColor
,
UIColor
.
white
.
withAlphaComponent
(
0
)
.
cgColor
]
bottomOverlayGradient
.
colors
=
[
UIColor
.
white
.
withAlphaComponent
(
0
)
.
cgColor
,
UIColor
.
white
.
cgColor
]
layer
.
addSublayer
(
topOverlayGradient
)
layer
.
addSublayer
(
bottomOverlayGradient
)
}
private
func
setupPanGesture
()
{
gesture
=
UIPanGestureRecognizer
(
target
:
self
,
action
:
#selector(
handlePanGesture(_:)
)
)
gesture
.
delegate
=
self
addGestureRecognizer
(
gesture
)
}
func
setShadow
(
to
view
:
UIView
)
{
view
.
clipsToBounds
=
false
let
layer
=
view
.
layer
layer
.
shadowOffset
=
config
.
cardShadowOffset
layer
.
shadowColor
=
config
.
cardShadowColor
.
cgColor
layer
.
shadowOpacity
=
config
.
cardShadowOpacity
layer
.
shadowRadius
=
config
.
cardShadowRadius
}
}
// MARK: - Actions ⚡
extension
GlidingCollection
{
// MARK: Public
/// Expand GlidingCollection
///
/// - Parameters:
/// - index: target index
/// - animated: animate changes
public
func
expand
(
at
index
:
Int
,
animated
:
Bool
=
true
)
{
guard
index
!=
expandedItemIndex
,
let
source
=
dataSource
,
index
<
source
.
numberOfItems
(
in
:
self
),
index
>=
0
else
{
return
}
delegate
?
.
glidingCollection
(
self
,
willExpandItemAt
:
index
)
collectionView
.
isUserInteractionEnabled
=
false
let
duration
:
Double
=
config
.
animationDuration
let
direction
:
Direction
=
index
>
expandedItemIndex
?
.
up
:
.
down
let
up
=
direction
==
.
up
let
bounds
=
self
.
bounds
let
minX
=
config
.
sideInsets
.
left
let
space
=
config
.
cardsSpacing
let
cellFrame
=
CGRect
(
x
:
minX
,
y
:
collectionView
.
frame
.
minY
,
width
:
config
.
cardsSize
.
width
,
height
:
config
.
cardsSize
.
height
)
var
delay
:
Double
=
0
if
animationInProcess
{
delay
=
duration
/
3.5
for
subview
in
subviews
+
containerView
.
subviews
where
subview
.
tag
==
AnimationItem
.
newRightSide
.
tag
{
let
layer
=
subview
.
layer
let
position
=
layer
.
presentation
()?
.
position
??
CGPoint
(
x
:
cellFrame
.
maxX
,
y
:
cellFrame
.
minY
)
layer
.
removeAllAnimations
()
layer
.
position
=
position
let
newPosition
=
CGPoint
(
x
:
bounds
.
width
+
space
,
y
:
cellFrame
.
minY
)
let
newValue
=
AnimationValue
.
position
(
newPosition
)
animate
(
subview
,
newValue
:
newValue
,
item
:
AnimationItem
.
newRightSide
,
duration
:
duration
*
1.2
,
delay
:
0
,
index
:
lastExpandedItemIndex
)
}
if
let
aniview
=
getAniview
(
of
:
AnimationItem
.
newCellWrapper
,
at
:
expandedItemIndex
)
{
aniview
.
view
.
removeFromSuperview
()
}
lastExpandedItemIndex
=
expandedItemIndex
}
lastDirection
=
direction
let
oldRightSideSnapshotView
=
UIImageView
()
let
oldCellSnapshotView
=
UIImageView
()
let
newCellWrapperView
=
UIView
()
let
newCellShadowView
=
UIView
()
let
newCellSnapshotView
=
UIImageView
()
let
newRightSideSnapshotView
=
UIImageView
()
containerView
.
addSubview
(
oldCellSnapshotView
)
containerView
.
addSubview
(
oldRightSideSnapshotView
)
containerView
.
addSubview
(
newCellShadowView
)
containerView
.
addSubview
(
newCellWrapperView
)
containerView
.
addSubview
(
newRightSideSnapshotView
)
let
unified
=
topViews
+
bottomViews
let
movingItem
=
unified
[
safe
:
index
]
topViews
=
Array
(
unified
.
prefix
(
through
:
index
))
bottomViews
=
index
+
1
<
unified
.
count
?
Array
(
unified
.
suffix
(
from
:
index
+
1
))
:
[]
// Set new expanded index
let
oldIndex
=
expandedItemIndex
expandedItemIndex
=
index
var
paths
=
collectionView
.
indexPathsForVisibleItems
.
sorted
{
$0
.
item
<
$1
.
item
}
var
cellIndex
=
0
var
oldCellFrame
=
CGRect
.
zero
for
path
in
paths
{
guard
let
cell
=
collectionView
.
cellForItem
(
at
:
path
)
else
{
continue
}
cell
.
alpha
=
1
let
offset
=
collectionView
.
contentOffset
.
x
var
frame
=
cell
.
frame
frame
.
origin
.
x
-=
offset
if
frame
.
minX
>
0
{
oldCellFrame
=
frame
break
}
cellIndex
+=
1
}
// MARK: Snapshot of old cell
if
let
path
=
paths
[
safe
:
cellIndex
],
let
cell
=
collectionView
.
cellForItem
(
at
:
path
)
{
UIGraphicsBeginImageContextWithOptions
(
cell
.
frame
.
size
,
true
,
0
)
if
let
context
=
UIGraphicsGetCurrentContext
()
{
cell
.
layer
.
render
(
in
:
context
)
}
oldCellSnapshotView
.
image
=
UIGraphicsGetImageFromCurrentImageContext
()
oldCellSnapshotView
.
frame
=
oldCellFrame
UIGraphicsEndImageContext
()
oldCellSnapshotView
.
tag
=
AnimationItem
.
oldCell
.
tag
setShadow
(
to
:
oldCellSnapshotView
)
}
// MARK: Snapshot of right side of collectionView
if
let
path
=
paths
[
safe
:
cellIndex
+
1
],
let
cell
=
collectionView
.
cellForItem
(
at
:
path
),
!
animationInProcess
{
UIGraphicsBeginImageContextWithOptions
(
cell
.
bounds
.
size
,
true
,
0
)
if
let
context
=
UIGraphicsGetCurrentContext
()
{
cell
.
layer
.
render
(
in
:
context
)
}
oldRightSideSnapshotView
.
image
=
UIGraphicsGetImageFromCurrentImageContext
()
UIGraphicsEndImageContext
()
oldRightSideSnapshotView
.
frame
=
CGRect
(
x
:
oldCellFrame
.
maxX
+
space
,
y
:
cellFrame
.
minY
,
width
:
cellFrame
.
width
,
height
:
cellFrame
.
height
)
oldRightSideSnapshotView
.
tag
=
AnimationItem
.
oldRightSide
.
tag
setShadow
(
to
:
oldRightSideSnapshotView
)
}
// MARK: Reload collection view & force to layout
collectionView
.
collectionViewLayout
.
invalidateLayout
()
if
collectionView
.
numberOfItems
(
inSection
:
0
)
>
0
{
let
path
=
IndexPath
(
item
:
0
,
section
:
0
)
collectionView
.
scrollToItem
(
at
:
path
,
at
:
UICollectionView
.
ScrollPosition
.
centeredHorizontally
,
animated
:
false
)
}
collectionView
.
reloadData
()
collectionView
.
layoutIfNeeded
()
paths
=
self
.
collectionView
.
indexPathsForVisibleItems
.
sorted
{
$0
.
item
<
$1
.
item
}
collectionView
.
visibleCells
.
forEach
{
$0
.
alpha
=
1
}
// MARK: Snapshot of new cell
if
let
path
=
paths
.
first
,
let
cell
=
collectionView
.
cellForItem
(
at
:
path
)
{
cell
.
contentView
.
transform
=
.
identity
UIGraphicsBeginImageContextWithOptions
(
cellFrame
.
size
,
true
,
0
)
if
let
context
=
UIGraphicsGetCurrentContext
()
{
if
let
parallaxView
=
cell
.
contentView
.
viewWithTag
(
kGlidingCollectionParallaxViewTag
)
{
parallaxView
.
transform
=
.
identity
}
cell
.
contentView
.
layer
.
render
(
in
:
context
)
}
newCellSnapshotView
.
image
=
UIGraphicsGetImageFromCurrentImageContext
()
UIGraphicsEndImageContext
()
newCellWrapperView
.
addSubview
(
newCellSnapshotView
)
newCellWrapperView
.
clipsToBounds
=
true
newCellWrapperView
.
isUserInteractionEnabled
=
false
let
imageViewOriginY
=
up
?
-
cellFrame
.
height
:
0
newCellSnapshotView
.
frame
=
CGRect
(
x
:
0
,
y
:
imageViewOriginY
,
width
:
cellFrame
.
width
,
height
:
cellFrame
.
height
)
newCellWrapperView
.
frame
=
CGRect
(
x
:
minX
,
y
:
cellFrame
.
minY
,
width
:
0
,
height
:
0
)
newCellShadowView
.
frame
=
newCellWrapperView
.
frame
newCellWrapperView
.
tag
=
AnimationItem
.
newCellWrapper
.
tag
newCellSnapshotView
.
tag
=
AnimationItem
.
newCell
.
tag
newCellShadowView
.
tag
=
AnimationItem
.
newCellShadow
.
tag
newCellShadowView
.
backgroundColor
=
backgroundColor
setShadow
(
to
:
newCellShadowView
)
}
// MARK: Snapshot of right side of collectionView
if
let
path
=
paths
[
safe
:
1
],
let
cell
=
collectionView
.
cellForItem
(
at
:
path
)
{
if
let
attributes
=
collectionView
.
collectionViewLayout
.
layoutAttributesForElements
(
in
:
cell
.
frame
),
let
targetAttributes
=
attributes
.
filter
({
$0
.
indexPath
==
path
})
.
first
,
let
_
=
collectionView
.
cellForItem
(
at
:
targetAttributes
.
indexPath
)
{
}
UIGraphicsBeginImageContextWithOptions
(
cell
.
bounds
.
size
,
true
,
0
)
if
let
context
=
UIGraphicsGetCurrentContext
()
{
cell
.
layer
.
render
(
in
:
context
)
}
newRightSideSnapshotView
.
image
=
UIGraphicsGetImageFromCurrentImageContext
()
UIGraphicsEndImageContext
()
newRightSideSnapshotView
.
frame
=
CGRect
(
x
:
bounds
.
maxX
,
y
:
cellFrame
.
minY
,
width
:
cell
.
bounds
.
width
,
height
:
cell
.
bounds
.
height
)
newRightSideSnapshotView
.
tag
=
AnimationItem
.
newRightSide
.
tag
setShadow
(
to
:
newRightSideSnapshotView
)
}
collectionView
.
visibleCells
.
forEach
{
$0
.
alpha
=
0
}
// MARK: Animate old cell out
let
oldCellLayer
=
oldCellSnapshotView
.
layer
var
oldCellNewBounds
=
oldCellLayer
.
bounds
oldCellNewBounds
.
size
=
.
zero
oldCellLayer
.
anchorPoint
=
up
?
CGPoint
(
x
:
0
,
y
:
0
)
:
CGPoint
(
x
:
0
,
y
:
1
)
oldCellLayer
.
position
=
up
?
CGPoint
(
x
:
minX
,
y
:
cellFrame
.
minY
)
:
CGPoint
(
x
:
minX
,
y
:
cellFrame
.
maxY
)
let
oldCellNewBoundsValue
=
AnimationValue
.
bounds
(
oldCellNewBounds
)
animate
(
oldCellSnapshotView
,
newValue
:
oldCellNewBoundsValue
,
item
:
.
oldCell
,
delay
:
delay
,
index
:
index
)
// MARK: Animate old right cell off-screen
let
oldRightSideLayer
=
oldRightSideSnapshotView
.
layer
oldRightSideLayer
.
anchorPoint
=
.
zero
oldRightSideLayer
.
position
=
CGPoint
(
x
:
cellFrame
.
maxX
+
space
,
y
:
cellFrame
.
minY
)
let
oldRightSideNewPosition
=
CGPoint
(
x
:
bounds
.
width
,
y
:
cellFrame
.
minY
)
let
oldRightSideNewValue
=
AnimationValue
.
position
(
oldRightSideNewPosition
)
animate
(
oldRightSideSnapshotView
,
newValue
:
oldRightSideNewValue
,
item
:
.
oldRightSide
,
index
:
index
)
// MARK: Animate buttons
UIView
.
animate
(
withDuration
:
duration
,
delay
:
duration
/
5
,
options
:
.
curveEaseInOut
,
animations
:
{
up
?
self
.
animateBottomButtons
()
:
self
.
animateTopButtons
()
},
completion
:
nil
)
if
up
,
let
movingButton
=
unified
[
safe
:
index
],
abs
(
oldIndex
-
index
)
<=
1
{
UIView
.
animate
(
withDuration
:
duration
,
delay
:
duration
/
3
,
options
:
UIView
.
AnimationOptions
.
curveEaseInOut
,
animations
:
{
if
up
{
let
insets
=
self
.
config
.
sideInsets
movingButton
.
frame
=
CGRect
(
x
:
insets
.
left
,
y
:
self
.
collectionView
.
frame
.
minY
-
40
,
width
:
bounds
.
width
-
insets
.
left
-
insets
.
right
,
height
:
30
)
}
},
completion
:
nil
)
UIView
.
animate
(
withDuration
:
duration
,
delay
:
duration
/
2
,
options
:
UIView
.
AnimationOptions
.
curveEaseInOut
,
animations
:
{
self
.
animateTopButtons
()
},
completion
:
nil
)
}
else
{
UIView
.
animate
(
withDuration
:
duration
,
delay
:
duration
/
4
,
options
:
UIView
.
AnimationOptions
.
curveEaseInOut
,
animations
:
{
up
?
self
.
animateTopButtons
()
:
self
.
animateBottomButtons
()
},
completion
:
nil
)
}
// MARK: Animate buttons textColor
for
button
in
unified
{
UIView
.
transition
(
with
:
button
,
duration
:
duration
/
2
,
options
:
UIView
.
AnimationOptions
.
transitionCrossDissolve
,
animations
:
{
let
color
=
button
===
movingItem
?
self
.
config
.
activeButtonColor
:
self
.
config
.
inactiveButtonsColor
button
.
setTitleColor
(
color
,
for
:
UIControl
.
State
.
normal
)
},
completion
:
nil
)
}
// MARK: Animate cell snapshot wrapper
let
newCellAnimationDelay
=
duration
/
3.7
+
delay
let
newCellWrapperLayer
=
newCellWrapperView
.
layer
newCellWrapperLayer
.
anchorPoint
=
up
?
CGPoint
(
x
:
0
,
y
:
1
)
:
CGPoint
(
x
:
0
,
y
:
0
)
newCellWrapperLayer
.
position
=
up
?
CGPoint
(
x
:
minX
,
y
:
cellFrame
.
maxY
)
:
CGPoint
(
x
:
minX
,
y
:
cellFrame
.
minY
)
newCellWrapperLayer
.
bounds
=
.
zero
var
newCellWrapperNewBounds
=
CGRect
.
zero
newCellWrapperNewBounds
.
size
=
cellFrame
.
size
let
newCellWrapperNewBoundsValue
=
AnimationValue
.
bounds
(
newCellWrapperNewBounds
)
newCellShadowView
.
layer
.
anchorPoint
=
newCellWrapperLayer
.
anchorPoint
newCellShadowView
.
layer
.
position
=
newCellWrapperLayer
.
position
newCellShadowView
.
layer
.
bounds
=
.
zero
animate
(
newCellShadowView
,
newValue
:
newCellWrapperNewBoundsValue
,
item
:
.
newCellShadow
,
delay
:
newCellAnimationDelay
,
index
:
index
)
animate
(
newCellWrapperView
,
newValue
:
newCellWrapperNewBoundsValue
,
item
:
.
newCellWrapper
,
delay
:
newCellAnimationDelay
,
index
:
index
)
// MARK: Animate cell snapshot
let
newCellSnapshotLayer
=
newCellSnapshotView
.
layer
newCellSnapshotLayer
.
anchorPoint
=
.
zero
newCellSnapshotLayer
.
position
=
up
?
CGPoint
(
x
:
0
,
y
:
-
cellFrame
.
height
)
:
CGPoint
(
x
:
0
,
y
:
0
)
let
newCellNewPosition
=
CGPoint
.
zero
let
newCellNewValue
=
AnimationValue
.
position
(
newCellNewPosition
)
animate
(
newCellSnapshotView
,
newValue
:
newCellNewValue
,
item
:
AnimationItem
.
newCell
,
delay
:
newCellAnimationDelay
,
index
:
index
)
// MARK: Animate new right side
let
position
=
CGPoint
(
x
:
cellFrame
.
maxX
+
space
,
y
:
cellFrame
.
minY
)
let
newRightSideLayer
=
newRightSideSnapshotView
.
layer
newRightSideLayer
.
anchorPoint
=
.
zero
newRightSideLayer
.
position
=
CGPoint
(
x
:
bounds
.
width
+
space
,
y
:
cellFrame
.
minY
)
let
newRightSideNewValue
=
AnimationValue
.
position
(
position
)
let
newRightSideDelay
=
duration
+
newCellAnimationDelay
animate
(
newRightSideSnapshotView
,
newValue
:
newRightSideNewValue
,
item
:
.
newRightSide
,
duration
:
config
.
animationDuration
*
2
,
delay
:
newRightSideDelay
,
index
:
index
)
self
.
newRightSideSnapshot
=
newRightSideSnapshotView
animationInProcess
=
true
}
/// Expand next item in list
public
func
expandNext
()
{
expand
(
at
:
expandedItemIndex
+
1
)
}
/// Expand previous item in list
public
func
expandPrevious
()
{
expand
(
at
:
expandedItemIndex
-
1
)
}
public
func
reloadData
()
{
for
button
in
topViews
+
bottomViews
{
button
.
removeFromSuperview
()
}
topViews
=
[]
bottomViews
=
[]
setupVerticalStack
()
setNeedsLayout
()
layoutIfNeeded
()
}
// MARK: Private
@objc
fileprivate
func
didTapped
(
_
button
:
UIButton
)
{
let
unifiedButtons
=
topViews
+
bottomViews
guard
let
index
=
unifiedButtons
.
firstIndex
(
of
:
button
)
else
{
return
}
delegate
?
.
glidingCollection
(
self
,
didSelectItemAt
:
index
)
expand
(
at
:
index
)
}
fileprivate
func
resetViews
()
{
// Remove temporary layer
newRightSideSnapshot
=
nil
// Unhide visibleCells
collectionView
.
visibleCells
.
forEach
{
$0
.
alpha
=
1
}
// Remove all snapshot layers
removeSnapshots
()
// Set new index to temporary property
lastExpandedItemIndex
=
expandedItemIndex
animationViewsDictionary
=
[:]
}
fileprivate
func
removeSnapshots
()
{
let
tags
=
AnimationItem
.
all
.
map
{
$0
.
tag
}
for
subview
in
subviews
+
containerView
.
subviews
{
if
tags
.
contains
(
subview
.
tag
)
{
subview
.
removeFromSuperview
()
}
}
}
@objc
fileprivate
func
handlePanGesture
(
_
gesture
:
UIPanGestureRecognizer
)
{
let
location
=
gesture
.
location
(
in
:
self
)
let
velocity
=
gesture
.
velocity
(
in
:
self
)
switch
gesture
.
state
{
case
.
began
:
gestureStartPosition
=
location
case
.
changed
:
guard
containerView
.
contentOffset
.
y
==
0
else
{
break
}
let
up
=
location
.
y
>
gestureStartPosition
.
y
let
range
=
abs
(
location
.
y
-
gestureStartPosition
.
y
)
if
range
>
100
||
abs
(
velocity
.
y
)
>
300
&&
abs
(
velocity
.
x
)
<
300
{
up
?
self
.
expandPrevious
()
:
self
.
expandNext
()
gesture
.
isEnabled
=
false
gesture
.
isEnabled
=
true
}
default
:
break
}
}
}
// MARK: - Animations
private
typealias
AniView
=
(
view
:
UIView
,
animation
:
CAAnimation
)
private
enum
AnimationValue
{
case
bounds
(
CGRect
)
case
position
(
CGPoint
)
var
key
:
String
{
switch
self
{
case
.
bounds
(
_
):
return
"bounds"
case
.
position
(
_
):
return
"position"
}
}
}
private
enum
AnimationItem
:
String
{
case
oldCell
,
oldRightSide
case
newCell
,
newCellWrapper
,
newCellShadow
,
newRightSide
static
var
all
:
[
AnimationItem
]
{
return
[
AnimationItem
.
oldCell
,
.
oldRightSide
,
.
newCell
,
.
newCellWrapper
,
.
newRightSide
,
.
newCellShadow
]
}
var
tag
:
Int
{
switch
self
{
case
.
oldCell
:
return
1
case
.
oldRightSide
:
return
2
case
.
newCell
:
return
3
case
.
newCellWrapper
:
return
4
case
.
newRightSide
:
return
5
case
.
newCellShadow
:
return
6
}
}
}
extension
GlidingCollection
:
CAAnimationDelegate
{
fileprivate
func
speedUp
(
_
layer
:
CALayer
,
reverse
:
Bool
)
{
let
time
=
CACurrentMediaTime
()
let
timeOffset
=
layer
.
convertTime
(
time
,
from
:
nil
)
layer
.
timeOffset
=
timeOffset
layer
.
beginTime
=
CACurrentMediaTime
()
layer
.
speed
=
reverse
?
-
2.0
:
3.0
}
@discardableResult
fileprivate
func
animate
(
_
view
:
UIView
,
newValue
:
AnimationValue
,
item
:
AnimationItem
,
duration
:
Double
?
=
nil
,
delay
:
Double
=
0
,
index
:
Int
)
->
CAAnimation
{
let
key
=
newValue
.
key
let
layer
=
view
.
layer
let
animation
=
CABasicAnimation
(
keyPath
:
key
)
switch
newValue
{
case
.
bounds
(
let
toBounds
):
animation
.
fromValue
=
NSValue
(
cgRect
:
layer
.
bounds
)
animation
.
toValue
=
NSValue
(
cgRect
:
toBounds
)
layer
.
bounds
=
toBounds
case
.
position
(
let
toPosition
):
animation
.
fromValue
=
NSValue
(
cgPoint
:
layer
.
position
)
animation
.
toValue
=
NSValue
(
cgPoint
:
toPosition
)
layer
.
position
=
toPosition
}
animation
.
isRemovedOnCompletion
=
false
animation
.
fillMode
=
CAMediaTimingFillMode
.
backwards
animation
.
timingFunction
=
CAMediaTimingFunction
(
name
:
CAMediaTimingFunctionName
.
easeInEaseOut
)
animation
.
duration
=
duration
??
config
.
animationDuration
animation
.
delegate
=
self
animation
.
beginTime
=
CACurrentMediaTime
()
+
delay
let
animationId
=
"
\(
item
.
rawValue
)
,
\(
index
)
"
animation
.
setValue
(
animationId
,
forKey
:
"id"
)
animationViewsDictionary
[
animationId
]
=
(
view
:
view
,
animation
:
animation
)
layer
.
add
(
animation
,
forKey
:
animationId
)
return
animation
}
/// :nodoc:
public
func
animationDidStop
(
_
anim
:
CAAnimation
,
finished
flag
:
Bool
)
{
if
let
id
=
anim
.
value
(
forKey
:
"id"
)
as?
String
,
let
aniview
=
animationViewsDictionary
[
id
]
{
let
components
=
id
.
components
(
separatedBy
:
","
)
let
index
=
Int
(
components
[
safe
:
1
]
??
""
)
??
0
let
item
=
AnimationItem
(
rawValue
:
components
.
first
??
""
)
??
AnimationItem
.
oldCell
if
index
!=
expandedItemIndex
,
item
!=
.
newRightSide
{
aniview
.
view
.
removeFromSuperview
()
}
switch
item
{
case
.
oldRightSide
:
collectionView
.
isUserInteractionEnabled
=
true
case
.
newCell
where
index
==
expandedItemIndex
&&
aniview
.
animation
.
beginTime
==
anim
.
beginTime
:
let
paths
=
collectionView
.
indexPathsForVisibleItems
.
sorted
{
$0
.
item
<
$1
.
item
}
guard
let
path
=
paths
.
first
,
let
cell
=
collectionView
.
cellForItem
(
at
:
path
)
else
{
break
}
cell
.
alpha
=
1
aniview
.
view
.
removeFromSuperview
()
// Remove also shadow view
if
let
shadowAniview
=
getAniview
(
of
:
AnimationItem
.
newCellShadow
,
at
:
index
)
{
shadowAniview
.
view
.
removeFromSuperview
()
}
case
.
newRightSide
where
index
==
expandedItemIndex
&&
aniview
.
animation
.
beginTime
==
anim
.
beginTime
:
resetViews
()
animationInProcess
=
false
default
:
break
}
}
}
fileprivate
func
animateTopButtons
()
{
let
buttonHeight
=
config
.
buttonsFont
.
pointSize
*
1.2
var
minY
=
collectionView
.
frame
.
minY
-
buttonHeight
let
insets
=
config
.
sideInsets
var
topFrame
=
CGRect
(
x
:
insets
.
left
,
y
:
0
,
width
:
bounds
.
width
-
insets
.
left
-
insets
.
right
,
height
:
buttonHeight
)
for
button
in
topViews
.
reversed
()
{
if
button
===
topViews
.
last
{
button
.
transform
=
.
identity
}
else
{
button
.
transform
=
scaledTransform
}
topFrame
.
origin
.
y
=
minY
-
config
.
buttonsSpacing
button
.
frame
=
topFrame
minY
-=
buttonHeight
+
config
.
buttonsSpacing
}
}
fileprivate
func
animateBottomButtons
()
{
var
maxY
=
collectionView
.
frame
.
maxY
let
insets
=
config
.
sideInsets
let
buttonHeight
=
config
.
buttonsFont
.
pointSize
*
1.2
var
topFrame
=
CGRect
(
x
:
insets
.
left
,
y
:
0
,
width
:
bounds
.
width
-
insets
.
left
-
insets
.
right
,
height
:
buttonHeight
)
for
button
in
bottomViews
{
button
.
transform
=
scaledTransform
topFrame
.
origin
.
y
=
maxY
+
config
.
buttonsSpacing
button
.
frame
=
topFrame
maxY
=
button
.
frame
.
maxY
}
}
fileprivate
func
getAniview
(
of
item
:
AnimationItem
,
at
index
:
Int
)
->
AniView
?
{
let
id
=
"
\(
item
.
rawValue
)
,
\(
index
)
"
return
animationViewsDictionary
[
id
]
}
}
// MARK: - GlidingLayoutDelegate
extension
GlidingCollection
:
GlidingLayoutDelegate
{
func
collectionViewDidScroll
()
{
for
cell
in
collectionView
.
visibleCells
where
cell
.
alpha
==
0
{
cell
.
alpha
=
1
}
guard
animationInProcess
else
{
return
}
removeSnapshots
()
}
}
// MARK: - ScrollView Delegate
extension
GlidingCollection
:
UIScrollViewDelegate
{
/// Must call super if you override this method.
public
func
scrollViewDidScroll
(
_
scrollView
:
UIScrollView
)
{
guard
let
count
=
dataSource
?
.
numberOfItems
(
in
:
self
),
expandedItemIndex
==
0
||
expandedItemIndex
==
count
-
1
else
{
return
}
let
top
=
expandedItemIndex
==
0
let
y
=
scrollView
.
contentOffset
.
y
let
condition
=
top
?
y
>
0
:
y
<
0
if
condition
{
scrollView
.
contentOffset
.
y
=
0
}
}
}
Em-call/GlidingConfig.swift
0 → 100644
View file @
27f01c03
//
// GlidingCollection.swift
// GlidingCollection
//
import
UIKit
/// Configuration struct.
/// Override `shared` property to apply new configuration.
public
struct
GlidingConfig
{
/// Shared instance of configuration. /// Override this property or change values directly.
public
static
var
shared
=
GlidingConfig
()
/// Side insets of GlidiingCollection view. /// Only left & right side insets will take effect.
public
var
sideInsets
=
UIEdgeInsets
(
top
:
10
,
left
:
30
,
bottom
:
10
,
right
:
30
)
/// Duration of animation between GlidingCollection sections.
public
var
animationDuration
:
Double
=
0.3
/// Spacing between vertical stack of items.
public
var
buttonsSpacing
:
CGFloat
=
15
/// Font of each element in vertical stack.
public
var
buttonsFont
=
UIFont
.
systemFont
(
ofSize
:
16
)
/// Scale factor of inactive sections buttons.
public
var
buttonsScaleFactor
:
CGFloat
=
0.65
/// Active section button color.
public
var
activeButtonColor
:
UIColor
=
.
darkGray
/// Inactive sections buttons color.
public
var
inactiveButtonsColor
:
UIColor
=
.
lightGray
/// Space between collectionView's cells.
public
var
cardsSpacing
:
CGFloat
=
30
/// Size of collectionView's cells.
public
var
cardsSize
=
CGSize
(
width
:
round
(
UIScreen
.
main
.
bounds
.
width
*
0.35
),
height
:
round
(
UIScreen
.
main
.
bounds
.
height
*
0.35
))
/// Apply parallax effect to horizontal cards.
public
var
isParallaxEnabled
=
true
/// Shadow color.
public
var
cardShadowColor
=
UIColor
.
black
/// Shadow offset: width - horizontal; height - vertical.
public
var
cardShadowOffset
=
CGSize
(
width
:
0
,
height
:
5
)
/// Shadow radius or blur.
public
var
cardShadowRadius
:
CGFloat
=
7
/// Shadow opacity.
public
var
cardShadowOpacity
:
Float
=
0.3
}
Em-call/GlidingLayout.swift
0 → 100644
View file @
27f01c03
//
// GlidingCollection.swift
// GlidingCollection
//
import
UIKit
/// :nodoc:
protocol
GlidingLayoutDelegate
{
func
collectionViewDidScroll
()
}
final
class
GlidingLayout
:
UICollectionViewFlowLayout
{
var
delegate
:
GlidingLayoutDelegate
?
override
func
targetContentOffset
(
forProposedContentOffset
proposedContentOffset
:
CGPoint
,
withScrollingVelocity
velocity
:
CGPoint
)
->
CGPoint
{
guard
let
collectionView
=
self
.
collectionView
else
{
return
proposedContentOffset
}
let
pageWidth
=
itemSize
.
width
+
minimumLineSpacing
let
rawPageValue
=
collectionView
.
contentOffset
.
x
/
pageWidth
let
currentPage
=
velocity
.
x
>
0
?
floor
(
rawPageValue
)
:
ceil
(
rawPageValue
)
let
nextPage
=
velocity
.
x
>
0
?
ceil
(
rawPageValue
)
:
floor
(
rawPageValue
)
let
pannedLessThanPage
=
abs
(
1
+
currentPage
-
rawPageValue
)
>
0.3
let
flicked
=
abs
(
velocity
.
x
)
>
0.3
var
offset
=
proposedContentOffset
if
pannedLessThanPage
&&
flicked
{
offset
.
x
=
nextPage
*
pageWidth
}
else
{
offset
.
x
=
round
(
rawPageValue
)
*
pageWidth
}
return
offset
}
override
func
shouldInvalidateLayout
(
forBoundsChange
newBounds
:
CGRect
)
->
Bool
{
delegate
?
.
collectionViewDidScroll
()
return
true
}
override
func
layoutAttributesForElements
(
in
rect
:
CGRect
)
->
[
UICollectionViewLayoutAttributes
]?
{
guard
let
attributes
=
super
.
layoutAttributesForElements
(
in
:
rect
)
else
{
return
nil
}
guard
GlidingConfig
.
shared
.
isParallaxEnabled
else
{
return
attributes
}
let
transformed
=
attributes
.
map
{
transformLayoutAttributes
(
$0
)
}
return
transformed
}
private
func
transformLayoutAttributes
(
_
attributes
:
UICollectionViewLayoutAttributes
)
->
UICollectionViewLayoutAttributes
{
guard
let
collectionView
=
self
.
collectionView
else
{
return
attributes
}
let
startOffset
=
(
attributes
.
frame
.
origin
.
x
-
collectionView
.
contentOffset
.
x
-
sectionInset
.
left
)
/
attributes
.
frame
.
width
let
maxScale
:
CGFloat
=
1.2
let
minScale
:
CGFloat
=
1.0
let
divided
=
abs
(
startOffset
)
/
10
let
scale
=
max
(
minScale
,
min
(
maxScale
,
1.0
+
divided
))
if
let
contentView
=
collectionView
.
cellForItem
(
at
:
attributes
.
indexPath
)?
.
contentView
,
let
parallaxView
=
contentView
.
viewWithTag
(
99
)
{
parallaxView
.
transform
=
CGAffineTransform
(
scaleX
:
scale
,
y
:
scale
)
}
return
attributes
}
}
Em-call/Protocols/GlidingCollectionDataSource.swift
0 → 100644
View file @
27f01c03
//
// GlidingCollectionDataSource.swift
// GlidingCollection
//
import
Foundation
/// Datasource protocol of GlidingCollection.
public
protocol
GlidingCollectionDatasource
{
/// Number of items in vertical stack of items.
///
/// - Parameter collection: GlidingCollection
/// - Returns: number of items in stack
func
numberOfItems
(
in
collection
:
GlidingCollection
)
->
Int
/// Item at given index.
///
/// - Parameters:
/// - collection: GlidingCollection
/// - index: index of item
/// - Returns: item title
func
glidingCollection
(
_
collection
:
GlidingCollection
,
itemAtIndex
index
:
Int
)
->
String
}
Em-call/Protocols/GlidingCollectionDelegate.swift
0 → 100644
View file @
27f01c03
//
// GlidingCollectionDelegate.swift
// GlidingCollection
//
import
Foundation
/// This delegate provides methods which can notify when transition starts/ends & when item was selected.
public
protocol
GlidingCollectionDelegate
{
/// This method will be called before starting
/// transition from one item to another.
///
/// - Parameters:
/// - collection: GlidingCollection
/// - index: Index of item that being expand.
func
glidingCollection
(
_
collection
:
GlidingCollection
,
willExpandItemAt
index
:
Int
)
/// This method will be called when transition
/// between items was finished.
///
/// - Parameters:
/// - collection: GlidingCollection
/// - index: Index of expanded item.
func
glidingCollection
(
_
collection
:
GlidingCollection
,
didExpandItemAt
index
:
Int
)
/// This method will be called if selected
/// one of the element of vertical stack.
///
/// - Parameters:
/// - collection: GlidingCollection
/// - index: Index of selected item.
func
glidingCollection
(
_
collection
:
GlidingCollection
,
didSelectItemAt
index
:
Int
)
}
// This extension will make all this methods optional so you can implement just part of this protocol if you wish.
public
extension
GlidingCollectionDelegate
{
func
glidingCollection
(
_
collection
:
GlidingCollection
,
willExpandItemAt
index
:
Int
)
{
}
func
glidingCollection
(
_
collection
:
GlidingCollection
,
didExpandItemAt
index
:
Int
)
{
}
func
glidingCollection
(
_
collection
:
GlidingCollection
,
didSelectItemAt
index
:
Int
)
{
}
}
Em-call/VC/ElectricTableViewController.swift
View file @
27f01c03
...
...
@@ -7,28 +7,49 @@
import
UIKit
class
ElectricTableViewController
:
UIViewController
,
UITableViewDataSource
,
UITableViewDelegate
,
UITextFieldDelegate
class
ElectricTableViewController
:
UIViewController
,
UITableViewDataSource
,
UITableViewDelegate
,
UITextFieldDelegate
,
UITextViewDelegate
{
//let trackList = Track.getTrackList()
var
settingsLauncher
:
SettingsLauncher
=
SettingsLauncher
()
@IBOutlet
weak
var
glidingView
:
GlidingCollection
!
fileprivate
var
collectionView
:
UICollectionView
!
@IBOutlet
weak
var
descTextView
:
UITextView
!
@IBOutlet
weak
var
descProblem
:
UITextField
!
let
cellReuseIdentifier
=
"cell"
var
address
=
"Unknow address"
var
dateAndTime
=
"2022/02/23"
var
contact
=
"+1 123 112 11 22"
var
card
=
"**** **** **** 1234"
// var storyboard = UIStoryboard(name: "Main", bundle: nil)
// private var images = [UIImage(named: "plus")!]
// private var images = [UIImage()]
fileprivate
var
images
:
[
UIImage
?]
=
[]
//let cellReuseIdentifier = "cell"
@IBOutlet
weak
var
tableView
:
UITableView
!
override
func
viewDidLoad
()
{
super
.
viewDidLoad
()
// Register the table view cell class and its reuse id
// loadImages()
settingsLauncher
.
delegate
=
self
// Register the table view cell class and its reuse id
self
.
tableView
.
register
(
UITableViewCell
.
self
,
forCellReuseIdentifier
:
cellReuseIdentifier
)
tableView
.
rowHeight
=
65
tableView
.
delegate
=
self
tableView
.
dataSource
=
self
descProblem
.
delegate
=
self
descTextView
.
delegate
=
self
setup
()
}
override
func
viewWillAppear
(
_
animated
:
Bool
)
{
super
.
viewWillAppear
(
animated
)
collectionView
.
reloadData
()
collectionView
.
collectionViewLayout
.
invalidateLayout
()
}
@IBAction
func
BookNowClick
(
_
sender
:
Any
)
{
let
storyboard
=
UIStoryboard
(
name
:
"Main"
,
bundle
:
nil
)
...
...
@@ -41,16 +62,23 @@ class ElectricTableViewController:UIViewController,UITableViewDataSource, UITabl
navigationController
?
.
pushViewController
(
vc
,
animated
:
true
)
}
// @IBAction func tapGesture(_ sender: Any) { view.endEditing(true) }
func
textFieldShouldReturn
(
_
textField
:
UITextField
)
->
Bool
{
descProblem
.
resignFirstResponder
()
@IBAction
func
pressAddPhoto
(
_
sender
:
Any
)
{
guard
let
navVC
=
self
.
navigationController
else
{
return
}
settingsLauncher
.
showSettings
(
navigVC
:
navVC
)
}
func
loadImages
()
{
}
// MARK: - Table view data source
/* override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1 }*/
func
textFieldShouldReturn
(
_
textField
:
UITextField
)
->
Bool
{
descTextView
.
resignFirstResponder
()
}
// MARK: - Table view data source
func
tableView
(
_
tableView
:
UITableView
,
numberOfRowsInSection
section
:
Int
)
->
Int
{
switch
section
{
case
0
:
return
1
...
...
@@ -66,15 +94,14 @@ class ElectricTableViewController:UIViewController,UITableViewDataSource, UITabl
}
func
tableView
(
_
tableView
:
UITableView
,
titleForHeaderInSection
section
:
Int
)
->
String
?
{
// let rets:String? = mainTable.tableView(tableView, titleForHeaderInSection: section)
// return rets!
switch
section
{
case
0
:
return
(
"Work location"
)
case
1
:
return
(
"Date and Time"
)
case
2
:
return
(
"Your contacts"
)
case
3
:
return
(
"Payment"
)
default
:
return
(
"Work location"
)
}
// return ("Work location")
}
}
func
tableView
(
_
tableView
:
UITableView
,
cellForRowAt
indexPath
:
IndexPath
)
->
UITableViewCell
{
...
...
@@ -120,6 +147,27 @@ class ElectricTableViewController:UIViewController,UITableViewDataSource, UITabl
}
}
// MARK: - Setup
extension
ElectricTableViewController
{
func
setup
()
{
setupGlidingCollectionView
()
}
private
func
setupGlidingCollectionView
()
{
glidingView
.
dataSource
=
self
let
nib
=
UINib
(
nibName
:
"CollectionCell"
,
bundle
:
nil
)
collectionView
=
glidingView
.
collectionView
collectionView
.
register
(
nib
,
forCellWithReuseIdentifier
:
"Cell"
)
collectionView
.
delegate
=
self
collectionView
.
dataSource
=
self
collectionView
.
backgroundColor
=
glidingView
.
backgroundColor
}
}
extension
ElectricTableViewController
:
MapViewControllerDelegate
{
func
delegateClick
(
text
:
String
)
{
address
=
text
...
...
@@ -144,72 +192,67 @@ extension ElectricTableViewController:CalendarViewControllerDelegate {
}
}
// MARK: - Navigation
/*
// In a storyboard-based application, you will often want to do a little preparation before navigation
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
// Проверяем что сработал segue с нужным идентификатором
// Это тот идентификатор, который мы указали в сториборде
if segue.identifier == "MapViewController"
{
// Здесь объектом sender является ячейка, на которую нажимает юзер
// Получаем indexPath выбранной ячейки с помощью метода indexPathForCell:
let indexPath = self.tableView.indexPath((sender as! UITableViewCell))
// Получаем объект Product под нужным индексом
let product = self.allData[indexPath!.row]
// Получаем контроллер, на который юзер попадёт с этим segue
let detailVC: DetailVC = segue.destinationViewController as! DetailVC
// Задаём атрибут Product в DetailVC
detailVC.product = product
}
}*/
/*
// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
*/
/*
// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
}
*/
/*
// Override to support conditional rearranging of the table view.
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the item to be re-orderable.
return true
extension
ElectricTableViewController
:
SettingsLauncherDelegate
{
func
settingsDelegateClick
(
img
:
UIImage
?)
{
if
img
!=
nil
{
images
.
append
(
img
!
)
}
collectionView
.
reloadData
()
}
*/
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
// MARK: - CollectionView 🎛
extension
ElectricTableViewController
:
UICollectionViewDataSource
,
UICollectionViewDelegate
{
func
collectionView
(
_
collectionView
:
UICollectionView
,
numberOfItemsInSection
section
:
Int
)
->
Int
{
// let section = glidingView.expandedItemIndex
return
images
.
count
}
func
collectionView
(
_
collectionView
:
UICollectionView
,
cellForItemAt
indexPath
:
IndexPath
)
->
UICollectionViewCell
{
guard
let
cell
=
collectionView
.
dequeueReusableCell
(
withReuseIdentifier
:
"Cell"
,
for
:
indexPath
)
as?
CollectionCell
else
{
return
UICollectionViewCell
()
}
////let section = glidingView.expandedItemIndex
if
images
.
count
>
0
{
let
image
=
images
[
indexPath
.
row
]
// let image = images[0]
cell
.
imageView
.
image
=
image
}
*/
cell
.
contentView
.
clipsToBounds
=
true
let
layer
=
cell
.
layer
let
config
=
GlidingConfig
.
shared
layer
.
shadowOffset
=
config
.
cardShadowOffset
layer
.
shadowColor
=
config
.
cardShadowColor
.
cgColor
layer
.
shadowOpacity
=
config
.
cardShadowOpacity
layer
.
shadowRadius
=
config
.
cardShadowRadius
layer
.
shouldRasterize
=
true
layer
.
rasterizationScale
=
UIScreen
.
main
.
scale
return
cell
}
func
collectionView
(
_
collectionView
:
UICollectionView
,
didSelectItemAt
indexPath
:
IndexPath
)
{
let
section
=
glidingView
.
expandedItemIndex
let
item
=
indexPath
.
item
print
(
"Selected item #
\(
item
)
in section #
\(
section
)
"
)
}
}
// MARK: - Gliding Collection 🎢
extension
ElectricTableViewController
:
GlidingCollectionDatasource
{
func
numberOfItems
(
in
collection
:
GlidingCollection
)
->
Int
{
// return items.count
return
0
}
func
glidingCollection
(
_
collection
:
GlidingCollection
,
itemAtIndex
index
:
Int
)
->
String
{
// return "– " + items[index]
return
"– "
}
}
Em-call/VC/HandmanViewController.swift
View file @
27f01c03
...
...
@@ -10,15 +10,25 @@ import UIKit
class
HandmanViewController
:
UIViewController
,
UITableViewDataSource
,
UITableViewDelegate
//, MapViewControllerDelegate, CalendarViewController
Delegate
UITableViewDelegate
,
UITextView
Delegate
{
var
settingsLauncher
:
SettingsLauncher
=
SettingsLauncher
()
@IBOutlet
weak
var
tableView
:
UITableView
!
@IBOutlet
weak
var
descProblem
:
UITextField
!
@IBOutlet
weak
var
descTextView
:
UITextView
!
@IBOutlet
weak
var
addr
:
UILabel
!
//let trackList = Track.getTrackList()
@IBOutlet
weak
var
glidingView
:
GlidingCollection
!
fileprivate
var
collectionView
:
UICollectionView
!
fileprivate
var
items
=
[
"gloves"
,
"boots"
,
"bindings"
,
"hoodie"
]
// fileprivate var images: [[UIImage?]] = []
// fileprivate var images = [UIImage(named: "plus")!]
fileprivate
var
images
:
[
UIImage
?]
=
[]
let
cellReuseIdentifier
=
"cell"
var
address
=
"Unknow address"
var
dateAndTime
=
"2022/02/23"
var
contact
=
"+1 123 112 11 22"
...
...
@@ -31,9 +41,25 @@ class HandmanViewController: UIViewController, UITableViewDataSource,
tableView
.
rowHeight
=
45
tableView
.
delegate
=
self
tableView
.
dataSource
=
self
descTextView
.
delegate
=
self
settingsLauncher
.
delegate
=
self
setup
()
}
override
func
viewWillAppear
(
_
animated
:
Bool
)
{
super
.
viewWillAppear
(
animated
)
collectionView
.
reloadData
()
collectionView
.
collectionViewLayout
.
invalidateLayout
()
}
@IBAction
func
pressAddPhoto
(
_
sender
:
Any
)
{
guard
let
navVC
=
self
.
navigationController
else
{
return
}
settingsLauncher
.
showSettings
(
navigVC
:
navVC
)
}
@IBAction
func
BOOK_NOW_Click
(
_
sender
:
Any
)
{
let
storyboard
=
UIStoryboard
(
name
:
"Main"
,
bundle
:
nil
)
let
vc
:
UIViewController
...
...
@@ -47,7 +73,7 @@ class HandmanViewController: UIViewController, UITableViewDataSource,
// @IBAction func tapGesture(_ sender: Any) {view.endEditing(true) }
func
textFieldShouldReturn
(
_
textField
:
UITextField
)
->
Bool
{
desc
Problem
.
resignFirstResponder
()
desc
TextView
.
resignFirstResponder
()
}
func
tableView
(
_
tableView
:
UITableView
,
numberOfRowsInSection
section
:
Int
)
->
Int
{
...
...
@@ -112,12 +138,78 @@ class HandmanViewController: UIViewController, UITableViewDataSource,
}
}
/*// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}*/
// MARK: - Setup
extension
HandmanViewController
{
func
setup
()
{
setupGlidingCollectionView
()
// loadImages()
}
private
func
setupGlidingCollectionView
()
{
glidingView
.
dataSource
=
self
let
nib
=
UINib
(
nibName
:
"CollectionCell"
,
bundle
:
nil
)
collectionView
=
glidingView
.
collectionView
collectionView
.
register
(
nib
,
forCellWithReuseIdentifier
:
"Cell"
)
collectionView
.
delegate
=
self
collectionView
.
dataSource
=
self
collectionView
.
backgroundColor
=
glidingView
.
backgroundColor
}
}
// MARK: - CollectionView 🎛
extension
HandmanViewController
:
UICollectionViewDataSource
,
UICollectionViewDelegate
{
func
collectionView
(
_
collectionView
:
UICollectionView
,
numberOfItemsInSection
section
:
Int
)
->
Int
{
// let section = glidingView.expandedItemIndex
return
images
.
count
}
func
collectionView
(
_
collectionView
:
UICollectionView
,
cellForItemAt
indexPath
:
IndexPath
)
->
UICollectionViewCell
{
guard
let
cell
=
collectionView
.
dequeueReusableCell
(
withReuseIdentifier
:
"Cell"
,
for
:
indexPath
)
as?
CollectionCell
else
{
return
UICollectionViewCell
()
}
////let section = glidingView.expandedItemIndex
if
images
.
count
>
0
{
let
image
=
images
[
indexPath
.
row
]
// let image = images[0]
cell
.
imageView
.
image
=
image
}
cell
.
contentView
.
clipsToBounds
=
true
let
layer
=
cell
.
layer
let
config
=
GlidingConfig
.
shared
layer
.
shadowOffset
=
config
.
cardShadowOffset
layer
.
shadowColor
=
config
.
cardShadowColor
.
cgColor
layer
.
shadowOpacity
=
config
.
cardShadowOpacity
layer
.
shadowRadius
=
config
.
cardShadowRadius
layer
.
shouldRasterize
=
true
layer
.
rasterizationScale
=
UIScreen
.
main
.
scale
return
cell
}
func
collectionView
(
_
collectionView
:
UICollectionView
,
didSelectItemAt
indexPath
:
IndexPath
)
{
let
section
=
glidingView
.
expandedItemIndex
let
item
=
indexPath
.
item
print
(
"Selected item #
\(
item
)
in section #
\(
section
)
"
)
}
}
// MARK: - Gliding Collection 🎢
extension
HandmanViewController
:
GlidingCollectionDatasource
{
func
numberOfItems
(
in
collection
:
GlidingCollection
)
->
Int
{
// return items.count
return
0
}
func
glidingCollection
(
_
collection
:
GlidingCollection
,
itemAtIndex
index
:
Int
)
->
String
{
// return "– " + items[index]
return
"– "
}
}
extension
HandmanViewController
:
MapViewControllerDelegate
{
func
delegateClick
(
text
:
String
)
{
...
...
@@ -141,3 +233,12 @@ extension HandmanViewController:CalendarViewControllerDelegate {
tableView
.
reloadData
()
}
}
extension
HandmanViewController
:
SettingsLauncherDelegate
{
func
settingsDelegateClick
(
img
:
UIImage
?)
{
if
img
!=
nil
{
images
.
append
(
img
!
)
}
collectionView
.
reloadData
()
}
}
Em-call/VC/PlumbersViewController.swift
View file @
27f01c03
...
...
@@ -9,57 +9,38 @@ import UIKit
class
PlumbersViewController
:
UIViewController
,
UITableViewDataSource
,
UITableViewDelegate
,
UITextFieldDelegate
,
UIImagePickerControllerDelegate
,
UINavigationControllerDelegate
class
PlumbersViewController
:
UIViewController
,
UITableViewDataSource
,
UITableViewDelegate
,
UITextFieldDelegate
,
UIImagePickerControllerDelegate
,
UINavigationControllerDelegate
,
UITextViewDelegate
{
var
settingsLauncher
:
SettingsLauncher
=
SettingsLauncher
()
@IBOutlet
weak
var
tabBar
:
UITabBar
!
var
isfirstTimeTransform
:
Bool
=
true
;
var
TRANSFORM_CELL_VALUE
=
CGAffineTransform
(
scaleX
:
0.8
,
y
:
0.8
)
let
ANIMATION_SPEED
=
0.2
@IBOutlet
weak
var
descProblem
:
UITextField
!
@IBOutlet
weak
var
glidingView
:
GlidingCollection
!
fileprivate
var
collectionView
:
UICollectionView
!
// let imagePickerController = UIImagePickerController()
let
cellReuseIdentifier
=
"cell"
var
address
=
"Unknow address"
var
dateAndTime
=
"2022/02/23"
var
contact
=
"+1 123 112 11 22"
var
card
=
"**** **** **** 1234"
private
var
images
=
[
UIImage
(
named
:
"plus"
)
!
]
@IBOutlet
weak
var
collectionView
:
UICollectionView
!
{
didSet
{
collectionView
.
delegate
=
self
collectionView
.
dataSource
=
self
collectionView
.
register
(
UINib
.
init
(
nibName
:
"PhotoCellCollectionViewCell"
,
bundle
:
nil
),
forCellWithReuseIdentifier
:
"photoCell"
)
collectionView
.
backgroundColor
=
.
clear
let
layout
=
UICollectionViewFlowLayout
()
layout
.
scrollDirection
=
.
horizontal
collectionView
.
isPagingEnabled
=
true
collectionView
.
isScrollEnabled
=
true
collectionView
.
setContentOffset
(
CGPoint
(
x
:
0
,
y
:
0
),
animated
:
true
)
}
}
fileprivate
var
images
:
[
UIImage
?]
=
[]
@IBOutlet
weak
var
textViewDesc
:
UITextView
!
@IBOutlet
weak
var
tableView
:
UITableView
!
override
func
viewDidLoad
()
{
super
.
viewDidLoad
()
// imagePickerController.delegate = self
self
.
tableView
.
register
(
UITableViewCell
.
self
,
forCellReuseIdentifier
:
cellReuseIdentifier
)
tableView
.
rowHeight
=
65
tableView
.
delegate
=
self
tableView
.
dataSource
=
self
descProblem
.
delegate
=
self
textViewDesc
.
delegate
=
self
settingsLauncher
.
delegate
=
self
/*
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
featuredVideos = UICollectionView(frame: UIScreen.mainScreen().bounds, collectionViewLayout: layout)
collectionView!.setContentOffset(CGPoint(x: 0,y: 0), animated: true)
featuredVideos!.registerClass(CollectionViewCell.self, forCellWithReuseIdentifier: "cellId")
view.addSubview(featuredVideos!)*/
setup
()
}
@IBAction
func
pressAddPhoto
(
_
sender
:
Any
)
{
...
...
@@ -67,25 +48,7 @@ class PlumbersViewController: UIViewController,UITableViewDataSource, UITableVie
else
{
return
}
settingsLauncher
.
showSettings
(
navigVC
:
navVC
)
}
//The delegate UIImagePickerController
/* func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
guard let image = info[.editedImage] as? UIImage
else {
return }
images.append(image)
collectionView.reloadData()
dismiss(animated: true)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
self.dismiss(animated: true, completion: nil)
}
func getDocumentsDirectory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return paths[0]
}
*/
@IBAction
func
BOOK_NOW_Click
(
_
sender
:
Any
)
{
let
storyboard
=
UIStoryboard
(
name
:
"Main"
,
bundle
:
nil
)
let
vc
:
UIViewController
...
...
@@ -97,12 +60,10 @@ class PlumbersViewController: UIViewController,UITableViewDataSource, UITableVie
navigationController
?
.
pushViewController
(
vc
,
animated
:
true
)
}
// @IBAction func tapGesture(_ sender: Any) {view.endEditing(true) }
func
textFieldShouldReturn
(
_
textField
:
UITextField
)
->
Bool
{
descProblem
.
resignFirstResponder
()
func
textFieldShouldReturn
(
_
textField
:
UITextField
)
->
Bool
{
textViewDesc
.
resignFirstResponder
()
}
func
tableView
(
_
tableView
:
UITableView
,
numberOfRowsInSection
section
:
Int
)
->
Int
{
return
1
}
...
...
@@ -195,86 +156,75 @@ extension PlumbersViewController:SettingsLauncherDelegate {
}
}
extension
PlumbersViewController
:
UICollectionViewDelegate
,
UICollectionViewDataSource
{
// MARK: - Setup
extension
PlumbersViewController
{
func
setup
()
{
setupGlidingCollectionView
()
// loadImages()
}
private
func
setupGlidingCollectionView
()
{
glidingView
.
dataSource
=
self
let
nib
=
UINib
(
nibName
:
"CollectionCell"
,
bundle
:
nil
)
collectionView
=
glidingView
.
collectionView
collectionView
.
register
(
nib
,
forCellWithReuseIdentifier
:
"Cell"
)
collectionView
.
delegate
=
self
collectionView
.
dataSource
=
self
collectionView
.
backgroundColor
=
glidingView
.
backgroundColor
}
}
// MARK: - CollectionView 🎛
extension
PlumbersViewController
:
UICollectionViewDataSource
,
UICollectionViewDelegate
{
func
collectionView
(
_
collectionView
:
UICollectionView
,
numberOfItemsInSection
section
:
Int
)
->
Int
{
// let section = glidingView.expandedItemIndex
return
images
.
count
//return 4
}
func
collectionView
(
_
collectionView
:
UICollectionView
,
cellForItemAt
indexPath
:
IndexPath
)
->
UICollectionViewCell
{
let
cell
=
collectionView
.
dequeueReusableCell
(
withReuseIdentifier
:
"photoCell"
,
for
:
indexPath
)
as!
PhotoCellCollectionViewCell
guard
let
cell
=
collectionView
.
dequeueReusableCell
(
withReuseIdentifier
:
"Cell"
,
for
:
indexPath
)
as?
CollectionCell
else
{
return
UICollectionViewCell
()
}
////let section = glidingView.expandedItemIndex
if
images
.
count
>
0
{
let
image
=
images
[
indexPath
.
row
]
cell
.
configure
(
by
:
image
,
count
:
indexPath
.
row
+
1
)
// let image = images[0]
cell
.
imageView
.
image
=
image
}
cell
.
contentView
.
clipsToBounds
=
true
if
(
indexPath
.
row
==
0
&&
isfirstTimeTransform
)
{
// make a bool and set YES initially, this check will prevent fist load transform
isfirstTimeTransform
=
false
;
}
else
{
cell
.
transform
=
TRANSFORM_CELL_VALUE
;
// the new cell will always be transform and without animation
}
let
layer
=
cell
.
layer
let
config
=
GlidingConfig
.
shared
layer
.
shadowOffset
=
config
.
cardShadowOffset
layer
.
shadowColor
=
config
.
cardShadowColor
.
cgColor
layer
.
shadowOpacity
=
config
.
cardShadowOpacity
layer
.
shadowRadius
=
config
.
cardShadowRadius
layer
.
shouldRasterize
=
true
layer
.
rasterizationScale
=
UIScreen
.
main
.
scale
return
cell
}
func
scrollViewWillEndDragging
(
_
scrollView
:
UIScrollView
,
withVelocity
velocity
:
CGPoint
,
targetContentOffset
:
UnsafeMutablePointer
<
CGPoint
>
)
{
//minimumLineSpacing and insetForSection are two constants in my code
//this cell width is for my case, adapt to yours
let
cellItemWidth
=
view
.
frame
.
width
-
(
10
)
// let cellItemWidth = view.frame.width - (insetForSection.left + insetForSection.right)
let
pageWidth
=
Float
(
cellItemWidth
+
5
)
// let pageWidth = Float(cellItemWidth + minimumLineSpacing)
let
offsetXAfterDragging
=
Float
(
scrollView
.
contentOffset
.
x
)
let
targetOffsetX
=
Float
(
targetContentOffset
.
pointee
.
x
)
let
pagesCountForOffset
=
pagesCount
(
forOffset
:
offsetXAfterDragging
,
withTargetOffset
:
targetOffsetX
,
pageWidth
:
pageWidth
)
var
newTargetOffsetX
=
pagesCountForOffset
*
pageWidth
keepNewTargetInBounds
(
&
newTargetOffsetX
,
scrollView
)
//ignore target
targetContentOffset
.
pointee
.
x
=
CGFloat
(
offsetXAfterDragging
)
let
newTargetPoint
=
CGPoint
(
x
:
CGFloat
(
newTargetOffsetX
),
y
:
scrollView
.
contentOffset
.
y
)
scrollView
.
setContentOffset
(
newTargetPoint
,
animated
:
true
)
//if you're using pageControl
// pageControl.currentPage = Int(newTargetOffsetX / pageWidth)
}
fileprivate
func
pagesCount
(
forOffset
offset
:
Float
,
withTargetOffset
targetOffset
:
Float
,
pageWidth
:
Float
)
->
Float
{
let
isRightDirection
=
targetOffset
>
offset
let
roundFunction
=
isRightDirection
?
ceilf
:
floorf
let
pagesCountForOffset
=
roundFunction
(
offset
/
pageWidth
)
return
pagesCountForOffset
}
fileprivate
func
keepNewTargetInBounds
(
_
newTargetOffsetX
:
inout
Float
,
_
scrollView
:
UIScrollView
)
{
if
newTargetOffsetX
<
0
{
newTargetOffsetX
=
0
}
let
contentSizeWidth
=
Float
(
scrollView
.
contentSize
.
width
)
if
newTargetOffsetX
>
contentSizeWidth
{
newTargetOffsetX
=
contentSizeWidth
}
}
func
collectionView
(
_
collectionView
:
UICollectionView
,
didSelectItemAt
indexPath
:
IndexPath
)
{
let
section
=
glidingView
.
expandedItemIndex
let
item
=
indexPath
.
item
print
(
"Selected item #
\(
item
)
in section #
\(
section
)
"
)
}
}
extension
PlumbersViewController
:
UICollectionViewDelegateFlowLayout
{
/* func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width/3, height: view.frame.width/3)
// MARK: - Gliding Collection 🎢
extension
PlumbersViewController
:
GlidingCollectionDatasource
{
func
numberOfItems
(
in
collection
:
GlidingCollection
)
->
Int
{
// return items.count
return
0
}
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
func
glidingCollection
(
_
collection
:
GlidingCollection
,
itemAtIndex
index
:
Int
)
->
String
{
// return "– " + items[index]
return
"– "
}
*/
func
collectionView
(
_
collectionView
:
UICollectionView
,
layout
collectionViewLayout
:
UICollectionViewLayout
,
minimumInteritemSpacingForSectionAt
section
:
Int
)
->
CGFloat
{
return
2
}
}
Em-call/VC/StartNavigationVCViewController.swift
0 → 100644
View file @
27f01c03
//
// StartNavigationVCViewController.swift
// Em-call
//
// Created by Alex Sh on 10.03.2022.
//
import
UIKit
class
StartNavigationVCViewController
:
UINavigationController
{
override
func
viewDidLoad
()
{
super
.
viewDidLoad
()
// Do any additional setup after loading the view.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
Em-call/VC/StartViewController.swift
View file @
27f01c03
...
...
@@ -29,12 +29,17 @@ class StartViewController: UIViewController {
self
.
present
(
alert
,
animated
:
true
)
}
return
}
}
else
{
//debug
let
storyboard
=
UIStoryboard
(
name
:
"Main"
,
bundle
:
nil
)
var
vc
:
UIViewController
vc
=
storyboard
.
instantiateViewController
(
withIdentifier
:
"TabBar"
)
navigationController
?
.
pushViewController
(
vc
,
animated
:
true
)
var
vc
:
UINavigationController
// let tabBar = storyboard.instantiateViewController(withIdentifier: "TabBar")
vc
=
storyboard
.
instantiateViewController
(
withIdentifier
:
"StartNavigationVC"
)
as!
UINavigationController
// vc = UINavigationController.init(rootViewController: tabBar)
// vc.pushViewController(tabBar, animated: true)
self
.
present
(
vc
,
animated
:
true
)
// self.present(tabBar, animated: true)
}
/*
let status = net.reqPostEnter(phone: number,code: psw)
if (status > 299) //|| (status == 0)
...
...
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