├── .DS_Store
├── .gitignore
├── FunIOS.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
│ └── xcuserdata
│ │ └── redli.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
└── xcuserdata
│ └── redli.xcuserdatad
│ └── xcschemes
│ └── xcschememanagement.plist
├── FunIOS.xcworkspace
├── contents.xcworkspacedata
├── xcshareddata
│ └── IDEWorkspaceChecks.plist
└── xcuserdata
│ └── redli.xcuserdatad
│ ├── UserInterfaceState.xcuserstate
│ └── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
├── FunIOS
├── .DS_Store
├── AppDelegate.swift
├── Assets.xcassets
│ ├── .DS_Store
│ ├── AccentColor.colorset
│ │ └── Contents.json
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── ios-marketing-1024x1024.png
│ │ ├── iphone-20x20@2x.png
│ │ ├── iphone-20x20@3x.png
│ │ ├── iphone-29x29@2x.png
│ │ ├── iphone-29x29@3x.png
│ │ ├── iphone-40x40@2x.png
│ │ ├── iphone-40x40@3x.png
│ │ ├── iphone-60x60@2x.png
│ │ └── iphone-60x60@3x.png
│ ├── Common
│ │ ├── .DS_Store
│ │ ├── Contents.json
│ │ ├── ic_collect.imageset
│ │ │ ├── Contents.json
│ │ │ ├── ic_collect@2x.png
│ │ │ └── ic_collect@3x.png
│ │ ├── ic_top.imageset
│ │ │ ├── Contents.json
│ │ │ ├── ic_top-1.png
│ │ │ └── ic_top.png
│ │ ├── ic_uncollect.imageset
│ │ │ ├── Contents.json
│ │ │ ├── ic_uncollect@2x.png
│ │ │ └── ic_uncollect@3x.png
│ │ ├── normal_placeholder_h.imageset
│ │ │ ├── Contents.json
│ │ │ └── normal_placeholder_h@2x.png
│ │ └── normal_placeholder_v.imageset
│ │ │ ├── Contents.json
│ │ │ └── normal_placeholder_v@2x.png
│ ├── Contents.json
│ ├── dropdown
│ │ ├── Contents.json
│ │ ├── dropdown_loading_00.imageset
│ │ │ ├── Contents.json
│ │ │ └── dropdown_loading_00@2x.png
│ │ ├── dropdown_loading_01.imageset
│ │ │ ├── Contents.json
│ │ │ └── dropdown_loading_01@2x.png
│ │ ├── dropdown_loading_010.imageset
│ │ │ ├── Contents.json
│ │ │ └── dropdown_loading_10@2x.png
│ │ ├── dropdown_loading_011.imageset
│ │ │ ├── Contents.json
│ │ │ └── dropdown_loading_11@2x.png
│ │ ├── dropdown_loading_012.imageset
│ │ │ ├── Contents.json
│ │ │ └── dropdown_loading_12@2x.png
│ │ ├── dropdown_loading_013.imageset
│ │ │ ├── Contents.json
│ │ │ └── dropdown_loading_13@2x.png
│ │ ├── dropdown_loading_014.imageset
│ │ │ ├── Contents.json
│ │ │ └── dropdown_loading_14@2x.png
│ │ ├── dropdown_loading_015.imageset
│ │ │ ├── Contents.json
│ │ │ └── dropdown_loading_15@2x.png
│ │ ├── dropdown_loading_02.imageset
│ │ │ ├── Contents.json
│ │ │ └── dropdown_loading_02@2x.png
│ │ ├── dropdown_loading_03.imageset
│ │ │ ├── Contents.json
│ │ │ └── dropdown_loading_03@2x.png
│ │ ├── dropdown_loading_04.imageset
│ │ │ ├── Contents.json
│ │ │ └── dropdown_loading_04@2x.png
│ │ ├── dropdown_loading_05.imageset
│ │ │ ├── Contents.json
│ │ │ └── dropdown_loading_05@2x.png
│ │ ├── dropdown_loading_06.imageset
│ │ │ ├── Contents.json
│ │ │ └── dropdown_loading_06@2x.png
│ │ ├── dropdown_loading_07.imageset
│ │ │ ├── Contents.json
│ │ │ └── dropdown_loading_07@2x.png
│ │ ├── dropdown_loading_08.imageset
│ │ │ ├── Contents.json
│ │ │ └── dropdown_loading_08@2x.png
│ │ └── dropdown_loading_09.imageset
│ │ │ ├── Contents.json
│ │ │ └── dropdown_loading_09@2x.png
│ ├── loading
│ │ ├── Contents.json
│ │ ├── sendloading_18x18_0.imageset
│ │ │ ├── Contents.json
│ │ │ ├── sendloading_18x18_0@2x.png
│ │ │ └── sendloading_18x18_0@3x.png
│ │ ├── sendloading_18x18_1.imageset
│ │ │ ├── Contents.json
│ │ │ ├── sendloading_18x18_1@2x.png
│ │ │ └── sendloading_18x18_1@3x.png
│ │ ├── sendloading_18x18_2.imageset
│ │ │ ├── Contents.json
│ │ │ ├── sendloading_18x18_2@2x.png
│ │ │ └── sendloading_18x18_2@3x.png
│ │ ├── sendloading_18x18_3.imageset
│ │ │ ├── Contents.json
│ │ │ ├── sendloading_18x18_3@2x.png
│ │ │ └── sendloading_18x18_3@3x.png
│ │ ├── sendloading_18x18_4.imageset
│ │ │ ├── Contents.json
│ │ │ ├── sendloading_18x18_4@2x.png
│ │ │ └── sendloading_18x18_4@3x.png
│ │ ├── sendloading_18x18_5.imageset
│ │ │ ├── Contents.json
│ │ │ ├── sendloading_18x18_5@2x.png
│ │ │ └── sendloading_18x18_5@3x.png
│ │ ├── sendloading_18x18_6.imageset
│ │ │ ├── Contents.json
│ │ │ ├── sendloading_18x18_6@2x.png
│ │ │ └── sendloading_18x18_6@3x.png
│ │ └── sendloading_18x18_7.imageset
│ │ │ ├── Contents.json
│ │ │ ├── sendloading_18x18_7@2x.png
│ │ │ └── sendloading_18x18_7@3x.png
│ ├── login
│ │ ├── .DS_Store
│ │ ├── Contents.json
│ │ ├── ic_close.imageset
│ │ │ ├── Contents.json
│ │ │ ├── ic_close-1.png
│ │ │ └── ic_close.png
│ │ ├── ic_logout.imageset
│ │ │ ├── Contents.json
│ │ │ ├── ic_logout-1.png
│ │ │ └── ic_logout.png
│ │ ├── ic_password.imageset
│ │ │ ├── Contents.json
│ │ │ ├── ic_password-1.png
│ │ │ └── ic_password.png
│ │ └── ic_user.imageset
│ │ │ ├── Contents.json
│ │ │ ├── ic_user-1.png
│ │ │ └── ic_user.png
│ ├── mine
│ │ ├── Contents.json
│ │ ├── ic_browsing.imageset
│ │ │ ├── Contents.json
│ │ │ ├── ic_browsing-1.png
│ │ │ └── ic_browsing.png
│ │ ├── ic_calendar.imageset
│ │ │ ├── Contents.json
│ │ │ ├── ic_calendar-1.png
│ │ │ └── ic_calendar.png
│ │ ├── ic_collection.imageset
│ │ │ ├── Contents.json
│ │ │ ├── ic_collection-1.png
│ │ │ └── ic_collection.png
│ │ ├── ic_courier.imageset
│ │ │ ├── Contents.json
│ │ │ ├── ic_courier-1.png
│ │ │ └── ic_courier.png
│ │ ├── ic_google.imageset
│ │ │ ├── Contents.json
│ │ │ ├── ic_google-1.png
│ │ │ └── ic_google.png
│ │ ├── ic_integral.imageset
│ │ │ ├── Contents.json
│ │ │ ├── ic_integral-1.png
│ │ │ └── ic_integral.png
│ │ ├── ic_ranking.imageset
│ │ │ ├── Contents.json
│ │ │ ├── ic_ranking-1.png
│ │ │ └── ic_ranking.png
│ │ ├── ic_share.imageset
│ │ │ ├── Contents.json
│ │ │ ├── ic_share-1.png
│ │ │ └── ic_share.png
│ │ ├── ic_todo.imageset
│ │ │ ├── Contents.json
│ │ │ ├── ic_todo-1.png
│ │ │ └── ic_todo.png
│ │ └── ic_weather.imageset
│ │ │ ├── Contents.json
│ │ │ ├── ic_weather-1.png
│ │ │ └── ic_weather.png
│ └── tabbar
│ │ ├── .DS_Store
│ │ ├── Contents.json
│ │ ├── home_tabbar_night_32x32_.imageset
│ │ ├── Contents.json
│ │ ├── Icon-60@2x.png
│ │ └── Icon-60@3x.png
│ │ ├── home_tabbar_press_32x32_.imageset
│ │ ├── Contents.json
│ │ ├── Icon-60@3x.png
│ │ └── icon-60@2x.png
│ │ ├── mine_tabbar_night_32x32_.imageset
│ │ ├── Contents.json
│ │ ├── Icon-60@2x.png
│ │ └── Icon-60@3x.png
│ │ ├── mine_tabbar_press_32x32_.imageset
│ │ ├── Contents.json
│ │ ├── icon-60@2x.png
│ │ └── icon-60@3x.png
│ │ ├── project_tabbar_night_32x32_.imageset
│ │ ├── Contents.json
│ │ ├── Icon-60@2x.png
│ │ └── Icon-60@3x.png
│ │ ├── project_tabbar_press_32x32_.imageset
│ │ ├── Contents.json
│ │ ├── icon-60@2x.png
│ │ └── icon-60@3x.png
│ │ ├── structure_tabbar_night_32x32_.imageset
│ │ ├── Contents.json
│ │ ├── Icon-60@2x.png
│ │ └── Icon-60@3x.png
│ │ ├── structure_tabbar_press_32x32_.imageset
│ │ ├── .DS_Store
│ │ ├── Contents.json
│ │ └── icon-60@2x.png
│ │ ├── wechat_tabbar_night_32x32_.imageset
│ │ ├── Contents.json
│ │ ├── Icon-60@2x.png
│ │ └── Icon-60@3x.png
│ │ └── wechat_tabbar_press_32x32_.imageset
│ │ ├── Contents.json
│ │ └── icon-60@2x.png
├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
├── Base
│ ├── BaseResponse.swift
│ ├── BaseTableViewCell.swift
│ └── BaseVController.swift
├── Cell-列表item样式
│ ├── ArticleCell.swift
│ ├── CollectCell.swift
│ ├── MenuCell.swift
│ ├── ProjectCell.swift
│ ├── RankingCell.swift
│ ├── StructureCell.swift
│ ├── UserCell.swift
│ └── WechatCell.swift
├── Const.swift
├── Extension
│ ├── MBProgressHUD+Extension.swift
│ ├── UIColor+Extension.swift
│ ├── UIView+Extension.swift
│ └── UIViewController+Extension.swift
├── IndexVController.swift
├── Info.plist
├── Models
│ ├── ArticleModel.swift
│ ├── BannerModel.swift
│ ├── IntegralModel.swift
│ ├── NavigationModel.swift
│ ├── RankingModel.swift
│ ├── StructureModel.swift
│ ├── UserCoinLevelModel.swift
│ └── UserModel.swift
├── SceneDelegate.swift
├── Services
│ └── Api.swift
├── Tools
│ ├── HttpUtils.swift
│ └── LogUtils.swift
├── UI
│ ├── Home
│ │ └── HomeVController.swift
│ ├── Login
│ │ └── LoginVController.swift
│ ├── Project
│ │ ├── ProjectArticlesVController.swift
│ │ └── ProjectVController.swift
│ ├── Structure
│ │ ├── StructureListVController.swift
│ │ └── StructureVController.swift
│ ├── StructureDetail
│ │ └── StructureDetailVController.swift
│ ├── User
│ │ ├── Collect
│ │ │ └── CollectVController.swift
│ │ ├── Integral
│ │ │ └── IntegralVController.swift
│ │ ├── Ranking
│ │ │ └── RankingVController.swift
│ │ └── UserVController.swift
│ ├── Web
│ │ └── WebVController.swift
│ └── Wechat
│ │ ├── WechatArticlesVController.swift
│ │ └── WechatVController.swift
├── View
│ ├── FloatButtonTableView.swift
│ └── RefreshView.swift
└── icon-60@3x.png
├── Podfile
└── README.md
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/.DS_Store
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## User settings
6 | xcuserdata/
7 |
8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
9 | *.xcscmblueprint
10 | *.xccheckout
11 |
12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
13 | Pods/
14 | build/
15 | DerivedData/
16 | Podfile.lock
17 | *.moved-aside
18 | *.pbxuser
19 | !default.pbxuser
20 | *.mode1v3
21 | !default.mode1v3
22 | *.mode2v3
23 | !default.mode2v3
24 | *.perspectivev3
25 | !default.perspectivev3
26 |
27 | ## Obj-C/Swift specific
28 | *.hmap
29 |
30 | ## App packaging
31 | *.ipa
32 | *.dSYM.zip
33 | *.dSYM
34 |
35 | ## Playgrounds
36 | timeline.xctimeline
37 | playground.xcworkspace
38 |
39 | # Swift Package Manager
40 | #
41 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
42 | # Packages/
43 | # Package.pins
44 | # Package.resolved
45 | # *.xcodeproj
46 | #
47 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
48 | # hence it is not needed unless you have added a package configuration file to your project
49 | # .swiftpm
50 |
51 | .build/
52 |
53 | # CocoaPods
54 | #
55 | # We recommend against adding the Pods directory to your .gitignore. However
56 | # you should judge for yourself, the pros and cons are mentioned at:
57 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
58 | #
59 | # Pods/
60 | #
61 | # Add this line if you want to avoid checking in source code from the Xcode workspace
62 | # *.xcworkspace
63 |
64 | # Carthage
65 | #
66 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
67 | # Carthage/Checkouts
68 |
69 | Carthage/Build/
70 |
71 | # Accio dependency management
72 | Dependencies/
73 | .accio/
74 |
75 | # fastlane
76 | #
77 | # It is recommended to not store the screenshots in the git repo.
78 | # Instead, use fastlane to re-generate the screenshots whenever they are needed.
79 | # For more information about the recommended setup visit:
80 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
81 |
82 | fastlane/report.xml
83 | fastlane/Preview.html
84 | fastlane/screenshots/**/*.png
85 | fastlane/test_output
86 |
87 | # Code Injection
88 | #
89 | # After new code Injection tools there's a generated folder /iOSInjectionProject
90 | # https://github.com/johnno1962/injectionforxcode
91 |
92 | iOSInjectionProject/
93 |
--------------------------------------------------------------------------------
/FunIOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/FunIOS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/FunIOS.xcodeproj/project.xcworkspace/xcuserdata/redli.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS.xcodeproj/project.xcworkspace/xcuserdata/redli.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/FunIOS.xcodeproj/xcuserdata/redli.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | FunIOS.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 20
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/FunIOS.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/FunIOS.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/FunIOS.xcworkspace/xcuserdata/redli.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS.xcworkspace/xcuserdata/redli.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/FunIOS/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/.DS_Store
--------------------------------------------------------------------------------
/FunIOS/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/21.
6 | //
7 |
8 | import UIKit
9 |
10 | @main
11 | class AppDelegate: UIResponder, UIApplicationDelegate {
12 |
13 |
14 |
15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
16 | // Override point for customization after application launch.
17 | return true
18 | }
19 |
20 | // MARK: UISceneSession Lifecycle
21 |
22 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
23 | // Called when a new scene session is being created.
24 | // Use this method to select a configuration to create the new scene with.
25 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
26 | }
27 |
28 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
29 | // Called when the user discards a scene session.
30 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
31 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
32 | }
33 |
34 |
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/.DS_Store
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "iphone-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "iphone-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "iphone-29x29@2x.png",
19 | "scale" : "2x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "iphone-29x29@3x.png",
25 | "scale" : "3x"
26 | },
27 | {
28 | "size" : "40x40",
29 | "idiom" : "iphone",
30 | "filename" : "iphone-40x40@2x.png",
31 | "scale" : "2x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "iphone-40x40@3x.png",
37 | "scale" : "3x"
38 | },
39 | {
40 | "size" : "60x60",
41 | "idiom" : "iphone",
42 | "filename" : "iphone-60x60@2x.png",
43 | "scale" : "2x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "iphone-60x60@3x.png",
49 | "scale" : "3x"
50 | },
51 | {
52 | "size" : "1024x1024",
53 | "idiom" : "ios-marketing",
54 | "filename" : "ios-marketing-1024x1024.png",
55 | "scale" : "1x"
56 | }
57 | ],
58 | "info" : {
59 | "version" : 1,
60 | "author" : "xcode"
61 | }
62 | }
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/AppIcon.appiconset/ios-marketing-1024x1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/AppIcon.appiconset/ios-marketing-1024x1024.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/AppIcon.appiconset/iphone-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/AppIcon.appiconset/iphone-20x20@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/AppIcon.appiconset/iphone-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/AppIcon.appiconset/iphone-20x20@3x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/AppIcon.appiconset/iphone-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/AppIcon.appiconset/iphone-29x29@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/AppIcon.appiconset/iphone-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/AppIcon.appiconset/iphone-29x29@3x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/AppIcon.appiconset/iphone-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/AppIcon.appiconset/iphone-40x40@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/AppIcon.appiconset/iphone-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/AppIcon.appiconset/iphone-40x40@3x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/AppIcon.appiconset/iphone-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/AppIcon.appiconset/iphone-60x60@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/AppIcon.appiconset/iphone-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/AppIcon.appiconset/iphone-60x60@3x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/Common/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/Common/.DS_Store
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/Common/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/Common/ic_collect.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "ic_collect@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "ic_collect@3x.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/Common/ic_collect.imageset/ic_collect@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/Common/ic_collect.imageset/ic_collect@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/Common/ic_collect.imageset/ic_collect@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/Common/ic_collect.imageset/ic_collect@3x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/Common/ic_top.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "ic_top-1.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "ic_top.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/Common/ic_top.imageset/ic_top-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/Common/ic_top.imageset/ic_top-1.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/Common/ic_top.imageset/ic_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/Common/ic_top.imageset/ic_top.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/Common/ic_uncollect.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "ic_uncollect@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "ic_uncollect@3x.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/Common/ic_uncollect.imageset/ic_uncollect@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/Common/ic_uncollect.imageset/ic_uncollect@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/Common/ic_uncollect.imageset/ic_uncollect@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/Common/ic_uncollect.imageset/ic_uncollect@3x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/Common/normal_placeholder_h.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "normal_placeholder_h@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/Common/normal_placeholder_h.imageset/normal_placeholder_h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/Common/normal_placeholder_h.imageset/normal_placeholder_h@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/Common/normal_placeholder_v.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "normal_placeholder_v@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/Common/normal_placeholder_v.imageset/normal_placeholder_v@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/Common/normal_placeholder_v.imageset/normal_placeholder_v@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_00.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "dropdown_loading_00@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_00.imageset/dropdown_loading_00@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/dropdown/dropdown_loading_00.imageset/dropdown_loading_00@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_01.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "dropdown_loading_01@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_01.imageset/dropdown_loading_01@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/dropdown/dropdown_loading_01.imageset/dropdown_loading_01@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_010.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "dropdown_loading_10@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_010.imageset/dropdown_loading_10@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/dropdown/dropdown_loading_010.imageset/dropdown_loading_10@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_011.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "dropdown_loading_11@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_011.imageset/dropdown_loading_11@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/dropdown/dropdown_loading_011.imageset/dropdown_loading_11@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_012.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "dropdown_loading_12@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_012.imageset/dropdown_loading_12@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/dropdown/dropdown_loading_012.imageset/dropdown_loading_12@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_013.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "dropdown_loading_13@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_013.imageset/dropdown_loading_13@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/dropdown/dropdown_loading_013.imageset/dropdown_loading_13@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_014.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "dropdown_loading_14@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_014.imageset/dropdown_loading_14@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/dropdown/dropdown_loading_014.imageset/dropdown_loading_14@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_015.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "dropdown_loading_15@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_015.imageset/dropdown_loading_15@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/dropdown/dropdown_loading_015.imageset/dropdown_loading_15@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_02.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "dropdown_loading_02@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_02.imageset/dropdown_loading_02@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/dropdown/dropdown_loading_02.imageset/dropdown_loading_02@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_03.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "dropdown_loading_03@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_03.imageset/dropdown_loading_03@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/dropdown/dropdown_loading_03.imageset/dropdown_loading_03@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_04.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "dropdown_loading_04@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_04.imageset/dropdown_loading_04@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/dropdown/dropdown_loading_04.imageset/dropdown_loading_04@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_05.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "dropdown_loading_05@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_05.imageset/dropdown_loading_05@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/dropdown/dropdown_loading_05.imageset/dropdown_loading_05@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_06.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "dropdown_loading_06@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_06.imageset/dropdown_loading_06@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/dropdown/dropdown_loading_06.imageset/dropdown_loading_06@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_07.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "dropdown_loading_07@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_07.imageset/dropdown_loading_07@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/dropdown/dropdown_loading_07.imageset/dropdown_loading_07@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_08.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "dropdown_loading_08@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_08.imageset/dropdown_loading_08@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/dropdown/dropdown_loading_08.imageset/dropdown_loading_08@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_09.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "dropdown_loading_09@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/dropdown/dropdown_loading_09.imageset/dropdown_loading_09@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/dropdown/dropdown_loading_09.imageset/dropdown_loading_09@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/loading/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/loading/sendloading_18x18_0.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "sendloading_18x18_0@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "sendloading_18x18_0@3x.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/loading/sendloading_18x18_0.imageset/sendloading_18x18_0@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/loading/sendloading_18x18_0.imageset/sendloading_18x18_0@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/loading/sendloading_18x18_0.imageset/sendloading_18x18_0@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/loading/sendloading_18x18_0.imageset/sendloading_18x18_0@3x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/loading/sendloading_18x18_1.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "sendloading_18x18_1@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "sendloading_18x18_1@3x.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/loading/sendloading_18x18_1.imageset/sendloading_18x18_1@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/loading/sendloading_18x18_1.imageset/sendloading_18x18_1@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/loading/sendloading_18x18_1.imageset/sendloading_18x18_1@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/loading/sendloading_18x18_1.imageset/sendloading_18x18_1@3x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/loading/sendloading_18x18_2.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "sendloading_18x18_2@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "sendloading_18x18_2@3x.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/loading/sendloading_18x18_2.imageset/sendloading_18x18_2@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/loading/sendloading_18x18_2.imageset/sendloading_18x18_2@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/loading/sendloading_18x18_2.imageset/sendloading_18x18_2@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/loading/sendloading_18x18_2.imageset/sendloading_18x18_2@3x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/loading/sendloading_18x18_3.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "sendloading_18x18_3@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "sendloading_18x18_3@3x.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/loading/sendloading_18x18_3.imageset/sendloading_18x18_3@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/loading/sendloading_18x18_3.imageset/sendloading_18x18_3@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/loading/sendloading_18x18_3.imageset/sendloading_18x18_3@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/loading/sendloading_18x18_3.imageset/sendloading_18x18_3@3x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/loading/sendloading_18x18_4.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "sendloading_18x18_4@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "sendloading_18x18_4@3x.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/loading/sendloading_18x18_4.imageset/sendloading_18x18_4@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/loading/sendloading_18x18_4.imageset/sendloading_18x18_4@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/loading/sendloading_18x18_4.imageset/sendloading_18x18_4@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/loading/sendloading_18x18_4.imageset/sendloading_18x18_4@3x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/loading/sendloading_18x18_5.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "sendloading_18x18_5@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "sendloading_18x18_5@3x.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/loading/sendloading_18x18_5.imageset/sendloading_18x18_5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/loading/sendloading_18x18_5.imageset/sendloading_18x18_5@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/loading/sendloading_18x18_5.imageset/sendloading_18x18_5@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/loading/sendloading_18x18_5.imageset/sendloading_18x18_5@3x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/loading/sendloading_18x18_6.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "sendloading_18x18_6@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "sendloading_18x18_6@3x.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/loading/sendloading_18x18_6.imageset/sendloading_18x18_6@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/loading/sendloading_18x18_6.imageset/sendloading_18x18_6@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/loading/sendloading_18x18_6.imageset/sendloading_18x18_6@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/loading/sendloading_18x18_6.imageset/sendloading_18x18_6@3x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/loading/sendloading_18x18_7.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "sendloading_18x18_7@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "sendloading_18x18_7@3x.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/loading/sendloading_18x18_7.imageset/sendloading_18x18_7@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/loading/sendloading_18x18_7.imageset/sendloading_18x18_7@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/loading/sendloading_18x18_7.imageset/sendloading_18x18_7@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/loading/sendloading_18x18_7.imageset/sendloading_18x18_7@3x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/login/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/login/.DS_Store
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/login/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/login/ic_close.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "ic_close-1.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "ic_close.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/login/ic_close.imageset/ic_close-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/login/ic_close.imageset/ic_close-1.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/login/ic_close.imageset/ic_close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/login/ic_close.imageset/ic_close.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/login/ic_logout.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "ic_logout-1.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "ic_logout.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/login/ic_logout.imageset/ic_logout-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/login/ic_logout.imageset/ic_logout-1.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/login/ic_logout.imageset/ic_logout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/login/ic_logout.imageset/ic_logout.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/login/ic_password.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "ic_password-1.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "ic_password.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/login/ic_password.imageset/ic_password-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/login/ic_password.imageset/ic_password-1.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/login/ic_password.imageset/ic_password.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/login/ic_password.imageset/ic_password.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/login/ic_user.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "ic_user-1.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "ic_user.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/login/ic_user.imageset/ic_user-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/login/ic_user.imageset/ic_user-1.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/login/ic_user.imageset/ic_user.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/login/ic_user.imageset/ic_user.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_browsing.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "ic_browsing-1.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "ic_browsing.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_browsing.imageset/ic_browsing-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/mine/ic_browsing.imageset/ic_browsing-1.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_browsing.imageset/ic_browsing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/mine/ic_browsing.imageset/ic_browsing.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_calendar.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "ic_calendar-1.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "ic_calendar.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_calendar.imageset/ic_calendar-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/mine/ic_calendar.imageset/ic_calendar-1.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_calendar.imageset/ic_calendar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/mine/ic_calendar.imageset/ic_calendar.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_collection.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "ic_collection.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "ic_collection-1.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_collection.imageset/ic_collection-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/mine/ic_collection.imageset/ic_collection-1.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_collection.imageset/ic_collection.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/mine/ic_collection.imageset/ic_collection.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_courier.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "ic_courier-1.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "ic_courier.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_courier.imageset/ic_courier-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/mine/ic_courier.imageset/ic_courier-1.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_courier.imageset/ic_courier.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/mine/ic_courier.imageset/ic_courier.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_google.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "ic_google-1.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "ic_google.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_google.imageset/ic_google-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/mine/ic_google.imageset/ic_google-1.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_google.imageset/ic_google.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/mine/ic_google.imageset/ic_google.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_integral.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "ic_integral-1.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "ic_integral.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_integral.imageset/ic_integral-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/mine/ic_integral.imageset/ic_integral-1.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_integral.imageset/ic_integral.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/mine/ic_integral.imageset/ic_integral.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_ranking.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "ic_ranking-1.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "ic_ranking.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_ranking.imageset/ic_ranking-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/mine/ic_ranking.imageset/ic_ranking-1.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_ranking.imageset/ic_ranking.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/mine/ic_ranking.imageset/ic_ranking.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_share.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "ic_share-1.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "ic_share.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_share.imageset/ic_share-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/mine/ic_share.imageset/ic_share-1.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_share.imageset/ic_share.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/mine/ic_share.imageset/ic_share.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_todo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "ic_todo-1.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "ic_todo.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_todo.imageset/ic_todo-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/mine/ic_todo.imageset/ic_todo-1.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_todo.imageset/ic_todo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/mine/ic_todo.imageset/ic_todo.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_weather.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "ic_weather-1.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "ic_weather.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_weather.imageset/ic_weather-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/mine/ic_weather.imageset/ic_weather-1.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/mine/ic_weather.imageset/ic_weather.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/mine/ic_weather.imageset/ic_weather.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/tabbar/.DS_Store
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/home_tabbar_night_32x32_.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "Icon-60@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "Icon-60@3x.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | },
22 | "properties" : {
23 | "template-rendering-intent" : "original"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/home_tabbar_night_32x32_.imageset/Icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/tabbar/home_tabbar_night_32x32_.imageset/Icon-60@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/home_tabbar_night_32x32_.imageset/Icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/tabbar/home_tabbar_night_32x32_.imageset/Icon-60@3x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/home_tabbar_press_32x32_.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "icon-60@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "icon-60@3x.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | },
22 | "properties" : {
23 | "template-rendering-intent" : "original"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/home_tabbar_press_32x32_.imageset/Icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/tabbar/home_tabbar_press_32x32_.imageset/Icon-60@3x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/home_tabbar_press_32x32_.imageset/icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/tabbar/home_tabbar_press_32x32_.imageset/icon-60@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/mine_tabbar_night_32x32_.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "Icon-60@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "Icon-60@3x.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | },
22 | "properties" : {
23 | "template-rendering-intent" : "original"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/mine_tabbar_night_32x32_.imageset/Icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/tabbar/mine_tabbar_night_32x32_.imageset/Icon-60@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/mine_tabbar_night_32x32_.imageset/Icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/tabbar/mine_tabbar_night_32x32_.imageset/Icon-60@3x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/mine_tabbar_press_32x32_.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "icon-60@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "icon-60@3x.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | },
22 | "properties" : {
23 | "template-rendering-intent" : "original"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/mine_tabbar_press_32x32_.imageset/icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/tabbar/mine_tabbar_press_32x32_.imageset/icon-60@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/mine_tabbar_press_32x32_.imageset/icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/tabbar/mine_tabbar_press_32x32_.imageset/icon-60@3x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/project_tabbar_night_32x32_.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "Icon-60@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "Icon-60@3x.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | },
22 | "properties" : {
23 | "template-rendering-intent" : "original"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/project_tabbar_night_32x32_.imageset/Icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/tabbar/project_tabbar_night_32x32_.imageset/Icon-60@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/project_tabbar_night_32x32_.imageset/Icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/tabbar/project_tabbar_night_32x32_.imageset/Icon-60@3x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/project_tabbar_press_32x32_.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "icon-60@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "icon-60@3x.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | },
22 | "properties" : {
23 | "template-rendering-intent" : "original"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/project_tabbar_press_32x32_.imageset/icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/tabbar/project_tabbar_press_32x32_.imageset/icon-60@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/project_tabbar_press_32x32_.imageset/icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/tabbar/project_tabbar_press_32x32_.imageset/icon-60@3x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/structure_tabbar_night_32x32_.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "Icon-60@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "Icon-60@3x.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/structure_tabbar_night_32x32_.imageset/Icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/tabbar/structure_tabbar_night_32x32_.imageset/Icon-60@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/structure_tabbar_night_32x32_.imageset/Icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/tabbar/structure_tabbar_night_32x32_.imageset/Icon-60@3x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/structure_tabbar_press_32x32_.imageset/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/tabbar/structure_tabbar_press_32x32_.imageset/.DS_Store
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/structure_tabbar_press_32x32_.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "icon-60@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "icon-60@3x.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/structure_tabbar_press_32x32_.imageset/icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/tabbar/structure_tabbar_press_32x32_.imageset/icon-60@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/wechat_tabbar_night_32x32_.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "Icon-60@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "Icon-60@3x.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/wechat_tabbar_night_32x32_.imageset/Icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/tabbar/wechat_tabbar_night_32x32_.imageset/Icon-60@2x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/wechat_tabbar_night_32x32_.imageset/Icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/tabbar/wechat_tabbar_night_32x32_.imageset/Icon-60@3x.png
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/wechat_tabbar_press_32x32_.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "icon-60@2x.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "filename" : "icon-60@3x.png",
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Assets.xcassets/tabbar/wechat_tabbar_press_32x32_.imageset/icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/Assets.xcassets/tabbar/wechat_tabbar_press_32x32_.imageset/icon-60@2x.png
--------------------------------------------------------------------------------
/FunIOS/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/FunIOS/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/FunIOS/Base/BaseResponse.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BaseResponse.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/21.
6 | //
7 |
8 | import Foundation
9 | import HandyJSON
10 |
11 | class BaseResponse: HandyJSON {
12 |
13 | var errorCode : Int? //服务返回码
14 |
15 | var errorMsg : String?
16 |
17 | var data : T?
18 |
19 | required init() {}
20 | }
21 |
--------------------------------------------------------------------------------
/FunIOS/Base/BaseTableViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BaseTableViewCell.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/22.
6 | //
7 |
8 | import UIKit
9 | import Reusable
10 |
11 |
12 | // Reusable 是用回收的
13 |
14 | /**
15 | 收藏功能提到basecell 。这个项目每个列表都有收藏功能。可加可不加
16 | */
17 |
18 | class BaseTableViewCell: UITableViewCell, Reusable {
19 |
20 | weak open var collectDelegate: CollectDelegate?
21 |
22 | //是否收藏
23 | var isCollect = false
24 |
25 | lazy var imgCollect = UIButton().then({attr in
26 | attr.setImage(UIImage(named: "ic_uncollect"), for: .normal)
27 | })
28 |
29 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
30 | super.init(style: style, reuseIdentifier: reuseIdentifier)
31 | selectionStyle = .none
32 | configUI()
33 | }
34 |
35 | open func configUI() {
36 |
37 | }
38 |
39 | func refreshCollect(isCollect collect: Bool) {
40 | if collect {
41 | imgCollect.setImage(UIImage(named: "ic_collect"), for: .normal)
42 | } else {
43 | imgCollect.setImage(UIImage(named: "ic_uncollect"), for: .normal)
44 | }
45 | self.isCollect = collect
46 | }
47 |
48 | @objc func collect(btn: UIButton) {
49 | if self.isCollect {
50 | collectDelegate?.uncollectAirticle(cid: btn.tag, tabCell: self)
51 | } else {
52 | collectDelegate?.collectAirticle(cid: btn.tag, tabCell: self)
53 | }
54 | }
55 |
56 | required init?(coder: NSCoder) {
57 | fatalError("init(coder:) has not been implemented")
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/FunIOS/Base/BaseVController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BaseVController.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/9/6.
6 | //
7 |
8 | import Foundation
9 | import UIKit
10 | import LGButton
11 |
12 |
13 | class BaseCVontroller: UIViewController{
14 |
15 | var floatAnimal = false
16 |
17 | var floatButton = UIButton().then({attr in
18 | attr.setImage(UIImage(named: "ic_top"), for: .normal)
19 | attr.contentMode = .scaleToFill
20 | attr.isHidden = true
21 | })
22 |
23 | func error(error: String?) {
24 | // view.makeToast(error)
25 | showHUDWithError(error: error)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/FunIOS/Cell-列表item样式/ArticleCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ArticleCell.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/22.
6 | //
7 |
8 | import UIKit
9 | import SnapKitExtend
10 |
11 | public protocol CollectDelegate : NSObjectProtocol{
12 |
13 | //收藏 文章
14 | func collectAirticle(cid id: Int, tabCell tabviewCell: UITableViewCell) -> Void
15 |
16 | //取消收藏 文章
17 | func uncollectAirticle(cid id: Int, tabCell tabviewCell: UITableViewCell) -> Void
18 | }
19 |
20 |
21 | class ArticleCell: BaseTableViewCell {
22 |
23 | private lazy var labelAuthor = UILabel().then({ (attr) in
24 | attr.text = "author"
25 | attr.font = UIFont.systemFont(ofSize: 12)
26 | attr.numberOfLines = 0 //相当于不限制行数
27 | attr.lineBreakMode = .byWordWrapping
28 | attr.sizeToFit()
29 | attr.backgroundColor = UIColor.white
30 | })
31 |
32 | private lazy var labelTime = UILabel().then({ (attr) in
33 | attr.text = "Time"
34 | attr.textColor = .gray
35 | attr.font = UIFont.systemFont(ofSize: 12)
36 | attr.numberOfLines = 0 //相当于不限制行数
37 | attr.lineBreakMode = .byWordWrapping
38 | attr.sizeToFit()
39 | attr.backgroundColor = UIColor.white
40 | })
41 |
42 |
43 | private lazy var labelTitle: UILabel = UILabel().then {(attr) in
44 | attr.text = "Titile"
45 | attr.textColor = .black
46 | attr.font = UIFont.systemFont(ofSize: 14)
47 | attr.numberOfLines = 2 //相当于不限制行数
48 | attr.lineBreakMode = .byWordWrapping
49 | attr.sizeToFit()
50 | attr.backgroundColor = UIColor.white
51 | }
52 |
53 |
54 | private lazy var labelChapterName = UILabel().then({(attr) in
55 | attr.text = "ChapterName"
56 | attr.textColor = .gray
57 | attr.font = UIFont.systemFont(ofSize: 10)
58 | attr.numberOfLines = 0 //相当于不限制行数
59 | attr.lineBreakMode = .byWordWrapping
60 | attr.sizeToFit()
61 | attr.backgroundColor = UIColor.white
62 | })
63 |
64 | private lazy var labelSuperChapterName = UILabel().then({(attr) in
65 | attr.text = "SuperChapterName"
66 | attr.textColor = .gray
67 | attr.font = UIFont.systemFont(ofSize: 10)
68 | attr.numberOfLines = 0 //相当于不限制行数
69 | attr.lineBreakMode = .byWordWrapping
70 | attr.sizeToFit()
71 | attr.backgroundColor = UIColor.white
72 | })
73 |
74 | var model: ArticleItemModel?{
75 | didSet {
76 | guard model == nil else {
77 | labelAuthor.text = (model?.author.isEmpty)! ? model?.shareUser : model?.author
78 | labelTime.text = model?.niceShareDate
79 | labelTitle.text = model?.title
80 | labelSuperChapterName.text = model?.superChapterName
81 | labelChapterName.text = " · \(model?.chapterName ?? "")"
82 |
83 | isCollect = model?.collect ?? false
84 |
85 | refreshCollect(isCollect: isCollect)
86 |
87 | imgCollect.tag = model?.id ?? 0
88 | return
89 | }
90 | }
91 | }
92 |
93 | override func configUI() {
94 | contentView.addSubview(labelAuthor)
95 | labelAuthor.snp.makeConstraints {maker in
96 | maker.leading.equalToSuperview().offset(10)
97 | maker.top.equalToSuperview().offset(10)
98 | }
99 |
100 | contentView.addSubview(labelTime)
101 | labelTime.snp.makeConstraints({maker in
102 | maker.trailing.equalToSuperview().offset(-10)
103 | maker.top.equalToSuperview().offset(10)
104 | })
105 |
106 | contentView.addSubview(labelTitle)
107 | labelTitle.snp.makeConstraints({maker in
108 | maker.top.equalTo(labelAuthor.snp.bottom).offset(10)
109 | maker.leading.equalToSuperview().offset(10)
110 | maker.trailing.equalToSuperview().offset(-10)
111 |
112 | })
113 |
114 | contentView.addSubview(labelSuperChapterName)
115 | labelSuperChapterName.snp.makeConstraints {maker in
116 | maker.leading.equalToSuperview().offset(10)
117 | maker.top.equalTo(labelTitle.snp.bottom).offset(10)
118 | maker.bottom.equalToSuperview().offset(-10)
119 | }
120 |
121 | contentView.addSubview(labelChapterName)
122 | labelChapterName.snp.makeConstraints({maker in
123 | maker.leading.equalTo(labelSuperChapterName.snp.trailing)
124 | maker.top.equalTo(labelTitle.snp.bottom).offset(10)
125 | maker.bottom.equalToSuperview().offset(-10)
126 | })
127 |
128 | contentView.addSubview(imgCollect)
129 | imgCollect.snp.makeConstraints { maker in
130 | maker.height.equalTo(20)
131 | maker.width.equalTo(20)
132 | maker.trailing.equalToSuperview().offset(-10)
133 | maker.bottom.equalToSuperview().offset(-5)
134 | }
135 |
136 | imgCollect.addTarget(self, action: #selector(self.collect(btn:)), for: .touchUpInside)
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/FunIOS/Cell-列表item样式/CollectCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CollectCell.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/8/10.
6 | //
7 |
8 | import Foundation
9 | import UIKit
10 |
11 | class CollectCell: BaseTableViewCell {
12 | private lazy var labelAuthor = UILabel().then({ (attr) in
13 | attr.text = "author"
14 | attr.font = UIFont.systemFont(ofSize: 15)
15 | attr.numberOfLines = 0 //相当于不限制行数
16 | attr.lineBreakMode = .byWordWrapping
17 | attr.sizeToFit()
18 | attr.backgroundColor = UIColor.white
19 | })
20 |
21 | private lazy var labelTime = UILabel().then({ (attr) in
22 | attr.text = "Time"
23 | attr.textColor = .gray
24 | attr.font = UIFont.systemFont(ofSize: 14)
25 | attr.numberOfLines = 0 //相当于不限制行数
26 | attr.lineBreakMode = .byWordWrapping
27 | attr.sizeToFit()
28 | attr.backgroundColor = UIColor.white
29 | })
30 |
31 |
32 | private lazy var labelTitle: UILabel = UILabel().then {(attr) in
33 | attr.text = "Titile"
34 | attr.textColor = .black
35 | attr.font = UIFont.boldSystemFont(ofSize: 15)
36 | attr.numberOfLines = 2 //相当于不限制行数
37 | attr.lineBreakMode = .byWordWrapping
38 | attr.sizeToFit()
39 | attr.backgroundColor = UIColor.white
40 | }
41 |
42 | private lazy var labelDesc: UILabel = UILabel().then { (attr) in
43 | attr.text = "desc"
44 | attr.font = UIFont.systemFont(ofSize: 14)
45 | attr.numberOfLines = 2 //相当于不限制行数
46 | attr.lineBreakMode = .byTruncatingTail
47 | attr.sizeToFit()
48 | attr.isHidden = true
49 | attr.backgroundColor = UIColor.white
50 | }
51 |
52 |
53 | private lazy var labelChapterName = UILabel().then({(attr) in
54 | attr.text = "ChapterName"
55 | attr.textColor = .gray
56 | attr.font = UIFont.boldSystemFont(ofSize: 12)
57 | attr.numberOfLines = 0 //相当于不限制行数
58 | attr.lineBreakMode = .byWordWrapping
59 | attr.sizeToFit()
60 | attr.backgroundColor = UIColor.white
61 | })
62 |
63 | private lazy var labelSuperChapterName = UILabel().then({(attr) in
64 | attr.text = "SuperChapterName"
65 | attr.textColor = .gray
66 | attr.font = UIFont.boldSystemFont(ofSize: 12)
67 | attr.numberOfLines = 0 //相当于不限制行数
68 | attr.lineBreakMode = .byWordWrapping
69 | attr.sizeToFit()
70 | attr.backgroundColor = UIColor.white
71 | })
72 |
73 | private lazy var line = UIView().then({ (attr) in
74 | attr.backgroundColor = UIColor.lightGray.withAlphaComponent(0.2)
75 | })
76 |
77 | var model: ArticleItemModel?{
78 | didSet {
79 | guard model == nil else {
80 | labelAuthor.text = (model?.author.isEmpty)! ? model?.shareUser : model?.author
81 | labelTime.text = model?.niceDate
82 | labelTitle.text = model?.title
83 | labelDesc.text = model?.desc
84 | labelSuperChapterName.text = model?.superChapterName
85 | labelChapterName.text = " · \(model?.chapterName ?? "")"
86 | return
87 | }
88 | }
89 | }
90 |
91 |
92 | override func configUI() {
93 | contentView.addSubview(labelAuthor)
94 | labelAuthor.snp.makeConstraints {(maker) in
95 | maker.leading.equalToSuperview().offset(10)
96 | maker.top.equalToSuperview().offset(10)
97 |
98 | }
99 |
100 | contentView.addSubview(labelTime)
101 | labelTime.snp.makeConstraints({(maker) in
102 | maker.trailing.equalToSuperview().offset(-10)
103 | maker.top.equalToSuperview().offset(10)
104 | })
105 |
106 | contentView.addSubview(labelTitle)
107 | labelTitle.snp.makeConstraints({(maker) in
108 | maker.top.equalTo(labelAuthor.snp.bottom).offset(10)
109 | maker.top.equalTo(labelTime.snp.bottom).offset(10)
110 | maker.leading.equalToSuperview().offset(10)
111 | maker.trailing.equalToSuperview().offset(-10)
112 | })
113 |
114 | // contentView.addSubview(labelDesc)
115 | // labelDesc.snp.makeConstraints { (maker) in
116 | // maker.top.equalTo(labelTitle.snp.bottom).offset(10)
117 | // maker.leading.equalToSuperview().offset(10)
118 | // maker.trailing.equalToSuperview().offset(-10)
119 | // }
120 |
121 | contentView.addSubview(labelSuperChapterName)
122 | labelSuperChapterName.snp.makeConstraints {(maker) in
123 | maker.leading.equalToSuperview().offset(10)
124 | maker.top.equalTo(labelTitle.snp.bottom).offset(10)
125 | }
126 |
127 | contentView.addSubview(labelChapterName)
128 | labelChapterName.snp.makeConstraints({(maker) in
129 | maker.leading.equalTo(labelSuperChapterName.snp.trailing)
130 | maker.top.equalTo(labelTitle.snp.bottom).offset(10)
131 | })
132 |
133 | contentView.addSubview(line)
134 | line.snp.makeConstraints { (maker) in
135 | maker.top.equalTo(labelSuperChapterName.snp.bottom).offset(10)
136 | maker.top.equalTo(labelChapterName.snp.bottom).offset(10)
137 | maker.bottom.equalToSuperview()
138 | maker.leading.equalToSuperview().offset(10)
139 | maker.trailing.equalToSuperview().offset(-10)
140 | maker.height.equalTo(1)
141 | }
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/FunIOS/Cell-列表item样式/MenuCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MenuCell.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/29.
6 | //
7 |
8 | import UIKit
9 | import Reusable
10 |
11 | class MenuCell: UICollectionViewCell, Reusable {
12 |
13 | var labelTitle: UILabel!
14 | var imgIcon: UIImageView!
15 |
16 | override init(frame: CGRect) {
17 | super.init(frame: frame)
18 | self.labelTitle = UILabel().then({ (attr) in
19 | attr.textAlignment = .center
20 | attr.font = UIFont.systemFont(ofSize: 12)
21 | })
22 |
23 | self.imgIcon = UIImageView().then({ (attr) in
24 | attr.contentMode = .scaleAspectFit
25 | })
26 |
27 | contentView.addSubview(self.imgIcon)
28 | self.imgIcon.snp.makeConstraints { (maker) in
29 | maker.top.equalToSuperview().offset(7)
30 | // maker.leading.equalToSuperview()
31 | // maker.trailing.equalToSuperview()
32 | maker.centerX.equalToSuperview()
33 | }
34 |
35 | contentView.addSubview(self.labelTitle)
36 | self.labelTitle.snp.makeConstraints { (maker) in
37 | maker.top.equalTo(self.imgIcon.snp.bottom).offset(5)
38 | // maker.leading.equalToSuperview()
39 | // maker.trailing.equalToSuperview()
40 | maker.centerX.equalToSuperview()
41 | }
42 | }
43 |
44 |
45 | required init?(coder: NSCoder) {
46 | fatalError("init(coder:) has not been implemented")
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/FunIOS/Cell-列表item样式/ProjectCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ProjectCell.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/25.
6 | //
7 |
8 | import UIKit
9 | import Kingfisher
10 |
11 | class ProjectCell: BaseTableViewCell {
12 |
13 | private lazy var labelAuthor = UILabel().then({ (attr) in
14 | attr.text = "author"
15 | attr.font = UIFont.systemFont(ofSize: 12)
16 | attr.numberOfLines = 0 //相当于不限制行数
17 | attr.lineBreakMode = .byWordWrapping
18 | attr.sizeToFit()
19 | attr.backgroundColor = UIColor.white
20 | })
21 |
22 | private lazy var labelTime = UILabel().then({ (attr) in
23 | attr.text = "Time"
24 | attr.textColor = .gray
25 | attr.font = UIFont.systemFont(ofSize: 12)
26 | attr.numberOfLines = 0 //相当于不限制行数
27 | attr.lineBreakMode = .byWordWrapping
28 | attr.sizeToFit()
29 | attr.backgroundColor = UIColor.white
30 | })
31 |
32 |
33 | private lazy var labelTitle: UILabel = UILabel().then {(attr) in
34 | attr.text = "Titile"
35 | attr.textColor = .black
36 | attr.font = UIFont.systemFont(ofSize: 15)
37 | attr.numberOfLines = 2 //相当于不限制行数
38 | attr.lineBreakMode = .byWordWrapping
39 | attr.sizeToFit()
40 | attr.backgroundColor = UIColor.white
41 | }
42 |
43 | private lazy var labelDesc: UILabel = UILabel().then { (attr) in
44 | attr.text = "desc"
45 | attr.font = UIFont.systemFont(ofSize: 12)
46 | attr.numberOfLines = 2 //相当于不限制行数
47 | attr.lineBreakMode = .byTruncatingTail
48 | attr.sizeToFit()
49 | attr.backgroundColor = UIColor.white
50 | }
51 |
52 | private lazy var imageContainer = UIImageView().then { (attr) in
53 |
54 | }
55 |
56 | private lazy var labelChapterName = UILabel().then({(attr) in
57 | attr.text = "ChapterName"
58 | attr.textColor = .gray
59 | attr.font = UIFont.systemFont(ofSize: 10)
60 | attr.numberOfLines = 0 //相当于不限制行数
61 | attr.lineBreakMode = .byWordWrapping
62 | attr.sizeToFit()
63 | attr.backgroundColor = UIColor.white
64 | })
65 |
66 | private lazy var labelSuperChapterName = UILabel().then({(attr) in
67 | attr.text = "SuperChapterName"
68 | attr.textColor = .gray
69 | attr.font = UIFont.systemFont(ofSize: 10)
70 | attr.numberOfLines = 0 //相当于不限制行数
71 | attr.lineBreakMode = .byWordWrapping
72 | attr.sizeToFit()
73 | attr.backgroundColor = UIColor.white
74 | })
75 |
76 | var model: ArticleItemModel?{
77 | didSet {
78 | guard model == nil else {
79 | labelAuthor.text = (model?.author.isEmpty)! ? model?.shareUser : model?.author
80 | labelTime.text = model?.niceShareDate
81 | labelTitle.text = model?.title
82 | labelDesc.text = model?.desc
83 | imageContainer.kf.setImage(with: URL(string: model!.envelopePic), placeholder: UIImage(named: "normal_placeholder_h"))
84 | labelSuperChapterName.text = model?.superChapterName
85 | labelChapterName.text = " · \(model?.chapterName ?? "")"
86 |
87 | isCollect = model?.collect ?? false
88 |
89 | refreshCollect(isCollect: isCollect)
90 |
91 | imgCollect.tag = model?.id ?? 0
92 |
93 | return
94 | }
95 | }
96 | }
97 |
98 | override func configUI() {
99 | contentView.addSubview(labelAuthor)
100 | labelAuthor.snp.makeConstraints {(maker) in
101 | maker.leading.equalToSuperview().offset(10)
102 | maker.top.equalToSuperview().offset(10)
103 |
104 | }
105 |
106 | contentView.addSubview(labelTime)
107 | labelTime.snp.makeConstraints({(maker) in
108 | maker.trailing.equalToSuperview().offset(-10)
109 | maker.top.equalToSuperview().offset(10)
110 | })
111 |
112 | contentView.addSubview(labelTitle)
113 | labelTitle.snp.makeConstraints({(maker) in
114 | maker.top.equalTo(labelAuthor.snp.bottom).offset(10)
115 | maker.top.equalTo(labelTime.snp.bottom).offset(10)
116 | maker.leading.equalToSuperview().offset(10)
117 | // maker.trailing.equalToSuperview().offset(-10)
118 | })
119 |
120 | contentView.addSubview(labelDesc)
121 | labelDesc.snp.makeConstraints { (maker) in
122 | maker.top.equalTo(labelTitle.snp.bottom).offset(10)
123 | maker.leading.equalToSuperview().offset(10)
124 | // maker.trailing.equalToSuperview().offset(-10)
125 | }
126 |
127 | contentView.addSubview(imageContainer)
128 | imageContainer.snp.makeConstraints { (maker) in
129 | maker.top.equalTo(labelAuthor.snp.bottom).offset(10)
130 | maker.top.equalTo(labelTime.snp.bottom).offset(10)
131 | maker.trailing.equalToSuperview().offset(-10)
132 | maker.leading.equalTo(labelTitle.snp.trailing).offset(10)
133 | maker.leading.equalTo(labelDesc.snp.trailing).offset(10)
134 | maker.height.equalTo(60)
135 | maker.width.equalTo(60)
136 | }
137 |
138 | contentView.addSubview(labelSuperChapterName)
139 | labelSuperChapterName.snp.makeConstraints {(maker) in
140 | maker.leading.equalToSuperview().offset(10)
141 | maker.top.equalTo(labelDesc.snp.bottom).offset(10)
142 | maker.bottom.equalToSuperview().offset(-10)
143 | }
144 |
145 | contentView.addSubview(labelChapterName)
146 | labelChapterName.snp.makeConstraints({(maker) in
147 | maker.leading.equalTo(labelSuperChapterName.snp.trailing)
148 | maker.top.equalTo(labelDesc.snp.bottom).offset(10)
149 | maker.bottom.equalToSuperview().offset(-10)
150 | })
151 |
152 | contentView.addSubview(imgCollect)
153 | imgCollect.snp.makeConstraints { maker in
154 | maker.height.equalTo(20)
155 | maker.width.equalTo(20)
156 | maker.trailing.equalToSuperview().offset(-10)
157 | maker.bottom.equalToSuperview().offset(-5)
158 | }
159 |
160 | imgCollect.addTarget(self, action: #selector(self.collect(btn:)), for: .touchUpInside)
161 | }
162 | }
163 |
--------------------------------------------------------------------------------
/FunIOS/Cell-列表item样式/RankingCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RankingCell.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/8/10.
6 | //
7 |
8 | import Foundation
9 | import UIKit
10 |
11 | class RankingCell: BaseTableViewCell {
12 |
13 | private let labelLeading = UILabel().then { attr in
14 | attr.textColor = UIColor.white
15 | attr.layer.cornerRadius = 20
16 | attr.layer.masksToBounds = true
17 | attr.backgroundColor = UIColor.randomColor
18 | attr.font = .boldSystemFont(ofSize: 12)
19 | attr.textAlignment = .center
20 | }
21 |
22 | private let labelTitle = UILabel().then { attr in
23 | attr.font = .boldSystemFont(ofSize: 16)
24 | attr.textColor = UIColor.black
25 | }
26 |
27 | private let labelSubTitle = UILabel().then { attr in
28 | attr.font = .systemFont(ofSize: 14)
29 | }
30 |
31 | private let labelTrailing = UILabel().then { attr in
32 |
33 | }
34 |
35 | var model: UserCoinLevelModel? {
36 | didSet {
37 | guard model == nil else {
38 | labelTitle.text = model?.username
39 | labelSubTitle.text = "\(model?.level ?? 0)"
40 | labelTrailing.text = "\(model?.coinCount ?? 0)"
41 | return
42 | }
43 | }
44 | }
45 |
46 | var index: Int? {
47 | didSet {
48 | guard model == nil else {
49 | labelLeading.text = "\(index ?? 0)"
50 | return
51 | }
52 | }
53 | }
54 |
55 | override func configUI() {
56 | contentView.addSubview(labelLeading)
57 | labelLeading.snp.makeConstraints { maker in
58 | maker.leading.equalToSuperview().offset(20)
59 | maker.centerY.equalToSuperview()
60 | maker.height.equalTo(40)
61 | maker.width.equalTo(40)
62 | }
63 |
64 | contentView.addSubview(labelTitle)
65 | labelTitle.snp.makeConstraints { maker in
66 | maker.leading.equalTo(labelLeading.snp.trailing).offset(10)
67 | maker.top.equalToSuperview().offset(10)
68 | }
69 |
70 | contentView.addSubview(labelSubTitle)
71 | labelSubTitle.snp.makeConstraints { maker in
72 | maker.leading.equalTo(labelLeading.snp.trailing).offset(10)
73 | // maker.top.equalTo(labelTitle.snp.bottom).offset(5)
74 | maker.bottom.equalToSuperview().offset(-10)
75 | }
76 |
77 | contentView.addSubview(labelTrailing)
78 | labelTrailing.snp.makeConstraints { maker in
79 | maker.trailing.equalToSuperview().offset(-20)
80 | maker.centerY.equalToSuperview()
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/FunIOS/Cell-列表item样式/StructureCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // StructureCell.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/25.
6 | //
7 |
8 | import UIKit
9 | import SnapKitExtend
10 | import TagListView
11 |
12 | public protocol TagViewDelegate : NSObjectProtocol{
13 |
14 | //体系Tag点击事件
15 | func tagStructureClick(parentModel model: StructureModel, childClickIndex clickIndex: Int) -> Void
16 |
17 | //导航Tag点击事件
18 | func tagNavigationClick(parentModel model: NavigationModel, childClickIndex clickIndex: Int) -> Void
19 | }
20 |
21 |
22 | class StructureCell: BaseTableViewCell {
23 |
24 | weak open var tagDelegate: TagViewDelegate?
25 |
26 | private var tagListView: TagListView = TagListView().then { (attr) in
27 | attr.textFont = UIFont.systemFont(ofSize: 14)
28 | attr.textColor = UIColor.white
29 | attr.cornerRadius = 10
30 | attr.paddingX = 10
31 | attr.paddingY = 5
32 | attr.marginX = 10
33 | attr.marginY = 5
34 | }
35 |
36 |
37 | override func configUI() {
38 | contentView.addSubview(tagListView)
39 | tagListView.snp.makeConstraints { (make) in
40 | make.top.equalTo(contentView.snp.top).offset(15)
41 | make.bottom.equalTo(contentView.snp.bottom).offset(-15)
42 | make.leading.equalToSuperview().offset(15)
43 | make.trailing.equalToSuperview().offset(-15)
44 | }
45 | }
46 |
47 | func setModel(type: Int, model: Any) {
48 | tagListView.removeAllTags();
49 | if type == 1 {
50 | let structure = model as! StructureModel
51 | for (index, value) in structure.children.enumerated() {
52 | let tagView = self.tagListView.addTag(value.name)
53 | tagView.tagBackgroundColor = UIColor.randomColor
54 | tagView.onTap = { tagView in
55 | self.tagDelegate?.tagStructureClick(parentModel: structure, childClickIndex: index)
56 | }
57 | }
58 | } else {
59 | let navigation = model as! NavigationModel
60 | for (index, value) in navigation.articles.enumerated() {
61 | let tagView = self.tagListView.addTag(value.title)
62 | tagView.tagBackgroundColor = UIColor.randomColor
63 | tagView.onTap = { tagView in
64 | self.tagDelegate?.tagNavigationClick(parentModel: navigation, childClickIndex: index)
65 | }
66 | }
67 | }
68 | contentView.frame.size.height = self.tagListView.height
69 | contentView.layoutIfNeeded()
70 | contentView.setNeedsLayout()
71 | }
72 |
73 | var model: StructureModel? {
74 | didSet {
75 | guard model == nil else {
76 | return
77 | }
78 | }
79 | }
80 | }
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/FunIOS/Cell-列表item样式/UserCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UserCell.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/8/9.
6 | //
7 |
8 | import UIKit
9 |
10 | class UserCell: BaseTableViewCell {
11 |
12 | private let icon = UIImageView().then { attr in
13 | attr.contentMode = .scaleAspectFit
14 | }
15 |
16 | private let title = UILabel().then { attr in
17 |
18 | }
19 |
20 | private lazy var line = UIView().then({ attr in
21 | attr.backgroundColor = UIColor.lightGray.withAlphaComponent(0.2)
22 | })
23 |
24 | var model: MenuItem? {
25 | didSet {
26 | guard model == nil else {
27 | title.text = model?.title
28 | icon.image = UIImage(named: model?.icon ?? "")
29 | return
30 | }
31 | }
32 | }
33 |
34 | override func configUI() {
35 | contentView.addSubview(line)
36 | line.snp.makeConstraints { maker in
37 | maker.top.equalToSuperview()
38 | maker.leading.equalToSuperview().offset(10)
39 | maker.trailing.equalToSuperview().offset(-10)
40 | maker.height.equalTo(1)
41 | }
42 | contentView.addSubview(icon)
43 | icon.snp.makeConstraints { maker in
44 | maker.centerY.equalToSuperview()
45 | maker.leading.equalToSuperview().offset(20)
46 | }
47 |
48 | contentView.addSubview(title)
49 | title.snp.makeConstraints { maker in
50 | maker.centerY.equalToSuperview()
51 | maker.leading.equalTo(icon.snp.trailing).offset(10)
52 | }
53 |
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/FunIOS/Cell-列表item样式/WechatCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WechatCell.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/25.
6 | //
7 |
8 | import UIKit
9 | import Kingfisher
10 |
11 | class WechatCell: BaseTableViewCell {
12 |
13 | private lazy var labelAuthor = UILabel().then({ (attr) in
14 | attr.text = "author"
15 | attr.font = UIFont.systemFont(ofSize: 12)
16 | attr.numberOfLines = 0 //相当于不限制行数
17 | attr.lineBreakMode = .byWordWrapping
18 | attr.sizeToFit()
19 | attr.backgroundColor = UIColor.white
20 | })
21 |
22 | private lazy var labelTime = UILabel().then({ (attr) in
23 | attr.text = "Time"
24 | attr.textColor = .gray
25 | attr.font = UIFont.systemFont(ofSize: 12)
26 | attr.numberOfLines = 0 //相当于不限制行数
27 | attr.lineBreakMode = .byWordWrapping
28 | attr.sizeToFit()
29 | attr.backgroundColor = UIColor.white
30 | })
31 |
32 |
33 | private lazy var labelTitle: UILabel = UILabel().then {(attr) in
34 | attr.text = "Titile"
35 | attr.textColor = .black
36 | attr.font = UIFont.systemFont(ofSize: 15)
37 | attr.numberOfLines = 2 //相当于不限制行数
38 | attr.lineBreakMode = .byWordWrapping
39 | attr.sizeToFit()
40 | attr.backgroundColor = UIColor.white
41 | }
42 |
43 | private lazy var labelDesc: UILabel = UILabel().then { (attr) in
44 | attr.text = "desc"
45 | attr.font = UIFont.systemFont(ofSize: 12)
46 | attr.numberOfLines = 2 //相当于不限制行数
47 | attr.lineBreakMode = .byTruncatingTail
48 | attr.sizeToFit()
49 | attr.backgroundColor = UIColor.white
50 | }
51 |
52 |
53 | private lazy var labelChapterName = UILabel().then({(attr) in
54 | attr.text = "ChapterName"
55 | attr.textColor = .gray
56 | attr.font = UIFont.systemFont(ofSize: 10)
57 | attr.numberOfLines = 0 //相当于不限制行数
58 | attr.lineBreakMode = .byWordWrapping
59 | attr.sizeToFit()
60 | attr.backgroundColor = UIColor.white
61 | })
62 |
63 | private lazy var labelSuperChapterName = UILabel().then({(attr) in
64 | attr.text = "SuperChapterName"
65 | attr.textColor = .gray
66 | attr.font = UIFont.systemFont(ofSize: 10)
67 | attr.numberOfLines = 0 //相当于不限制行数
68 | attr.lineBreakMode = .byWordWrapping
69 | attr.sizeToFit()
70 | attr.backgroundColor = UIColor.white
71 | })
72 |
73 | private lazy var line = UIView().then({ (attr) in
74 | attr.backgroundColor = UIColor.lightGray.withAlphaComponent(0.2)
75 | })
76 |
77 | var model: ArticleItemModel?{
78 | didSet {
79 | guard model == nil else {
80 | labelAuthor.text = (model?.author.isEmpty)! ? model?.shareUser : model?.author
81 | labelTime.text = model?.niceShareDate
82 | labelTitle.text = model?.title
83 | labelDesc.text = model?.desc
84 | labelSuperChapterName.text = model?.superChapterName
85 | labelChapterName.text = " · \(model?.chapterName ?? "")"
86 |
87 | isCollect = model?.collect ?? false
88 |
89 | refreshCollect(isCollect: isCollect)
90 |
91 | imgCollect.tag = model?.id ?? 0
92 |
93 | return
94 | }
95 | }
96 | }
97 |
98 |
99 | override func configUI() {
100 | contentView.addSubview(labelAuthor)
101 | labelAuthor.snp.makeConstraints {(maker) in
102 | maker.leading.equalToSuperview().offset(10)
103 | maker.top.equalToSuperview().offset(10)
104 |
105 | }
106 |
107 | contentView.addSubview(labelTime)
108 | labelTime.snp.makeConstraints({(maker) in
109 | maker.trailing.equalToSuperview().offset(-10)
110 | maker.top.equalToSuperview().offset(10)
111 | })
112 |
113 | contentView.addSubview(labelTitle)
114 | labelTitle.snp.makeConstraints({(maker) in
115 | maker.top.equalTo(labelAuthor.snp.bottom).offset(10)
116 | maker.top.equalTo(labelTime.snp.bottom).offset(10)
117 | maker.leading.equalToSuperview().offset(10)
118 | maker.trailing.equalToSuperview().offset(-10)
119 | })
120 |
121 | contentView.addSubview(labelDesc)
122 | labelDesc.snp.makeConstraints { (maker) in
123 | maker.top.equalTo(labelTitle.snp.bottom).offset(10)
124 | maker.leading.equalToSuperview().offset(10)
125 | maker.trailing.equalToSuperview().offset(-10)
126 | }
127 |
128 | contentView.addSubview(labelSuperChapterName)
129 | labelSuperChapterName.snp.makeConstraints {(maker) in
130 | maker.leading.equalToSuperview().offset(10)
131 | maker.top.equalTo(labelDesc.snp.bottom).offset(10)
132 | }
133 |
134 | contentView.addSubview(labelChapterName)
135 | labelChapterName.snp.makeConstraints({(maker) in
136 | maker.leading.equalTo(labelSuperChapterName.snp.trailing)
137 | maker.top.equalTo(labelDesc.snp.bottom).offset(10)
138 | })
139 |
140 | contentView.addSubview(line)
141 | line.snp.makeConstraints { (maker) in
142 | maker.top.equalTo(labelSuperChapterName.snp.bottom).offset(10)
143 | maker.top.equalTo(labelChapterName.snp.bottom).offset(10)
144 | maker.bottom.equalToSuperview()
145 | maker.leading.equalToSuperview().offset(10)
146 | maker.trailing.equalToSuperview().offset(-10)
147 | maker.height.equalTo(1)
148 | }
149 |
150 | contentView.addSubview(imgCollect)
151 | imgCollect.snp.makeConstraints { maker in
152 | maker.height.equalTo(20)
153 | maker.width.equalTo(20)
154 | maker.trailing.equalToSuperview().offset(-10)
155 | maker.bottom.equalToSuperview().offset(-5)
156 | }
157 |
158 | imgCollect.addTarget(self, action: #selector(self.collect(btn:)), for: .touchUpInside)
159 | }
160 |
161 | }
162 |
--------------------------------------------------------------------------------
/FunIOS/Const.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Const.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/21.
6 | //
7 |
8 | import Foundation
9 | import UIKit
10 |
11 |
12 | let screenWidth = UIScreen.main.bounds.width
13 | let screenHeight = UIScreen.main.bounds.height
14 |
15 | let statusBarHeight = UIApplication.shared.statusBarFrame.height
16 |
17 | let baseUrl = "https://www.wanandroid.com/"
18 |
19 | let userKey = "user_key"
20 |
21 | let userEvent = "user_event"
22 |
--------------------------------------------------------------------------------
/FunIOS/Extension/MBProgressHUD+Extension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MBProgressHUD+Extension.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/8/4.
6 | //
7 |
8 | import UIKit
9 | import MBProgressHUD
10 | let HUD_Duration_Infinite = -1
11 | let HUD_Duration_Normal = 1.5
12 | let HUD_Duration_Short = 0.5
13 |
14 | extension MBProgressHUD {
15 | @discardableResult
16 | class func showAdded(view: UIView, duration showTime: Double, animated: Bool) -> (MBProgressHUD) {
17 | var animated = animated
18 | let existHUD:MBProgressHUD = MBProgressHUD(view: view)
19 | if existHUD != nil{
20 | // 如果有HUD先隐藏掉,保证始终只有一个HUD
21 | MBProgressHUD.hide(for: view, animated: false)
22 | // 如果有HUD,则不做animation
23 | animated = false
24 | }
25 |
26 | let showView = self.showAdded(to: view, animated: animated)
27 |
28 | if Int(showTime) != HUD_Duration_Infinite {
29 | DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(showTime * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: {
30 | MBProgressHUD.hide(for: view, animated: false)
31 | })
32 | }
33 | return showView
34 | }
35 |
36 | @discardableResult
37 | class func showAdded(view: UIView, duration showTime: TimeInterval, withText text: String?, animated: Bool) -> (MBProgressHUD) {
38 | let showView = self.showAdded(view: view, duration: showTime, animated: animated)
39 | MBProgressHUD(view: view).isUserInteractionEnabled = false
40 | MBProgressHUD(view: view).mode = .text
41 | MBProgressHUD(view: view).label.text = text
42 | return showView
43 | }
44 |
45 | @discardableResult
46 | class func showAdded(view: UIView, icon image: UIImage?, duration showTime: TimeInterval, withText text: String?, animated: Bool) -> (MBProgressHUD) {
47 | let showView = self.showAdded(view: view, duration: showTime, animated: animated)
48 | MBProgressHUD(view: view).isUserInteractionEnabled = false
49 | MBProgressHUD(view: view).mode = .customView
50 | return showView
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/FunIOS/Extension/UIColor+Extension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // File.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/28.
6 | //
7 |
8 | import Foundation
9 | import UIKit
10 |
11 | extension UIColor {
12 | //返回随机颜色
13 | class var randomColor: UIColor {
14 | get {
15 | let red = CGFloat (arc4random()%256)/255.0
16 | let green = CGFloat (arc4random()%256)/255.0
17 | let blue = CGFloat (arc4random()%256)/255.0
18 | return UIColor (red: red, green: green, blue: blue, alpha: 1.0)
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/FunIOS/Extension/UIView+Extension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+Extension.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/25.
6 | //
7 |
8 | import UIKit
9 |
10 | extension UIView {
11 | var x: CGFloat {
12 | get {
13 | return frame.origin.x
14 | }
15 | set(x) {
16 | var frame = self.frame
17 | frame.origin.x = x
18 | self.frame = frame
19 | }
20 | }
21 |
22 | var y: CGFloat {
23 | get {
24 | return frame.origin.y
25 | }
26 | set(y) {
27 | var frame = self.frame
28 | frame.origin.y = y
29 | self.frame = frame
30 | }
31 | }
32 |
33 | var centerX: CGFloat {
34 | get {
35 | return center.x
36 | }
37 | set(centerX) {
38 | var center = self.center
39 | center.x = centerX
40 | self.center = center
41 | }
42 | }
43 |
44 | var centerY: CGFloat {
45 | get {
46 | return center.y
47 | }
48 | set(centerY) {
49 | var center = self.center
50 | center.y = centerY
51 | self.center = center
52 | }
53 | }
54 |
55 | var width: CGFloat {
56 | get {
57 | return frame.size.width
58 | }
59 | set(width) {
60 | var frame = self.frame
61 | frame.size.width = width
62 | self.frame = frame
63 | }
64 | }
65 |
66 | var height: CGFloat {
67 | get {
68 | return frame.size.height
69 | }
70 | set(height) {
71 | var frame = self.frame
72 | frame.size.height = height
73 | self.frame = frame
74 | }
75 | }
76 |
77 | var size: CGSize {
78 | get {
79 | return frame.size
80 | }
81 | set(size) {
82 | var frame = self.frame
83 | frame.size = size
84 | self.frame = frame
85 | }
86 | }
87 |
88 | var origin: CGPoint {
89 | get {
90 | return frame.origin
91 | }
92 | set(origin) {
93 | var frame = self.frame
94 | frame.origin = origin
95 | self.frame = frame
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/FunIOS/Extension/UIViewController+Extension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIViewController+Extension.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/8/4.
6 | //
7 |
8 | import UIKit
9 | import Foundation
10 | import MBProgressHUD
11 |
12 | private let minHUDWidth: CGFloat = 0.0
13 |
14 | extension UIViewController {
15 | @discardableResult
16 | func showWaitHUD() -> MBProgressHUD {
17 | return showWaitHUD(title: "加载中…")
18 | }
19 |
20 | @discardableResult
21 | func showWaitHUD(title: String?) -> MBProgressHUD {
22 | let HUD = showHUD(title: title, duration: TimeInterval(HUD_Duration_Infinite))
23 | HUD.isUserInteractionEnabled = true
24 | return HUD
25 | }
26 |
27 | @discardableResult
28 | func showHUDWithError(error: String?) -> MBProgressHUD {
29 | return showHUD(title: error, duration: HUD_Duration_Normal)
30 | }
31 |
32 | @discardableResult
33 | func showHUD(title: String?) -> MBProgressHUD {
34 | return showHUD(title: title, duration: HUD_Duration_Normal)
35 | }
36 |
37 | @discardableResult
38 | func showHUD(title: String?, detail: String?) -> MBProgressHUD {
39 | return showHUD(title: title, detail: detail, duration: HUD_Duration_Normal)
40 | }
41 |
42 | @discardableResult
43 | func showHUD(title: String?, duration: TimeInterval) -> MBProgressHUD {
44 | return showHUD(title: "", detail: title, duration: duration)
45 | }
46 |
47 | @discardableResult
48 | func showHUD(title: String?, detail: String?, duration: TimeInterval) -> MBProgressHUD {
49 | var HUD:MBProgressHUD = MBProgressHUD()
50 | if hudContainerView() != nil {
51 | HUD = MBProgressHUD.showAdded(view: hudContainerView()!, duration: duration, withText: title, animated: true)
52 | HUD.detailsLabel.text = detail
53 | setHUDBelowNavigationBar()
54 | HUD.minSize = CGSize(width: minHUDWidth, height: 0.0)
55 |
56 | }
57 | return HUD
58 | }
59 |
60 | @discardableResult
61 | func showHUD(withTitle title: String?, detail: String?, topIcon iconImage: UIImage?, duration: TimeInterval) -> MBProgressHUD {
62 | let HUD = showHUD(title: title, detail: detail, duration: duration)
63 | HUD.mode = .customView
64 | HUD.customView = UIImageView(image: iconImage)
65 | return HUD
66 | }
67 |
68 | @discardableResult
69 | func showHUD(withTitle title: String?, error: Error?) -> MBProgressHUD {
70 |
71 | let errorDetail = error?.localizedDescription
72 | return showHUD(title: title, detail: errorDetail)
73 | }
74 |
75 |
76 | func hideHUD() {
77 | if hudContainerView() != nil {
78 | MBProgressHUD.hide(for: hudContainerView()!, animated: true)
79 | }
80 | }
81 |
82 | @discardableResult
83 | func hudContainerView() -> UIView? {
84 | if isViewLoaded {
85 | if parent != nil && parent != navigationController {
86 | return parent?.hudContainerView()
87 | } else if navigationController?.parent != nil && navigationController?.parent != tabBarController {
88 | return navigationController?.parent?.hudContainerView()
89 | } else {
90 | return view
91 | }
92 | } else {
93 | return nil
94 | }
95 | }
96 |
97 | func setHUDBelowNavigationBar() {
98 | if navigationController?.view == hudContainerView() {
99 | if let navigationBar = navigationController?.navigationBar {
100 | if let hud = MBProgressHUD.forView((navigationController?.view)!) {
101 | navigationController?.view.insertSubview(hud, belowSubview: navigationBar)
102 | }
103 |
104 | }
105 | }
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/FunIOS/IndexVController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/21.
6 | //
7 |
8 | import UIKit
9 |
10 | class IndexVController: UITabBarController {
11 |
12 | override func viewDidLoad() {
13 | super.viewDidLoad()
14 | initTab()
15 | UITabBar.appearance().tintColor = UIColor.red.withAlphaComponent(0.5)
16 | }
17 |
18 | private func initTab() {
19 | let home = HomeVController()
20 | let project = ProjectVController()
21 | let wechat = WechatVController()
22 | let structure = StructrureVController()
23 | let user = UserVController()
24 |
25 | home.tabBarItem = UITabBarItem(title: "主页", image: UIImage(named: "home_tabbar_night_32x32_"), selectedImage: UIImage(named: "home_tabbar_press_32x32_"))
26 |
27 | project.tabBarItem = UITabBarItem(title: "项目", image: UIImage(named: "project_tabbar_night_32x32_"), selectedImage: UIImage(named: "project_tabbar_press_32x32_"))
28 |
29 | wechat.tabBarItem = UITabBarItem(title: "公众号", image: UIImage(named: "wechat_tabbar_night_32x32_"), selectedImage: UIImage(named: "wechat_tabbar_press_32x32_"))
30 |
31 | structure.tabBarItem = UITabBarItem(title: "体系", image: UIImage(named: "structure_tabbar_night_32x32_"), selectedImage: UIImage(named: "structure_tabbar_press_32x32_"))
32 |
33 | user.tabBarItem = UITabBarItem(title: "我的", image: UIImage(named: "mine_tabbar_night_32x32_"), selectedImage: UIImage(named: "mine_tabbar_press_32x32_"))
34 |
35 | self.viewControllers = [home, project, wechat, structure, user]
36 | }
37 |
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/FunIOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | $(MARKETING_VERSION)
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 |
37 |
38 |
39 |
40 | UIApplicationSupportsIndirectInputEvents
41 |
42 | UILaunchStoryboardName
43 | LaunchScreen
44 | UIMainStoryboardFile
45 | Main
46 | UIRequiredDeviceCapabilities
47 |
48 | armv7
49 |
50 | UISupportedInterfaceOrientations
51 |
52 | UIInterfaceOrientationPortrait
53 | UIInterfaceOrientationLandscapeLeft
54 | UIInterfaceOrientationLandscapeRight
55 |
56 | UISupportedInterfaceOrientations~ipad
57 |
58 | UIInterfaceOrientationPortrait
59 | UIInterfaceOrientationPortraitUpsideDown
60 | UIInterfaceOrientationLandscapeLeft
61 | UIInterfaceOrientationLandscapeRight
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/FunIOS/Models/ArticleModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AirticleModel.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/22.
6 | //
7 |
8 | import HandyJSON
9 |
10 |
11 | import HandyJSON
12 |
13 |
14 | class ArticleModel : HandyJSON {
15 |
16 | var curPage : Int = 0
17 | var datas : [ArticleItemModel] = []
18 | var offset : Int = 0
19 | var over : Bool = false
20 | var pageCount : Int = 0
21 | var size : Int = 0
22 | var total : Int = 0
23 |
24 |
25 | required init() {}
26 |
27 | }
28 |
29 | class ArticleItemModel : HandyJSON {
30 |
31 | var apkLink : String = ""
32 | var audit : Int = 0
33 | var author : String = ""
34 | var canEdit : Bool = false
35 | var chapterId : Int = 0
36 | var chapterName : String = ""
37 | var collect : Bool = false
38 | var courseId : Int = 0
39 | var desc : String = ""
40 | var descMd : String = ""
41 | var envelopePic : String = ""
42 | var fresh : Bool = false
43 | var host : String = ""
44 | var id : Int = 0
45 | var link : String = ""
46 | var niceDate : String = ""
47 | var niceShareDate : String = ""
48 | var origin : String = ""
49 | var prefix : String = ""
50 | var projectLink : String = ""
51 | var publishTime : Int = 0
52 | var realSuperChapterId : Int = 0
53 | var selfVisible : Int = 0
54 | var shareDate : Int = 0
55 | var shareUser : String = ""
56 | var superChapterId : Int = 0
57 | var superChapterName : String = ""
58 | var tags : [Tag] = []
59 | var title : String = ""
60 | var type : Int = 0
61 | var userId : Int = 0
62 | var visible : Int = 0
63 | var zan : Int = 0
64 |
65 |
66 | required init() {}
67 |
68 | }
69 |
70 | class Tag : HandyJSON {
71 |
72 | var name : String = ""
73 | var url : String = ""
74 |
75 |
76 | required init() {}
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/FunIOS/Models/BannerModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BannerModel.swift
3 | // Model file generated using JSONExport: https://github.com/Ahmed-Ali/JSONExport
4 |
5 | import HandyJSON
6 |
7 |
8 | class BannerModel : HandyJSON {
9 |
10 | var desc : String = ""
11 | var id : Int = 0
12 | var imagePath : String = ""
13 | var isVisible : Int = 0
14 | var order : Int = 0
15 | var title : String = ""
16 | var type : Int = 0
17 | var url : String = ""
18 |
19 |
20 | required init() {}
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/FunIOS/Models/IntegralModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CoinModel.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/8/9.
6 | //
7 |
8 | /**
9 | {"curPage":1,"datas":[{"coinCount":13,"date":1628475372000,"desc":"2021-08-09 10:16:12 签到 , 积分:13 + 0","id":478599,"reason":"签到","type":1,"userId":45070,"userName":"redli"}],"offset":0,"over":false,"pageCount":5,"size":20,"total":91}
10 | */
11 |
12 | import HandyJSON
13 |
14 | class IntegralModel : HandyJSON {
15 |
16 | var curPage : Int = 0
17 | var datas : [IntegralItemModel] = []
18 | var offset : Int = 0
19 | var over : Bool = false
20 | var pageCount : Int = 0
21 | var size : Int = 0
22 | var total : Int = 0
23 |
24 | required init() {}
25 |
26 | }
27 |
28 | class IntegralItemModel: HandyJSON {
29 | var coinCount : Int = 0
30 | var date : Int = 0
31 | var desc : String = ""
32 | var id : Int = 0
33 | var reason : String = ""
34 | var type : Int = 0
35 | var userId : Int = 0
36 | var userName : String = ""
37 |
38 |
39 | required init() {}
40 | }
41 |
--------------------------------------------------------------------------------
/FunIOS/Models/NavigationModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NavigationModel.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/27.
6 | //
7 |
8 | import HandyJSON
9 |
10 | open class NavigationModel: HandyJSON {
11 |
12 | var articles: [ArticleItemModel] = []
13 | var cid: Int = 0
14 | var name: String = ""
15 |
16 | required public init() {}
17 | }
18 |
--------------------------------------------------------------------------------
/FunIOS/Models/RankingModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RankingModel.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/8/10.
6 | //
7 | /**
8 | {"curPage":1,"datas":[{"coinCount":48606,"level":487,"nickname":"","rank":"1","userId":20382,"username":"g**eii"}],"offset":0,"over":false,"pageCount":2685,"size":30,"total":80540}
9 | */
10 |
11 |
12 | import Foundation
13 | import HandyJSON
14 |
15 | class RankingModel : HandyJSON {
16 |
17 | var curPage : Int = 0
18 | var datas : [UserCoinLevelModel] = []
19 | var offset : Int = 0
20 | var over : Bool = false
21 | var pageCount : Int = 0
22 | var size : Int = 0
23 | var total : Int = 0
24 |
25 |
26 | required init() {}
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/FunIOS/Models/StructureModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // StructureModel.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/25.
6 | //
7 |
8 | import HandyJSON
9 |
10 |
11 | open class StructureModel : HandyJSON {
12 |
13 | var children : [StructureModel] = []
14 | var courseId : Int = 0
15 | var id : Int = 0
16 | var name : String = ""
17 | var order : Int = 0
18 | var parentChapterId : Int = 0
19 | var userControlSetTop : Bool = false
20 | var visible : Int = 0
21 |
22 |
23 | required public init() {}
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/FunIOS/Models/UserCoinLevelModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CoinModel.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/8/9.
6 | //
7 |
8 | /**
9 | {"coinCount":2308,"level":24,"nickname":"","rank":"782","userId":45070,"username":"r**li"}
10 | */
11 |
12 | import HandyJSON
13 |
14 | class UserCoinLevelModel : HandyJSON {
15 |
16 | var coinCount : Int = 0
17 | var level : Int = 0
18 | var nickname : String = ""
19 | var rank : String = ""
20 | var userId : Int = 0
21 | var username : String = ""
22 |
23 |
24 | required init() {}
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/FunIOS/Models/UserModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UserModel.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/8/4.
6 | //
7 |
8 | import HandyJSON
9 |
10 | class UserModel : HandyJSON {
11 |
12 | var admin : Bool = false
13 | var chapterTops : [AnyObject] = []
14 | var coinCount : Int = 0
15 | var collectIds : [Int] = []
16 | var email : String = ""
17 | var icon : String = ""
18 | var id : Int = 0
19 | var nickname : String = ""
20 | var password : String = ""
21 | var publicName : String = ""
22 | var token : String = ""
23 | var type : Int = 0
24 | var username : String = ""
25 |
26 |
27 | required init() {}
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/FunIOS/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/21.
6 | //
7 |
8 | import UIKit
9 |
10 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
11 |
12 | var window: UIWindow?
13 |
14 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
15 | guard let windowScene = (scene as? UIWindowScene) else { return }
16 | let contentView = IndexVController()
17 | self.window = UIWindow(windowScene: windowScene)
18 | self.window?.backgroundColor = UIColor.white
19 | self.window?.rootViewController = UINavigationController.init(rootViewController: contentView)
20 | self.window?.makeKeyAndVisible()
21 | }
22 |
23 | func sceneDidDisconnect(_ scene: UIScene) {
24 | // Called as the scene is being released by the system.
25 | // This occurs shortly after the scene enters the background, or when its session is discarded.
26 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
27 | // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
28 | }
29 |
30 | func sceneDidBecomeActive(_ scene: UIScene) {
31 | // Called when the scene has moved from an inactive state to an active state.
32 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
33 | }
34 |
35 | func sceneWillResignActive(_ scene: UIScene) {
36 | // Called when the scene will move from an active state to an inactive state.
37 | // This may occur due to temporary interruptions (ex. an incoming phone call).
38 | }
39 |
40 | func sceneWillEnterForeground(_ scene: UIScene) {
41 | // Called as the scene transitions from the background to the foreground.
42 | // Use this method to undo the changes made on entering the background.
43 | }
44 |
45 | func sceneDidEnterBackground(_ scene: UIScene) {
46 | // Called as the scene transitions from the foreground to the background.
47 | // Use this method to save data, release shared resources, and store enough scene-specific state information
48 | // to restore the scene back to its current state.
49 | }
50 |
51 |
52 | }
53 |
54 |
--------------------------------------------------------------------------------
/FunIOS/Services/Api.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Api.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/22.
6 | //
7 |
8 | import Foundation
9 | import HandyJSON
10 |
11 | class Api {
12 |
13 | //获取轮播图列表
14 | static func fetchBanners(success: @escaping(_ result: Array?) -> (), error: @escaping(_ error: String?) -> ()) {
15 | HttpUtils.request(url: "banner/json", success: success, error: error)
16 | }
17 |
18 | //获取置顶文章列表
19 | static func fetchTopArticles(success: @escaping(_ result: Array?) -> (), error: @escaping(_ error: String?) -> ()) {
20 | HttpUtils.request(url: "article/top/json", success: success, error: error)
21 | }
22 |
23 | //获取文章列表
24 | static func fetchArticles(page: Int, success: @escaping(_ result: ArticleModel?) -> (), error: @escaping(_ error: String?) -> ()) {
25 | HttpUtils.request(url: "article/list/\(page)/json", success: success, error: error)
26 | }
27 |
28 | //获取项目分类
29 | static func fetchProjectSegmented(success: @escaping(_ result: Array?) -> (), error: @escaping(_ error: String?) -> ()) {
30 | HttpUtils.request(url: "project/tree/json", success: success, error: error)
31 | }
32 |
33 | //获取项目文章列表
34 | static func fetchProjectArticles(page: Int, cid: Int, success: @escaping(_ result: ArticleModel?) -> (), error: @escaping(_ error: String?) -> ()) {
35 | HttpUtils.request(url: "article/list/\(page)/json?cid=\(cid)", success: success, error: error)
36 | }
37 |
38 | //获取公众号分类
39 | static func fetchWechatSegmented(success: @escaping(_ result: Array?) -> (), error: @escaping(_ error: String?) -> ()) {
40 | HttpUtils.request(url: "wxarticle/chapters/json", success: success, error: error)
41 | }
42 |
43 | //获取公众号文章列表
44 | static func fetchWechatArticles(page: Int, cid: Int, success: @escaping(_ result: ArticleModel?) -> (), error: @escaping(_ error: String?) -> ()) {
45 | HttpUtils.request(url: "wxarticle/list/\(cid)/\(page)/json", success: success, error: error)
46 | }
47 |
48 | //获取navigation item 体系中的体系列表
49 | static func fetchStructures(success: @escaping(_ result: Array?) -> (), error: @escaping(_ error: String?) -> ()) {
50 | HttpUtils.request(url: "tree/json", success: success, error: error)
51 | }
52 |
53 | //获取navigation item 体系中的导航列表
54 | static func fetchNavigations(success: @escaping(_ result: Array?) -> (), error: @escaping(_ error: String?) -> ()) {
55 | HttpUtils.request(url: "navi/json", success: success, error: error)
56 | }
57 |
58 | //登录
59 | static func login(username: String, password: String, success: @escaping(_ result: UserModel?) -> (), error: @escaping(_ error: String?) -> ()) {
60 | HttpUtils.request(url: "user/login", type: MethodType.post, params: ["username": username, "password" : password], success: success, error: error)
61 | }
62 |
63 | //获取用户等级和积分
64 | static func fetchUserCoinLevel(success: @escaping(_ result: UserCoinLevelModel?) -> (), error: @escaping(_ error: String?) -> ()) {
65 | HttpUtils.request(url: "lg/coin/userinfo/json", success: success, error: error)
66 | }
67 |
68 | //获取收藏文章列表
69 | static func fetchCollectArticles(page: Int, success: @escaping(_ result: ArticleModel?) -> (), error: @escaping(_ error: String?) -> ()) {
70 | HttpUtils.request(url: "/lg/collect/list/\(page)/json", success: success, error: error)
71 | }
72 |
73 | //获取个人积分
74 | static func fetchMyIntegral(page: Int, success: @escaping(_ result: IntegralModel?) -> (), error: @escaping(_ error: String?) -> ()) {
75 | HttpUtils.request(url: "lg/coin/list/\(page)/json", success: success, error: error)
76 | }
77 |
78 | //获取积分排行榜
79 | static func fetchRanking(page: Int, success: @escaping(_ result: RankingModel?) -> (), error: @escaping(_ error: String?) -> ()) {
80 | HttpUtils.request(url: "coin/rank/\(page)/json", success: success, error: error)
81 | }
82 |
83 | //收藏文章
84 | static func collect(cid: Int, success: @escaping(_ result: Any?) -> (), error: @escaping(_ error: String?) -> ()) {
85 | HttpUtils.request(url: "lg/collect/\(cid)/json", type: MethodType.post, success: success, error: error)
86 | }
87 |
88 | //收藏网址
89 | static func collectUrl(name: String, link: String, success: @escaping(_ result: Any?) -> (), error: @escaping(_ error: String?) -> ()) {
90 | HttpUtils.request(url: "lg/collect/addtool/json", params: ["name": name, "link": link], success: success, error: error)
91 | }
92 |
93 | //取消收藏文章
94 | static func uncollect(cid: Int, success: @escaping(_ result: Any?) -> (), error: @escaping(_ error: String?) -> ()) {
95 | HttpUtils.request(url: "lg/uncollect_originId/\(cid)/json", type: MethodType.post, success: success, error: error)
96 | }
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/FunIOS/Tools/HttpUtils.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HttpUtils.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/21.
6 | //
7 |
8 | import Foundation
9 | import HandyJSON
10 | import Alamofire
11 |
12 | enum MethodType {
13 | case get
14 | case post
15 | }
16 |
17 | class HttpUtils {
18 |
19 | // static 也可以用 class 替代 效果是一样的
20 | static func request(url: String, type: MethodType? = MethodType.get, params: [String: Any]? = nil, success: @escaping(_ result: T?) -> (), error: @escaping(_ error: String?) -> ()) {
21 |
22 | let method = type == .get ? HTTPMethod.get : HTTPMethod.post
23 | // let headers: HTTPHeaders = ["Cookie": ""]
24 |
25 | print("请求地址 ---> \(baseUrl + url)")
26 |
27 | AF.request(baseUrl + url, method: method, parameters: params).responseJSON { response in
28 |
29 | guard let data = response.value else {
30 | error(response.error?.errorDescription ?? "请求错误")
31 | log(log: "请求错误 ---> \(response.error?.errorDescription ?? "")")
32 | return
33 | }
34 |
35 | let result = JSONDeserializer>.deserializeFrom(dict: data as? [String: Any])
36 |
37 | if result?.errorCode == 0 {
38 | success(result?.data)
39 | print("请求成功 ---> \(baseUrl + url)")
40 | } else{
41 | error(result?.errorMsg)
42 | print("请求失败 ---> \(baseUrl + url)")
43 | }
44 | print(response.value ?? "")
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/FunIOS/Tools/LogUtils.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LogUtil.swift
3 | // WanAndroid_IOS
4 | //
5 | // Created by 雷富 on 2020/4/7.
6 | // Copyright © 2020 雷富. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | func log(log: T, fileName: String = #file, methodName: String = #function, lineNumber: Int = #line) {
12 | //print(#file) //获取当前print所在的文件路径
13 | //print(#function) //获取当前print所在的方法名称
14 | //print(#line) //获取当前print所在的行数
15 | //判断是否打印debug
16 | #if DEBUG
17 | print("\((fileName as NSString).pathComponents.last!)_\(methodName)[行: \(lineNumber)]: \(log)")
18 |
19 | #endif
20 | }
21 |
22 |
23 |
--------------------------------------------------------------------------------
/FunIOS/UI/Home/HomeVController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MainVController.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/21.
6 | //
7 |
8 | import UIKit
9 | import Then
10 | import LLCycleScrollView
11 | import SnapKit
12 | import SVProgressHUD
13 | import MBProgressHUD
14 | import HandyJSON
15 |
16 | class HomeVController: BaseCVontroller {
17 |
18 | var page = 0
19 |
20 | private var articleList = Array()
21 |
22 | private var bannerLists = Array()
23 |
24 | private lazy var dispatchGroup = { return DispatchGroup.init() }()
25 |
26 | private lazy var tableView: FloatButtonTableView = FloatButtonTableView(frame: .zero, style: .plain).then({ (attr) in
27 | attr.backgroundColor = UIColor.white
28 | attr.delegate = self
29 | attr.dataSource = self
30 | attr.floatButtonDelegate = self
31 | attr.alwaysBounceVertical = true
32 | // attr.separatorStyle = .none
33 | attr.register(ArticleCell.self, forCellReuseIdentifier: "ArticleCell")
34 | })
35 |
36 | private lazy var bannerView = LLCycleScrollView().then({ (attr) in
37 | attr.backgroundColor = UIColor.yellow
38 | attr.autoScrollTimeInterval = 5
39 | attr.placeHolderImage = UIImage(named: "normal_placeholder_h")
40 | attr.coverImage = UIImage(named: "normal_placeholder_h")
41 | attr.imageViewContentMode = .scaleToFill
42 | attr.pageControlPosition = .right
43 | attr.frame = CGRect(x: 0, y: 0, width: screenWidth, height: screenWidth / 2)
44 | attr.lldidSelectItemAtIndex = self.didSelectBanner(index:)
45 | })
46 |
47 | private func didSelectBanner(index: NSInteger) {
48 | let bannerModel = self.bannerLists[index]
49 | let webVController = WebVController(title: bannerModel.title, url: bannerModel.url)
50 | navigationController?.pushViewController(webVController, animated: true)
51 | }
52 |
53 | override func viewWillAppear(_ animated: Bool) {
54 | self.navigationController?.navigationBar.isHidden = true
55 | }
56 |
57 | override func viewDidDisappear(_ animated: Bool) {
58 | // self.navigationController?.navigationBar.isHidden = false
59 | }
60 |
61 | override func viewDidLoad() {
62 | self.view.addSubview(tableView)
63 | tableView.snp.makeConstraints { maker in
64 | maker.top.equalToSuperview().offset(statusBarHeight)
65 | maker.left.equalToSuperview()
66 | maker.right.equalToSuperview()
67 | maker.bottom.equalToSuperview().offset(-40)
68 | }
69 |
70 | tableView.tableHeaderView = bannerView
71 |
72 | self.view.addSubview(floatButton)
73 | floatButton.snp.makeConstraints { maker in
74 | maker.bottom.equalToSuperview().offset(-80)
75 | maker.right.equalToSuperview().offset(-30)
76 | }
77 |
78 | floatButton.addTarget(self, action: #selector(topOffset), for: .touchUpInside)
79 |
80 | if #available(iOS 11.0, *) {
81 | UIScrollView.appearance().contentInsetAdjustmentBehavior = .never
82 | } else {
83 | automaticallyAdjustsScrollViewInsets = false
84 | }
85 | setRefresh()
86 | }
87 |
88 | @objc func topOffset() {
89 | self.tableView.scrollToRow(at: IndexPath.init(row: 0, section: 0), at: .bottom, animated: floatAnimal)
90 | }
91 |
92 | private func setRefresh() {
93 |
94 | let refreshHeader = RefreshHeader{ [weak self] in
95 | self?.page = 0
96 | self?.getData(false)
97 | }
98 |
99 | refreshHeader.isAutomaticallyChangeAlpha = true
100 | refreshHeader.lastUpdatedTimeLabel?.isHidden = true
101 | tableView.mj_header = refreshHeader
102 | refreshHeader.beginRefreshing()
103 |
104 | tableView.mj_footer = RefreshFooter{ [weak self] in
105 | self?.getData(true)
106 | }
107 | tableView.mj_footer?.isAutomaticallyChangeAlpha = true
108 | }
109 |
110 |
111 | private func getData(_ loadMore: Bool = false) {
112 | if !loadMore {
113 | page = 0
114 | } else {
115 | page += 1
116 | }
117 |
118 | if !loadMore {
119 | Api.fetchBanners(success: {(value:Array?) in
120 | self.bannerLists = value ?? []
121 | self.bannerView.imagePaths = value?.map{$0.imagePath} ?? []
122 | self.bannerView.titles = value?.map{ $0.title} ?? []
123 | }, error: error(error:))
124 |
125 | self.dispatchGroup.enter()
126 | Api.fetchTopArticles(success: {(value: Array?) in
127 | self.articleList = value ?? []
128 | self.dispatchGroup.leave()
129 | }, error: error(error:))
130 | }
131 |
132 | self.dispatchGroup.enter()
133 | Api.fetchArticles(page: page, success: { (value: ArticleModel?) in
134 | //结束刷新
135 | if self.tableView.mj_header!.isRefreshing { self.tableView.mj_header?.endRefreshing()
136 | }
137 |
138 | if self.tableView.mj_footer!.isRefreshing { self.tableView.mj_footer?.endRefreshing()
139 | }
140 |
141 | //是否加载更多
142 | if loadMore {
143 | if value?.datas.count ?? 0 <= 0 {
144 | self.tableView.mj_footer?.endRefreshingWithNoMoreData() } else {
145 | self.articleList.append(contentsOf: value!.datas)
146 | }
147 | } else {
148 | if value?.datas.count ?? 0 < (loadMore ? 20 : 19) {
149 | self.tableView.mj_footer?.endRefreshingWithNoMoreData()
150 | }
151 | self.articleList.append(contentsOf: value!.datas)
152 | }
153 | self.dispatchGroup.leave()
154 | }, error: error(error:))
155 |
156 | self.dispatchGroup.notify(queue: DispatchQueue.main) {
157 | self.tableView.reloadData()
158 | }
159 | }
160 |
161 | }
162 |
163 | extension HomeVController: UITableViewDataSource, UITableViewDelegate, CollectDelegate , FloatButtonDelegate{
164 | //数据
165 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
166 | return articleList.count
167 | }
168 |
169 | //每行行高
170 | func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
171 | 100
172 | }
173 |
174 | //每行加载样式
175 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
176 | let tableViewCell = tableView.dequeueReusableCell(for: indexPath, cellType: ArticleCell.self)
177 | tableViewCell.collectDelegate = self
178 | tableViewCell.model = articleList[indexPath.row]
179 | return tableViewCell
180 | }
181 |
182 | //item点击事件
183 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
184 | let model = self.articleList[indexPath.row]
185 | let webVController = WebVController(title: model.title, url: model.link)
186 | navigationController?.pushViewController(webVController, animated: true)
187 | }
188 |
189 | //收藏文章
190 | func collectAirticle(cid id: Int, tabCell tabviewCell: UITableViewCell) {
191 | Api.collect(cid: id, success: { value in
192 | let cell = tabviewCell as! ArticleCell
193 | cell.refreshCollect(isCollect: true)
194 | self.view.makeToast("收藏成功")
195 | }, error: error(error:))
196 | }
197 |
198 | //取消收藏文章
199 | func uncollectAirticle(cid id: Int, tabCell tabviewCell: UITableViewCell) {
200 | Api.uncollect(cid: id, success: { value in
201 | let cell = tabviewCell as! ArticleCell
202 | cell.refreshCollect(isCollect: false)
203 | self.view.makeToast("取消收藏成功")
204 | }, error: error(error:))
205 | }
206 |
207 | func floatStatus(forHide hide: Bool, withAnimal animal: Bool) {
208 | floatButton.isHidden = hide
209 | floatAnimal = animal
210 | }
211 | }
212 |
--------------------------------------------------------------------------------
/FunIOS/UI/Login/LoginVController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LoginVController.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/30.
6 | //
7 |
8 | import UIKit
9 | import LGButton
10 | import Toast_Swift
11 | import MBProgressHUD
12 | import SwiftEventBus
13 |
14 | class LoginVController: BaseCVontroller {
15 |
16 | private let closeImage = UIImageView().then { (attr) in
17 | attr.image = UIImage(named: "ic_close")
18 | attr.isUserInteractionEnabled = true
19 | }
20 |
21 | private let labelTitle = UILabel().then { (attr) in
22 | attr.text = "Fun IOS"
23 | attr.font = UIFont.boldSystemFont(ofSize: 20)
24 | attr.textColor = UIColor.black
25 | }
26 |
27 | private let textFieldUser = UITextField().then { (attr) in
28 | attr.borderStyle = .roundedRect
29 | attr.placeholder = "请输入账户"
30 | attr.clearButtonMode = .always
31 | attr.leftViewMode = .always
32 | attr.leftView = UIImageView(image: UIImage(named: "ic_user"))
33 | }
34 |
35 | private let textFieldPwd = UITextField().then { (attr) in
36 | attr.borderStyle = .roundedRect
37 | attr.placeholder = "请输入密码"
38 | attr.isSecureTextEntry = true
39 | attr.clearButtonMode = .always
40 | attr.leftViewMode = .always
41 | attr.leftView = UIImageView(image: UIImage(named: "ic_password"))
42 | }
43 |
44 | private let btnLogin = LGButton().then { (attr) in
45 | attr.cornerRadius = 10
46 | attr.titleString = "登录"
47 | attr.titleFontSize = 16
48 | attr.titleColor = UIColor.white
49 | attr.bgColor = UIColor.red.withAlphaComponent(0.6)
50 | }
51 |
52 | override func viewDidAppear(_ animated: Bool) {
53 |
54 | }
55 |
56 | override func viewDidLoad() {
57 | view.backgroundColor = UIColor.white
58 |
59 | let barHight = navigationController?.navigationBar.frame.height
60 |
61 | view.addSubview(closeImage)
62 | closeImage.snp.makeConstraints { (maker) in
63 | maker.top.equalToSuperview().offset(statusBarHeight + barHight!)
64 | maker.leading.equalToSuperview().offset(30)
65 | maker.height.equalTo(20)
66 | maker.width.equalTo(20)
67 | }
68 | let closeTap = UITapGestureRecognizer.init(target: self, action: #selector(close))
69 | closeImage.addGestureRecognizer(closeTap)
70 |
71 | view.addSubview(labelTitle)
72 | labelTitle.snp.makeConstraints { (maker) in
73 | maker.top.equalToSuperview().offset(statusBarHeight + barHight! + screenWidth / 3)
74 | maker.centerX.equalToSuperview()
75 | }
76 |
77 | view.addSubview(textFieldUser)
78 | textFieldUser.snp.makeConstraints { (maker) in
79 | maker.top.equalTo(labelTitle.snp.bottom).offset(30)
80 | maker.leading.equalToSuperview().offset(20)
81 | maker.trailing.equalToSuperview().offset(-20)
82 | maker.height.equalTo(50)
83 | }
84 |
85 | view.addSubview(textFieldPwd)
86 | textFieldPwd.snp.makeConstraints { (maker) in
87 | maker.top.equalTo(textFieldUser.snp.bottom).offset(20)
88 | maker.leading.equalToSuperview().offset(20)
89 | maker.trailing.equalToSuperview().offset(-20)
90 | maker.height.equalTo(50)
91 | }
92 |
93 | view.addSubview(btnLogin)
94 | btnLogin.snp.makeConstraints { (maker) in
95 | maker.top.equalTo(textFieldPwd.snp.bottom).offset(20)
96 | maker.centerX.equalToSuperview()
97 | maker.width.equalTo(screenWidth / 3 * 2)
98 | maker.height.equalTo(50)
99 | }
100 | btnLogin.addTarget(self, action: #selector(login), for: .touchUpInside)
101 | }
102 |
103 | @objc func login() {
104 | let username = textFieldUser.text
105 | let password = textFieldPwd.text
106 |
107 | if ((username?.isEmpty) == nil) {
108 | view.makeToast("请输入用户名")
109 | return
110 | }
111 |
112 | if ((password?.isEmpty) == nil) {
113 | view.makeToast("请输入密码")
114 | return
115 | }
116 |
117 | self.showHUD(title: "登录中")
118 |
119 | Api.login(username: username!, password: password!, success: { (value: UserModel?) in
120 | UserDefaults.standard.setValue(value?.toJSONString(prettyPrint:true), forKey: userKey)
121 | self.hideHUD()
122 | self.close()
123 | SwiftEventBus.post(userEvent, sender: value)
124 | }, error: error(error:))
125 | }
126 |
127 | @objc func close() {
128 | navigationController?.popViewController(animated: true)
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/FunIOS/UI/Project/ProjectArticlesVController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ProjectArticlesVController.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/25.
6 | //
7 |
8 | import UIKit
9 | import JXSegmentedView
10 |
11 | class ProjectArticlesVController: BaseCVontroller {
12 |
13 |
14 | // 当前页面
15 | var page = 0
16 | //文章id
17 | var cid : Int = 0
18 | //实体类数组
19 | private var articleList = [ArticleItemModel]()
20 |
21 | private lazy var tableView: UITableView = UITableView(frame: .zero, style: .plain).then({ (attr) in
22 | attr.backgroundColor = UIColor.white
23 | attr.delegate = self
24 | attr.dataSource = self
25 | attr.alwaysBounceVertical = true
26 | // attr.separatorStyle = .none
27 | attr.register(cellType: ProjectCell.self)
28 | // attr.rowHeight = 150
29 | })
30 |
31 |
32 |
33 | convenience init(cid: Int) {
34 | self.init()
35 | self.cid = cid
36 | }
37 |
38 |
39 | override func viewDidLoad() {
40 | self.view.addSubview(tableView)
41 | tableView.snp.makeConstraints { (maker) in
42 | maker.edges.equalToSuperview()
43 | }
44 |
45 | tableView.register(ArticleCell.self, forCellReuseIdentifier: "ArticleCell")
46 |
47 |
48 | if #available(iOS 11.0, *) {
49 | UIScrollView.appearance().contentInsetAdjustmentBehavior = .never
50 | } else {
51 | automaticallyAdjustsScrollViewInsets = false
52 | }
53 |
54 | setRefresh()
55 | }
56 |
57 | private func setRefresh() {
58 |
59 | let refreshHeader = RefreshHeader{ [weak self] in
60 | self?.page = 0
61 | self?.getData(false)
62 | }
63 |
64 | refreshHeader.isAutomaticallyChangeAlpha = true
65 | refreshHeader.lastUpdatedTimeLabel?.isHidden = true
66 | tableView.mj_header = refreshHeader
67 | refreshHeader.beginRefreshing()
68 |
69 | tableView.mj_footer = RefreshFooter{ [weak self] in
70 | self?.getData(true)
71 | }
72 | tableView.mj_footer?.isAutomaticallyChangeAlpha = true
73 |
74 | }
75 |
76 |
77 | private func getData(_ loadMore: Bool = false) {
78 | if !loadMore {
79 | page = 0
80 | } else {
81 | page += 1
82 | }
83 |
84 | Api.fetchProjectArticles(page: page, cid: cid, success: { (value: ArticleModel?) in
85 | //结束刷新
86 | if self.tableView.mj_header!.isRefreshing { self.tableView.mj_header?.endRefreshing()
87 | }
88 |
89 | if self.tableView.mj_footer!.isRefreshing { self.tableView.mj_footer?.endRefreshing()
90 | }
91 |
92 | //是否加载更多
93 | if loadMore {
94 | if value?.datas.count ?? 0 <= 0 {
95 | self.tableView.mj_footer?.endRefreshingWithNoMoreData() } else {
96 | self.articleList.append(contentsOf: value!.datas)
97 | }
98 | } else {
99 | if value?.datas.count ?? 0 < 20 {
100 | self.tableView.mj_footer?.endRefreshingWithNoMoreData()
101 | }
102 | self.articleList = value?.datas ?? []
103 | }
104 |
105 | self.tableView.reloadData()
106 | }, error: error(error:))
107 | }
108 | }
109 |
110 | extension ProjectArticlesVController: JXSegmentedListContainerViewListDelegate, UITableViewDataSource, UITableViewDelegate, CollectDelegate {
111 | func listView() -> UIView {
112 | view
113 | }
114 |
115 | //数据
116 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
117 | return articleList.count
118 | }
119 |
120 | //每行加载样式
121 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
122 | let tableViewCell = tableView.dequeueReusableCell(for: indexPath, cellType: ProjectCell.self)
123 | tableViewCell.collectDelegate = self
124 | tableViewCell.model = articleList[indexPath.row]
125 | return tableViewCell
126 | }
127 |
128 | //item点击事件
129 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
130 | let model = self.articleList[indexPath.row]
131 | let webVController = WebVController(title: model.title, url: model.link)
132 | navigationController?.pushViewController(webVController, animated: true)
133 | }
134 |
135 | //收藏文章
136 | func collectAirticle(cid id: Int, tabCell tabviewCell: UITableViewCell) {
137 | Api.collect(cid: id, success: { value in
138 | let cell = tabviewCell as! ProjectCell
139 | cell.refreshCollect(isCollect: true)
140 | self.view.makeToast("收藏成功")
141 | }, error: error(error:))
142 | }
143 |
144 | //取消收藏文章
145 | func uncollectAirticle(cid id: Int, tabCell tabviewCell: UITableViewCell) {
146 | Api.uncollect(cid: id, success: { value in
147 | let cell = tabviewCell as! ProjectCell
148 | cell.refreshCollect(isCollect: false)
149 | self.view.makeToast("取消收藏成功")
150 | }, error: error(error:))
151 | }
152 | }
153 |
154 |
--------------------------------------------------------------------------------
/FunIOS/UI/Project/ProjectVController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ProjectVController.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/21.
6 | //
7 |
8 | import UIKit
9 | import SnapKitExtend
10 | import JXSegmentedView
11 |
12 | class ProjectVController: BaseCVontroller {
13 |
14 |
15 | private let segmentedView = JXSegmentedView()
16 |
17 | private let segmentedDataSource = JXSegmentedTitleDataSource()
18 |
19 | private lazy var divLine = UIView().then({ (attr) in
20 | attr.backgroundColor = UIColor.lightGray.withAlphaComponent(0.2)
21 | })
22 |
23 | //配置指示器
24 | private let indicator = JXSegmentedIndicatorLineView()
25 |
26 | private lazy var listContainerView:JXSegmentedListContainerView = {
27 | return JXSegmentedListContainerView(dataSource: self)
28 | }()
29 |
30 | //指示器内容
31 | private var tabTitles : [String] = []
32 |
33 | private var viewControllers: [ProjectArticlesVController] = []
34 |
35 | override func viewWillAppear(_ animated: Bool) {
36 | self.navigationController?.navigationBar.isHidden = true
37 | }
38 |
39 | override func viewDidLoad() {
40 | Api.fetchProjectSegmented(success: { (value:Array?) in
41 | value?.forEach({ (item: StructureModel) in
42 | self.tabTitles.append(item.name)
43 | self.viewControllers.append(ProjectArticlesVController(cid: item.id))
44 | })
45 | self.loadUI()
46 | }, error: error(error:))
47 | }
48 |
49 | private func loadUI() {
50 | self.segmentedDataSource.titles = self.tabTitles
51 | self.segmentedView.dataSource = self.segmentedDataSource
52 | self.view.addSubview(self.segmentedView)
53 | self.view.addSubview(self.divLine)
54 | self.indicator.indicatorWidth = 20
55 | self.segmentedView.indicators = [self.indicator]
56 | self.segmentedView.listContainer = self.listContainerView
57 | self.view.addSubview(self.listContainerView)
58 | }
59 |
60 | override func viewDidLayoutSubviews() {
61 | super.viewDidLayoutSubviews()
62 | segmentedView.frame = CGRect(x: 0, y: statusBarHeight, width: screenWidth, height: 50)
63 |
64 | divLine.frame = CGRect(x: 0, y: statusBarHeight + 50, width: screenWidth, height: 1)
65 |
66 | listContainerView.frame = CGRect(x: 0, y: statusBarHeight + 50 + 1, width: screenWidth, height: screenHeight - statusBarHeight - 50 - 1)
67 | }
68 | }
69 |
70 | extension ProjectVController: JXSegmentedListContainerViewDataSource {
71 | func numberOfLists(in listContainerView: JXSegmentedListContainerView) -> Int {
72 | return viewControllers.count
73 | }
74 |
75 | func listContainerView(_ listContainerView: JXSegmentedListContainerView, initListAt index: Int) -> JXSegmentedListContainerViewListDelegate {
76 | return viewControllers[index]
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/FunIOS/UI/Structure/StructureListVController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // StructureListVController.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/27.
6 | //
7 |
8 | import UIKit
9 | import JXSegmentedView
10 |
11 |
12 | class StructureListVController: BaseCVontroller {
13 |
14 | //type = 1 体系, type = 2 导航
15 | private var type = 1
16 |
17 | private var list = [Any]()
18 |
19 | private lazy var tableView: UITableView = UITableView(frame: .zero, style: .plain).then({ (attr) in
20 | attr.backgroundColor = UIColor.white
21 | attr.delegate = self
22 | attr.dataSource = self
23 | attr.alwaysBounceVertical = true
24 | attr.separatorStyle = .none
25 | })
26 |
27 | convenience init(type: Int) {
28 | self.init()
29 | self.type = type
30 |
31 | if type == 1 {
32 | self.list = [StructureModel]()
33 | } else {
34 | self.list = [NavigationModel]()
35 | }
36 | }
37 |
38 |
39 | override func viewDidLoad() {
40 | tableView.register(cellType: StructureCell.self)
41 | self.view.addSubview(tableView)
42 | tableView.snp.makeConstraints { (maker) in
43 | maker.edges.equalToSuperview()
44 | }
45 |
46 | setRefresh()
47 | }
48 |
49 | private func setRefresh() {
50 |
51 | let refreshHeader = RefreshHeader{ [weak self] in
52 | self?.getData()
53 | }
54 |
55 | refreshHeader.isAutomaticallyChangeAlpha = true
56 | refreshHeader.lastUpdatedTimeLabel?.isHidden = true
57 | tableView.mj_header = refreshHeader
58 | refreshHeader.beginRefreshing()
59 | }
60 |
61 |
62 | private func getData() {
63 | if type == 1 {
64 | Api.fetchStructures(success: { (value: Array?) in
65 | self.reloadTable(value: value)
66 | }, error: error(error:))
67 | } else {
68 | Api.fetchNavigations(success: { (value: Array?) in
69 | self.reloadTable(value: value)
70 | }, error: error(error:))
71 | }
72 | }
73 |
74 | private func reloadTable(value: Array?) {
75 | self.list.append(contentsOf: value ?? [])
76 | self.tableView.reloadData()
77 | //结束刷新
78 | if self.tableView.mj_header!.isRefreshing { self.tableView.mj_header?.endRefreshing()
79 | }
80 |
81 | //刷新一下tableview布局
82 | DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {[weak self] in
83 | self?.tableView.beginUpdates()
84 | self?.tableView.endUpdates()
85 | }
86 | }
87 | }
88 |
89 | extension StructureListVController: UITableViewDelegate, UITableViewDataSource, JXSegmentedListContainerViewListDelegate, TagViewDelegate {
90 |
91 | func tagStructureClick(parentModel model: StructureModel, childClickIndex clickIndex: Int) {
92 | let structureDetailVController = StructureDetailVController.init(parentModel: model, childClickIndex: clickIndex)
93 | navigationController?.pushViewController(structureDetailVController, animated: true)
94 | }
95 |
96 | func tagNavigationClick(parentModel model: NavigationModel, childClickIndex clickIndex: Int) {
97 | let item = model.articles[clickIndex]
98 | let webVController = WebVController(title: item.title, url: item.link)
99 | navigationController?.pushViewController(webVController, animated: true)
100 | }
101 |
102 | func listView() -> UIView {
103 | view
104 | }
105 |
106 | func numberOfSections(in tableView: UITableView) -> Int {
107 | return self.list.count
108 | }
109 |
110 | func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
111 | return 30
112 | }
113 |
114 | func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
115 | let view = UIView()
116 | view.backgroundColor = UIColor(red:0.94, green:0.94, blue:0.94, alpha:1.0)
117 | let viewLabel = UILabel(frame: CGRect(x: 10, y: 0, width: UIScreen.main.bounds.size.width, height: 30))
118 | if self.type == 1 {
119 | viewLabel.text = (self.list[section] as! StructureModel).name
120 | } else {
121 | viewLabel.text = (self.list[section] as! NavigationModel).name
122 | }
123 |
124 | viewLabel.textColor = UIColor(red:0.31, green:0.31, blue:0.31, alpha:1.0)
125 | view.addSubview(viewLabel)
126 | tableView.addSubview(view)
127 | return view
128 | }
129 |
130 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
131 | // if self.type == 1 {
132 | // return (self.list[section] as! StructureModel).children.count
133 | // } else {
134 | // return (self.list[section] as! NavigationModel).articles.count
135 | // }
136 | return 1
137 | }
138 |
139 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
140 | let tableViewCell = tableView.dequeueReusableCell(for: indexPath, cellType: StructureCell.self)
141 | tableViewCell.tagDelegate = self
142 | if self.type == 1 {
143 | // tableViewCell.setModel(type: 1, model: (self.list[indexPath.section] as! StructureModel).children[indexPath.row])
144 | tableViewCell.setModel(type: 1, model: (self.list[indexPath.section] as! StructureModel))
145 | } else {
146 | // tableViewCell.setModel(type: 2, model: (self.list[indexPath.section] as! NavigationModel).articles[indexPath.row])
147 | tableViewCell.setModel(type: 2, model: (self.list[indexPath.section] as! NavigationModel))
148 | }
149 | return tableViewCell
150 | }
151 |
152 | // func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
153 | // if type == 1 {
154 | // let model = (self.list[indexPath.section] as! StructureModel).children[indexPath.row]
155 | // } else {
156 | // let model = (self.list[indexPath.section] as! NavigationModel).articles[indexPath.row]
157 | // let webVController = WebVController(title: model.title, url: model.link)
158 | // navigationController?.pushViewController(webVController, animated: true)
159 | // }
160 | // }
161 | }
162 |
--------------------------------------------------------------------------------
/FunIOS/UI/Structure/StructureVController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // StructureVController.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/21.
6 | //
7 |
8 | import UIKit
9 | import JXSegmentedView
10 | import SnapKitExtend
11 |
12 | class StructrureVController: UIViewController {
13 |
14 | private let titles = ["体系", "导航"]
15 |
16 | private let segmentedView = JXSegmentedView()
17 |
18 | private let segmentedDataSource = JXSegmentedTitleDataSource()
19 |
20 | //配置指示器
21 | private let indicator = JXSegmentedIndicatorBackgroundView()
22 |
23 | private lazy var divLine = UIView().then({ (attr) in
24 | attr.backgroundColor = UIColor.lightGray.withAlphaComponent(0.2)
25 | })
26 |
27 | private lazy var listContainerView:JXSegmentedListContainerView = {
28 | return JXSegmentedListContainerView(dataSource: self)
29 | }()
30 |
31 | private var viewControllers: [StructureListVController] = []
32 |
33 | var totalItemWidth: CGFloat = 0
34 |
35 | override func viewWillAppear(_ animated: Bool) {
36 | self.navigationController?.navigationBar.isHidden = true
37 | }
38 |
39 | override func viewDidLoad() {
40 | totalItemWidth = UIScreen.main.bounds.size.width - 30 * 2
41 | segmentedDataSource.itemWidth = totalItemWidth / CGFloat(titles.count) / 2
42 | segmentedDataSource.titles = titles
43 | segmentedDataSource.isTitleMaskEnabled = true
44 | segmentedDataSource.titleNormalColor = UIColor.red
45 | segmentedDataSource.titleSelectedColor = UIColor.white
46 | segmentedDataSource.itemSpacing = 0
47 | segmentedView.dataSource = segmentedDataSource
48 | segmentedView.layer.masksToBounds = true
49 | segmentedView.layer.cornerRadius = 15
50 | segmentedView.layer.borderColor = UIColor.red.cgColor
51 | segmentedView.layer.borderWidth = 1 / UIScreen.main.scale
52 |
53 | indicator.indicatorHeight = 30
54 | indicator.indicatorWidthIncrement = 0
55 | indicator.indicatorColor = UIColor.red
56 |
57 | segmentedView.indicators = [indicator]
58 |
59 | titles.forEach { (title) in
60 | viewControllers.append(StructureListVController(type: title == self.titles[0] ? 1 : 2))
61 | }
62 |
63 | segmentedView.listContainer = listContainerView
64 |
65 | view.addSubview(segmentedView)
66 | view.addSubview(listContainerView)
67 | }
68 |
69 | override func viewDidLayoutSubviews() {
70 | super.viewDidLayoutSubviews()
71 |
72 | segmentedView.frame = CGRect(x:screenWidth / 2 - (totalItemWidth / 4), y: statusBarHeight, width: totalItemWidth / 2, height: 30)
73 |
74 | divLine.frame = CGRect(x: 0, y: statusBarHeight + 50, width: screenWidth, height: 1)
75 |
76 | listContainerView.frame = CGRect(x: 0, y: statusBarHeight + 30, width: screenWidth, height: screenHeight - statusBarHeight - 30)
77 | }
78 |
79 | }
80 |
81 | extension StructrureVController: JXSegmentedListContainerViewDataSource {
82 | func numberOfLists(in listContainerView: JXSegmentedListContainerView) -> Int {
83 | return viewControllers.count
84 | }
85 |
86 | func listContainerView(_ listContainerView: JXSegmentedListContainerView, initListAt index: Int) -> JXSegmentedListContainerViewListDelegate {
87 | return viewControllers[index]
88 | }
89 |
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/FunIOS/UI/StructureDetail/StructureDetailVController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // StructureDetailVController.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/28.
6 | //
7 |
8 | import UIKit
9 | import JXSegmentedView
10 |
11 | class StructureDetailVController: UIViewController {
12 |
13 | private var model: StructureModel?
14 |
15 | private var clickIndex: Int?
16 |
17 | private let segmentedView = JXSegmentedView()
18 |
19 | private let segmentedDataSource = JXSegmentedTitleDataSource()
20 |
21 | private lazy var divLine = UIView().then({ (attr) in
22 | attr.backgroundColor = UIColor.lightGray.withAlphaComponent(0.2)
23 | })
24 |
25 | //配置指示器
26 | private let indicator = JXSegmentedIndicatorLineView()
27 |
28 | private lazy var listContainerView:JXSegmentedListContainerView = {
29 | return JXSegmentedListContainerView(dataSource: self)
30 | }()
31 |
32 | //指示器内容
33 | private var tabTitles : [String] = []
34 |
35 | private var viewControllers: [WechatArticlesVController] = []
36 |
37 | convenience init(parentModel model: StructureModel, childClickIndex clickIndex: Int) {
38 | self.init()
39 | self.model = model
40 | self.clickIndex = clickIndex
41 | }
42 |
43 | override func viewWillAppear(_ animated: Bool) {
44 | self.navigationController?.navigationBar.isHidden = false
45 | //设置背景色,防止跳转界面视图重叠
46 | self.view.backgroundColor = UIColor.white
47 | }
48 |
49 | override func viewDidLoad() {
50 | super.viewDidLoad()
51 | self.navigationItem.title = model?.name
52 | self.model?.children.forEach({ (value: StructureModel) in
53 | self.tabTitles.append(value.name)
54 | self.viewControllers.append(WechatArticlesVController(cid: value.id))
55 | })
56 | self.segmentedDataSource.titles = self.tabTitles
57 | self.segmentedView.dataSource = self.segmentedDataSource
58 | self.view.addSubview(self.segmentedView)
59 | self.view.addSubview(self.divLine)
60 | self.indicator.indicatorWidth = 20
61 | self.segmentedView.indicators = [self.indicator]
62 | self.segmentedView.defaultSelectedIndex = self.clickIndex ?? 0
63 | self.segmentedView.listContainer = self.listContainerView
64 | self.view.addSubview(self.listContainerView)
65 | }
66 |
67 | override func viewDidLayoutSubviews() {
68 | super.viewDidLayoutSubviews()
69 |
70 | let navigationHeight = navigationController?.navigationBar.frame.size.height ?? 40
71 |
72 | segmentedView.frame = CGRect(x: 0, y: statusBarHeight + navigationHeight, width: screenWidth, height: 50)
73 |
74 | divLine.frame = CGRect(x: 0, y: statusBarHeight + navigationHeight + 50, width: screenWidth, height: 1)
75 |
76 | listContainerView.frame = CGRect(x: 0, y: statusBarHeight + navigationHeight + 50 + 1, width: screenWidth, height: screenHeight - statusBarHeight - 50 - 1)
77 | }
78 | }
79 |
80 | extension StructureDetailVController: JXSegmentedListContainerViewDataSource {
81 |
82 | func numberOfLists(in listContainerView: JXSegmentedListContainerView) -> Int {
83 | return viewControllers.count
84 | }
85 |
86 | func listContainerView(_ listContainerView: JXSegmentedListContainerView, initListAt index: Int) -> JXSegmentedListContainerViewListDelegate {
87 | return viewControllers[index]
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/FunIOS/UI/User/Collect/CollectVController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CollectVController.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/8/10.
6 | //
7 |
8 | import Foundation
9 | import UIKit
10 |
11 | class CollectVController: BaseCVontroller {
12 |
13 | // 当前页面
14 | var page = 0
15 |
16 | private var data = [ArticleItemModel]()
17 |
18 | private lazy var tableView: UITableView = UITableView(frame: .zero, style: .plain).then({ (attr) in
19 | attr.backgroundColor = UIColor.white
20 | attr.delegate = self
21 | attr.dataSource = self
22 | attr.alwaysBounceVertical = true
23 | attr.separatorStyle = .none
24 | attr.register(cellType: CollectCell.self)
25 | })
26 |
27 |
28 | override func viewWillAppear(_ animated: Bool) {
29 | navigationController?.navigationBar.isHidden = false
30 | navigationItem.title = "我的收藏"
31 | }
32 |
33 | override func viewDidLoad() {
34 | let navigationHeight = navigationController?.navigationBar.frame.height ?? 0
35 | self.view.addSubview(tableView)
36 | tableView.snp.makeConstraints { (maker) in
37 | maker.top.equalToSuperview().offset(statusBarHeight + navigationHeight)
38 | maker.leading.equalToSuperview()
39 | maker.trailing.equalToSuperview()
40 | maker.bottom.equalToSuperview()
41 | }
42 | setRefresh()
43 | }
44 |
45 | private func setRefresh() {
46 |
47 | let refreshHeader = RefreshHeader{ [weak self] in
48 | self?.page = 0
49 | self?.getData(false)
50 | }
51 |
52 | refreshHeader.isAutomaticallyChangeAlpha = true
53 | refreshHeader.lastUpdatedTimeLabel?.isHidden = true
54 | tableView.mj_header = refreshHeader
55 | refreshHeader.beginRefreshing()
56 |
57 | tableView.mj_footer = RefreshFooter{ [weak self] in
58 | self?.getData(true)
59 | }
60 | tableView.mj_footer?.isAutomaticallyChangeAlpha = true
61 | }
62 |
63 | private func getData(_ loadMore: Bool = false) {
64 | if !loadMore {
65 | page = 0
66 | } else {
67 | page += 1
68 | }
69 |
70 | Api.fetchCollectArticles(page: page, success: { (value: ArticleModel?) in
71 | //结束刷新
72 | if self.tableView.mj_header!.isRefreshing { self.tableView.mj_header?.endRefreshing()
73 | }
74 |
75 | if self.tableView.mj_footer!.isRefreshing { self.tableView.mj_footer?.endRefreshing()
76 | }
77 |
78 | //是否加载更多
79 | if loadMore {
80 | if value?.datas.count ?? 0 <= 0 {
81 | self.tableView.mj_footer?.endRefreshingWithNoMoreData() } else {
82 | self.data.append(contentsOf: value!.datas)
83 | }
84 | } else {
85 | if value?.datas.count ?? 0 < 20 {
86 | self.tableView.mj_footer?.endRefreshingWithNoMoreData()
87 | }
88 | self.data = value?.datas ?? []
89 | }
90 |
91 | self.tableView.reloadData()
92 | }, error: error(error:))
93 | }
94 |
95 | }
96 |
97 | extension CollectVController: UITableViewDelegate, UITableViewDataSource {
98 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
99 | return data.count
100 | }
101 |
102 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
103 | let tableViewCell = tableView.dequeueReusableCell(for: indexPath, cellType: CollectCell.self)
104 | tableViewCell.model = self.data[indexPath.row]
105 | return tableViewCell
106 | }
107 |
108 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
109 | let model = self.data[indexPath.row]
110 | let webVController = WebVController(title: model.title, url: model.link)
111 | navigationController?.pushViewController(webVController, animated: true)
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/FunIOS/UI/User/Integral/IntegralVController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // IntegralVController.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/8/10.
6 | //
7 |
8 | import Foundation
9 | import UIKit
10 |
11 | class IntegralVController: BaseCVontroller {
12 |
13 |
14 | // 当前页面
15 | var page = 0
16 |
17 | private var data = [IntegralItemModel]()
18 |
19 | private lazy var tableView: UITableView = UITableView(frame: .zero, style: .plain).then({ (attr) in
20 | attr.backgroundColor = UIColor.white
21 | attr.delegate = self
22 | attr.dataSource = self
23 | attr.alwaysBounceVertical = true
24 |
25 | })
26 |
27 |
28 | override func viewWillAppear(_ animated: Bool) {
29 | navigationController?.navigationBar.isHidden = false
30 | navigationItem.title = "积分列表"
31 | }
32 |
33 | override func viewDidLoad() {
34 | let navigationHeight = navigationController?.navigationBar.frame.height ?? 0
35 | self.view.addSubview(tableView)
36 | tableView.snp.makeConstraints { (maker) in
37 | maker.top.equalToSuperview().offset(statusBarHeight + navigationHeight)
38 | maker.leading.equalToSuperview()
39 | maker.trailing.equalToSuperview()
40 | maker.bottom.equalToSuperview()
41 | }
42 | setRefresh()
43 | }
44 |
45 | private func setRefresh() {
46 |
47 | let refreshHeader = RefreshHeader{ [weak self] in
48 | self?.page = 0
49 | self?.getData(false)
50 | }
51 |
52 | refreshHeader.isAutomaticallyChangeAlpha = true
53 | refreshHeader.lastUpdatedTimeLabel?.isHidden = true
54 | tableView.mj_header = refreshHeader
55 | refreshHeader.beginRefreshing()
56 |
57 | tableView.mj_footer = RefreshFooter{ [weak self] in
58 | self?.getData(true)
59 | }
60 | tableView.mj_footer?.isAutomaticallyChangeAlpha = true
61 | }
62 |
63 | private func getData(_ loadMore: Bool = false) {
64 | if !loadMore {
65 | page = 0
66 | } else {
67 | page += 1
68 | }
69 |
70 | Api.fetchMyIntegral(page: page, success: { (value: IntegralModel?) in
71 | //结束刷新
72 | if self.tableView.mj_header!.isRefreshing { self.tableView.mj_header?.endRefreshing()
73 | }
74 |
75 | if self.tableView.mj_footer!.isRefreshing { self.tableView.mj_footer?.endRefreshing()
76 | }
77 |
78 | //是否加载更多
79 | if loadMore {
80 | if value?.datas.count ?? 0 <= 0 {
81 | self.tableView.mj_footer?.endRefreshingWithNoMoreData() } else {
82 | self.data.append(contentsOf: value!.datas)
83 | }
84 | } else {
85 | if value?.datas.count ?? 0 < 20 {
86 | self.tableView.mj_footer?.endRefreshingWithNoMoreData()
87 | }
88 | self.data = value?.datas ?? []
89 | }
90 |
91 | self.tableView.reloadData()
92 | }, error: error(error:))
93 | }
94 |
95 | }
96 |
97 |
98 | extension IntegralVController: UITableViewDataSource, UITableViewDelegate {
99 |
100 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
101 | return self.data.count
102 | }
103 |
104 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
105 |
106 | let tabelCell = UITableViewCell.init(style: .subtitle, reuseIdentifier: "integral_cell")
107 | tabelCell.textLabel?.text = self.data[indexPath.row].reason
108 | tabelCell.detailTextLabel?.text = self.data[indexPath.row
109 | ].desc
110 | tabelCell.selectedBackgroundView = UIView()
111 | return tabelCell
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/FunIOS/UI/User/Ranking/RankingVController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RankingVController.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/8/10.
6 | //
7 |
8 | import Foundation
9 | import UIKit
10 |
11 |
12 | class RankingVController: BaseCVontroller {
13 | // 当前页面
14 | var page = 1
15 |
16 | private var data = [UserCoinLevelModel]()
17 |
18 | private lazy var tableView: UITableView = UITableView(frame: .zero, style: .plain).then({ (attr) in
19 | attr.backgroundColor = UIColor.white
20 | attr.delegate = self
21 | attr.dataSource = self
22 | attr.alwaysBounceVertical = true
23 | attr.rowHeight = 60
24 | attr.register(cellType: RankingCell.self)
25 | })
26 |
27 | override func viewWillAppear(_ animated: Bool) {
28 | navigationController?.navigationBar.isHidden = false
29 | navigationItem.title = "排行榜"
30 | }
31 |
32 | override func viewDidLoad() {
33 | let navigationHeight = navigationController?.navigationBar.frame.height ?? 0
34 | self.view.addSubview(tableView)
35 | tableView.snp.makeConstraints { (maker) in
36 | maker.top.equalToSuperview().offset(statusBarHeight + navigationHeight)
37 | maker.leading.equalToSuperview()
38 | maker.trailing.equalToSuperview()
39 | maker.bottom.equalToSuperview()
40 | }
41 | setRefresh()
42 | }
43 |
44 | private func setRefresh() {
45 |
46 | let refreshHeader = RefreshHeader{ [weak self] in
47 | self?.page = 1
48 | self?.getData(false)
49 | }
50 |
51 | refreshHeader.isAutomaticallyChangeAlpha = true
52 | refreshHeader.lastUpdatedTimeLabel?.isHidden = true
53 | tableView.mj_header = refreshHeader
54 | refreshHeader.beginRefreshing()
55 |
56 | tableView.mj_footer = RefreshFooter{ [weak self] in
57 | self?.getData(true)
58 | }
59 | tableView.mj_footer?.isAutomaticallyChangeAlpha = true
60 | }
61 |
62 | private func getData(_ loadMore: Bool = false) {
63 | if !loadMore {
64 | page = 0
65 | } else {
66 | page += 1
67 | }
68 |
69 | Api.fetchRanking(page: page, success: { (value: RankingModel?) in
70 | //结束刷新
71 | if self.tableView.mj_header!.isRefreshing { self.tableView.mj_header?.endRefreshing()
72 | }
73 |
74 | if self.tableView.mj_footer!.isRefreshing { self.tableView.mj_footer?.endRefreshing()
75 | }
76 |
77 | //是否加载更多
78 | if loadMore {
79 | if value?.datas.count ?? 0 <= 0 {
80 | self.tableView.mj_footer?.endRefreshingWithNoMoreData() } else {
81 | self.data.append(contentsOf: value!.datas)
82 | }
83 | } else {
84 | if value?.datas.count ?? 0 < 20 {
85 | self.tableView.mj_footer?.endRefreshingWithNoMoreData()
86 | }
87 | self.data = value?.datas ?? []
88 | }
89 |
90 | self.tableView.reloadData()
91 | }, error: error(error:))
92 | }
93 | }
94 |
95 | extension RankingVController: UITableViewDataSource, UITableViewDelegate {
96 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
97 | return self.data.count
98 | }
99 |
100 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
101 | let cell = tableView.dequeueReusableCell(for: indexPath, cellType: RankingCell.self)
102 | cell.model = self.data[indexPath.row]
103 | cell.index = indexPath.row + 1
104 | return cell
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/FunIOS/UI/Web/WebVController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WebVController.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/25.
6 | //
7 |
8 | import UIKit
9 | import WebKit
10 |
11 | class WebVController: UIViewController {
12 | var url : String?
13 |
14 | convenience init(title: String? , url: String?) {
15 | self.init()
16 | self.title = title
17 | self.url = url
18 | }
19 |
20 | override func viewWillAppear(_ animated: Bool) {
21 | // let barButton = UIBarButtonItem()
22 | // barButton.title = ""
23 | // self.navigationItem.backBarButtonItem = barButton
24 | self.navigationController?.navigationBar.isHidden = false
25 | }
26 |
27 | override func viewDidLoad() {
28 | super.viewDidLoad()
29 | self.navigationItem.title = title ?? "网页"
30 | //添加webview
31 | let webView = WKWebView.init(frame: view.frame)
32 |
33 | if url != nil {
34 | webView.load(URLRequest.init(url:URL.init(string: url!)!))
35 | }
36 |
37 | self.view.addSubview(webView)
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/FunIOS/UI/Wechat/WechatArticlesVController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WechatArticlesVController.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/25.
6 | //
7 |
8 | import UIKit
9 | import JXSegmentedView
10 |
11 | class WechatArticlesVController: BaseCVontroller {
12 |
13 | // 当前页面
14 | var page = 0
15 | //文章id
16 | var cid : Int = 0
17 | //实体类数组
18 | private var articleList = [ArticleItemModel]()
19 |
20 | private lazy var tableView: UITableView = UITableView(frame: .zero, style: .plain).then({ (attr) in
21 | attr.backgroundColor = UIColor.white
22 | attr.delegate = self
23 | attr.dataSource = self
24 | attr.alwaysBounceVertical = true
25 | attr.separatorStyle = .none
26 | attr.register(cellType: WechatCell.self)
27 | // attr.rowHeight = 150
28 | })
29 |
30 |
31 |
32 | convenience init(cid: Int) {
33 | self.init()
34 | self.cid = cid
35 | }
36 |
37 | override func viewWillAppear(_ animated: Bool) {
38 | self.view.backgroundColor = UIColor.white
39 | }
40 |
41 | override func viewDidLoad() {
42 | self.view.addSubview(tableView)
43 | tableView.snp.makeConstraints { (maker) in
44 | maker.edges.equalToSuperview()
45 | }
46 |
47 | tableView.register(ArticleCell.self, forCellReuseIdentifier: "ArticleCell")
48 |
49 | if #available(iOS 11.0, *) {
50 | UIScrollView.appearance().contentInsetAdjustmentBehavior = .never
51 | } else {
52 | automaticallyAdjustsScrollViewInsets = false
53 | }
54 |
55 | setRefresh()
56 | }
57 |
58 | private func setRefresh() {
59 | let refreshHeader = RefreshHeader{ [weak self] in
60 | self?.getData(false)
61 | }
62 |
63 | refreshHeader.isAutomaticallyChangeAlpha = true
64 | refreshHeader.lastUpdatedTimeLabel?.isHidden = true
65 | tableView.mj_header = refreshHeader
66 | refreshHeader.beginRefreshing()
67 |
68 | tableView.mj_footer = RefreshFooter{ [weak self] in
69 | self?.getData(true)
70 | }
71 | tableView.mj_footer?.isAutomaticallyChangeAlpha = true
72 | }
73 |
74 |
75 | private func getData(_ loadMore: Bool = false) {
76 | if !loadMore {
77 | page = 0
78 | } else {
79 | page += 1
80 | }
81 |
82 | Api.fetchWechatArticles(page: page, cid: cid, success: { (value: ArticleModel?) in
83 | //结束刷新
84 | if self.tableView.mj_header!.isRefreshing { self.tableView.mj_header?.endRefreshing()
85 | }
86 | if self.tableView.mj_footer!.isRefreshing { self.tableView.mj_footer?.endRefreshing()
87 | }
88 | //是否加载更多
89 | if loadMore {
90 | if value?.datas.count ?? 0 <= 0 {
91 | self.tableView.mj_footer?.endRefreshingWithNoMoreData() } else {
92 | self.articleList.append(contentsOf: value!.datas)
93 | }
94 | } else {
95 | if value?.datas.count ?? 0 < 20 {
96 | self.tableView.mj_footer?.endRefreshingWithNoMoreData()
97 | }
98 | self.articleList = value?.datas ?? []
99 | }
100 |
101 | self.tableView.reloadData()
102 | }, error: error(error:))
103 | }
104 | }
105 |
106 | extension WechatArticlesVController: JXSegmentedListContainerViewListDelegate, UITableViewDataSource, UITableViewDelegate, CollectDelegate {
107 | func listView() -> UIView {
108 | view
109 | }
110 |
111 | //数据
112 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
113 | return articleList.count
114 | }
115 |
116 | //每行加载样式
117 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
118 | let tableViewCell = tableView.dequeueReusableCell(for: indexPath, cellType: WechatCell.self)
119 | tableViewCell.collectDelegate = self
120 | tableViewCell.model = articleList[indexPath.row]
121 | return tableViewCell
122 | }
123 |
124 | //item点击事件
125 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
126 | let model = self.articleList[indexPath.row]
127 | let webVController = WebVController(title: model.title, url: model.link)
128 | navigationController?.pushViewController(webVController, animated: true)
129 | }
130 |
131 | //收藏文章
132 | func collectAirticle(cid id: Int, tabCell tabviewCell: UITableViewCell) {
133 | Api.collect(cid: id, success: { value in
134 | let cell = tabviewCell as! WechatCell
135 | cell.refreshCollect(isCollect: true)
136 | self.view.makeToast("收藏成功")
137 | }, error: error(error:))
138 | }
139 |
140 | //取消收藏文章
141 | func uncollectAirticle(cid id: Int, tabCell tabviewCell: UITableViewCell) {
142 | Api.uncollect(cid: id, success: { value in
143 | let cell = tabviewCell as! WechatCell
144 | cell.refreshCollect(isCollect: false)
145 | self.view.makeToast("取消收藏成功")
146 | }, error: error(error:))
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/FunIOS/UI/Wechat/WechatVController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WechatAccountVController.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/21.
6 | //
7 |
8 | import UIKit
9 | import SnapKitExtend
10 | import JXSegmentedView
11 |
12 | class WechatVController: BaseCVontroller {
13 |
14 | private let segmentedView = JXSegmentedView()
15 |
16 | private let segmentedDataSource = JXSegmentedTitleDataSource()
17 |
18 | private lazy var divLine = UIView().then({ (attr) in
19 | attr.backgroundColor = UIColor.lightGray.withAlphaComponent(0.2)
20 | })
21 |
22 | //配置指示器
23 | private let indicator = JXSegmentedIndicatorLineView()
24 |
25 | private lazy var listContainerView:JXSegmentedListContainerView = {
26 | return JXSegmentedListContainerView(dataSource: self)
27 | }()
28 |
29 | //指示器内容
30 | private var tabTitles : [String] = []
31 |
32 | private var viewControllers: [WechatArticlesVController] = []
33 |
34 | override func viewWillAppear(_ animated: Bool) {
35 | self.navigationController?.navigationBar.isHidden = true
36 | }
37 |
38 | override func viewDidLoad() {
39 | Api.fetchWechatSegmented(success: { (value:Array?) in
40 | value?.forEach({ (item: StructureModel) in
41 | self.tabTitles.append(item.name)
42 | self.viewControllers.append(WechatArticlesVController(cid: item.id))
43 | })
44 | self.loadUI()
45 | }, error: error(error:))
46 | }
47 |
48 | private func loadUI() {
49 | self.segmentedDataSource.titles = self.tabTitles
50 | self.segmentedView.dataSource = self.segmentedDataSource
51 | self.view.addSubview(self.segmentedView)
52 | self.view.addSubview(self.divLine)
53 | self.indicator.indicatorWidth = 20
54 | self.segmentedView.indicators = [self.indicator]
55 | self.segmentedView.listContainer = self.listContainerView
56 | self.view.addSubview(self.listContainerView)
57 | }
58 |
59 | override func viewDidLayoutSubviews() {
60 | super.viewDidLayoutSubviews()
61 | segmentedView.frame = CGRect(x: 0, y: statusBarHeight, width: screenWidth, height: 50)
62 |
63 | divLine.frame = CGRect(x: 0, y: statusBarHeight + 50, width: screenWidth, height: 1)
64 |
65 | listContainerView.frame = CGRect(x: 0, y: statusBarHeight + 50 + 1, width: screenWidth, height: screenHeight - statusBarHeight - 50 - 1)
66 | }
67 | }
68 |
69 | extension WechatVController: JXSegmentedListContainerViewDataSource {
70 | func numberOfLists(in listContainerView: JXSegmentedListContainerView) -> Int {
71 | return viewControllers.count
72 | }
73 |
74 | func listContainerView(_ listContainerView: JXSegmentedListContainerView, initListAt index: Int) -> JXSegmentedListContainerViewListDelegate {
75 | return viewControllers[index]
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/FunIOS/View/FloatButtonTableView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BaseUITableView.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/9/7.
6 | //
7 |
8 | import Foundation
9 | import UIKit
10 | import MEVFloatingButton
11 |
12 | public protocol FloatButtonDelegate: NSObjectProtocol {
13 | func floatStatus(forHide hide: Bool, withAnimal animal: Bool)
14 | }
15 |
16 | class FloatButtonTableView: UITableView {
17 |
18 | weak open var floatButtonDelegate: FloatButtonDelegate?
19 |
20 | override init(frame: CGRect, style: UITableView.Style) {
21 | super.init(frame: frame, style: style)
22 | self.addObserver(self, forKeyPath: "contentOffset", options: .new, context: nil)
23 | }
24 |
25 | override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
26 | let offset = change?[NSKeyValueChangeKey.newKey] as! CGPoint
27 |
28 | print("\(offset.y)")
29 |
30 | if offset.y > 400.0 && offset.y < 1000.0 {
31 | floatButtonDelegate?.floatStatus(forHide: false, withAnimal: true)
32 | } else if offset.y > 1000.0 {
33 | floatButtonDelegate?.floatStatus(forHide: false, withAnimal: false)
34 | } else {
35 | floatButtonDelegate?.floatStatus(forHide: true, withAnimal: false)
36 | }
37 | }
38 |
39 |
40 | required init?(coder: NSCoder) {
41 | fatalError("init(coder:) has not been implemented")
42 | }
43 | }
44 |
45 | extension FloatButtonTableView {
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/FunIOS/View/RefreshView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RefreshView.swift
3 | // FunIOS
4 | //
5 | // Created by redli on 2021/7/23.
6 | //
7 |
8 | import MJRefresh
9 |
10 | class RefreshHeader: MJRefreshGifHeader {
11 |
12 | override func prepare() {
13 | super.prepare()
14 | var images = [UIImage]()
15 | for index in 0..<16 {
16 | let image = UIImage(named: "dropdown_loading_0\(index)")
17 | images.append(image!)
18 | }
19 | setImages(images, for: .idle)
20 | setImages(images, for: .refreshing)
21 | setTitle("下拉刷新", for: .idle)
22 | setTitle("松开刷新", for: .pulling)
23 | setTitle("刷新中", for: .refreshing)
24 | }
25 |
26 | override func placeSubviews() {
27 | super.placeSubviews()
28 | gifView?.contentMode = .center
29 | gifView?.frame = CGRect(x: 0, y: 4, width: mj_w, height: 25)
30 | stateLabel?.font = UIFont.systemFont(ofSize: 12)
31 | stateLabel?.frame = CGRect(x: 0, y: 35, width: mj_w, height: 14)
32 | }
33 |
34 | }
35 |
36 |
37 | class RefreshFooter: MJRefreshAutoGifFooter {
38 |
39 | override func prepare() {
40 | super.prepare()
41 | // 设置控件的高度
42 | mj_h = 50
43 | // 图片数组
44 | var images = [UIImage]()
45 | // 遍历
46 | for index in 0..<8 {
47 | let image = UIImage(named: "sendloading_18x18_\(index)")
48 | images.append(image!)
49 | }
50 | // 设置空闲状态的图片
51 | setImages(images, for: .idle)
52 | // 设置刷新状态的图片
53 | setImages(images, for: .refreshing)
54 | setTitle("上拉加载数据", for: .idle)
55 | setTitle("正在努力加载", for: .pulling)
56 | setTitle("正在努力加载", for: .refreshing)
57 | setTitle("没有更多数据啦", for: .noMoreData)
58 | }
59 |
60 | override func placeSubviews() {
61 | super.placeSubviews()
62 | gifView?.mj_x = 135
63 | }
64 | }
65 |
66 |
--------------------------------------------------------------------------------
/FunIOS/icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hanklee9820/FunIOS/6023b32af72b85e977b5307c8f166577fe800fe3/FunIOS/icon-60@3x.png
--------------------------------------------------------------------------------
/Podfile:
--------------------------------------------------------------------------------
1 | source 'https://github.com/CocoaPods/Specs.git'
2 | platform :ios, '10.0'
3 | use_frameworks!
4 |
5 | target 'FunIOS' do
6 |
7 | # pod 'Moya'//网络二次封装
8 | # pod 'HYBUnicodeReadable', '~> 1.1'
9 | pod 'PrintBeautifulLog'
10 | pod 'Alamofire' #网络, '~> 4.7'
11 | pod 'MJRefresh' #刷新
12 | pod 'LLCycleScrollView' #轮播
13 | # pod 'EmptyDataSet-Swift'
14 | pod 'HandyJSON'
15 | pod 'Kingfisher' #图片
16 | pod 'Then' #语法糖
17 | #pod 'SnapKit', '~> 4.2.0'
18 | pod 'SnapKitExtend' #自动布局扩展
19 | pod 'SVProgressHUD'
20 | pod 'MBProgressHUD'
21 | pod 'Reusable' #可复用
22 | #pod 'Tabman' #tab导航
23 | pod 'JXSegmentedView'
24 | pod 'LGButton'
25 | pod 'Toast-Swift', '~> 5.0.1'
26 | pod 'TagListView', '~> 1.0' #tag标签栏
27 | pod 'SwiftEventBus', :tag => '5.1.0', :git => 'https://github.com/cesarferreira/SwiftEventBus.git'
28 | # pod 'MEVFloatingButton' #UITableView,UICollectionView和UIScrollView超类,用于在它上面显示一个可定制的浮动按钮
29 |
30 | end
31 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # FunIOS - [玩Android](https://www.wanandroid.com/index) IOS Swift 版本
2 |
3 | ## 介绍
4 |
5 | **我一直都是做Android开发的,一直以来在断断续续的学习IOS,学了Object-C,可以看懂,写就不太习惯,后来直接上手了swift,突然觉得太舒服了,跟kotlin,dart差不多,本项目是纯代目撸布局。使用SnapKit 拘束布局搭建**
6 |
7 | ## 改善
8 | **有需求欢迎issue,空余时间会持续更新中**
9 |
10 | ## 依赖第三方
11 |
12 | ```
13 | pod 'PrintBeautifulLog' #日志
14 | pod 'Alamofire' , '~> 4.7' #网络
15 | pod 'MJRefresh' #刷新
16 | pod 'LLCycleScrollView' #轮播
17 | pod 'HandyJSON' #序列化 反序列
18 | pod 'Kingfisher' #图片
19 | pod 'Then' #语法糖
20 | pod 'SnapKitExtend' #自动布局扩展
21 | pod 'SVProgressHUD' #加载框
22 | pod 'MBProgressHUD' #加载框
23 | pod 'Reusable' #可复用
24 | pod 'JXSegmentedView' #顶部tab
25 | pod 'LGButton' #按钮
26 | pod 'Toast-Swift', '~> 5.0.1' #吐司
27 | pod 'TagListView', '~> 1.0' #tag标签栏
28 | pod 'SwiftEventBus', :tag => '5.1.0', :git => 'https://github.com/cesarferreira/SwiftEventBus.git' #跨界面通信
29 |
30 | ```
31 |
32 | ## 版本号
33 | ***V1.0***
34 | *基本模块的实现 主页 项目 公众号 体系 我的 数据获取显示,登录等*
35 |
36 | ***V1.1***
37 | *更新app logo 图标,删除没必要的png,增加收藏功能,网络请求增加失败回调统一处理*
38 |
39 | ***V1.2***
40 | *删除不必要的文件,首页列表增加置顶功能(置顶功能冗余度有点高,不方便移植,后续慢慢琢磨一下)*
41 |
42 | ## 使用方法
43 | **下载源码,根目录执行 pod install 用 xcode 打开 FunIOS.xcworkspace 即可**
44 |
45 | ## 截图
46 |
47 |
48 |
49 |
50 |
51 |
52 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------