├── .gitignore
├── Podfile
├── Podfile.lock
├── README.md
├── TQGO.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
│ └── xcuserdata
│ │ └── yxy.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
└── xcuserdata
│ └── yxy.xcuserdatad
│ └── xcschemes
│ ├── TQGO.xcscheme
│ └── xcschememanagement.plist
├── TQGO.xcworkspace
├── contents.xcworkspacedata
├── xcshareddata
│ └── IDEWorkspaceChecks.plist
└── xcuserdata
│ └── yxy.xcuserdatad
│ └── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
├── TQGO
├── Category
│ ├── Date+Common.swift
│ ├── DispatchQueue+common.swift
│ ├── NSObject+Common.swift
│ ├── Notification.Name+YXYCommon.swift
│ ├── String+Common.swift
│ ├── UIButton+YXYCommon.swift
│ ├── UIColor+YXYCommon.swift
│ ├── UIDevice+Common.swift
│ ├── UIImage+YYCommon.swift
│ ├── UISegmentControll+YXYCommon.swift
│ ├── UITableViewCell+RXCommon.swift
│ ├── UITextField+YYCommon.swift
│ ├── UIView+Common.swift
│ ├── UIViewController+RXCommon.swift
│ └── UIViewController+YXYCommon.swift
├── Class
│ ├── Base
│ │ ├── AppDelegate.swift
│ │ ├── BaseNavigationController.swift
│ │ ├── BaseTabBarVC.swift
│ │ ├── BaseTableView.swift
│ │ ├── BaseVC.swift
│ │ ├── Common.swift
│ │ └── ProjectTabBarVC.swift
│ ├── CreditPayModule
│ │ └── Controller
│ │ │ └── CreditPayVC.swift
│ ├── LoginRegisterModule
│ │ ├── Controller
│ │ │ ├── LoginVC.swift
│ │ │ └── RegisterVC.swift
│ │ └── ViewModel
│ │ │ ├── LoginVM.swift
│ │ │ └── RegisterVM.swift
│ ├── PersonalCenterModule
│ │ ├── Controller
│ │ │ └── PersonalCenterVC.swift
│ │ ├── Model
│ │ │ └── UserInfo.swift
│ │ └── View
│ │ │ └── MyHeaderCell.swift
│ ├── PromotionModule
│ │ ├── Controller
│ │ │ ├── GoodsDetailVC.swift
│ │ │ ├── PromotionSubVC.swift
│ │ │ └── PromotionVC.swift
│ │ ├── Model
│ │ │ ├── MenuModel.swift
│ │ │ ├── PromosModel.swift
│ │ │ └── PromotionModel.swift
│ │ └── View
│ │ │ └── PromotionSubCell.swift
│ ├── ShopCartModule
│ │ └── Controller
│ │ │ └── ShopCartVC.swift
│ └── UnicomAreaModule
│ │ ├── Controller
│ │ └── UnicomAreaVC.swift
│ │ ├── Model
│ │ ├── GoodsModel.swift
│ │ ├── SlideShowModel.swift
│ │ └── UnicomIndexModel.swift
│ │ └── View
│ │ ├── ADCell.swift
│ │ ├── DiscountAreaCell.swift
│ │ ├── HotCollectionViewCell.swift
│ │ ├── HotGoodsCell.swift
│ │ └── UnicomMenuCell.swift
├── Info.plist
├── Macro
│ ├── AppConstant.swift
│ ├── Macro.swift
│ └── TQGO-Bridging-Header.h
├── Model
│ └── APIModel
│ │ └── APIResultModel.swift
├── Resource
│ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── icon-20@2x.png
│ │ │ ├── icon-20@3x.png
│ │ │ ├── icon-29@2x.png
│ │ │ ├── icon-29@3x.png
│ │ │ ├── icon-40@2x.png
│ │ │ ├── icon-40@3x.png
│ │ │ ├── icon-60@2x.png
│ │ │ ├── icon-60@3x.png
│ │ │ └── icon_1024.png
│ │ ├── Contents.json
│ │ ├── LanchIcon
│ │ │ ├── Contents.json
│ │ │ └── icon_launch.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── icon_launch@2x.png
│ │ │ │ └── icon_launch@3x.png
│ │ ├── MyImage
│ │ │ ├── Contents.json
│ │ │ ├── icon_arrow_right_white.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── icon_arrow_right_white@2x.png
│ │ │ │ └── icon_arrow_right_white@3x.png
│ │ │ ├── icon_header.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── icon_header@2x.png
│ │ │ │ └── icon_header@3x.png
│ │ │ ├── icon_phone_num.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── icon_phone_num@2x.png
│ │ │ │ └── icon_phone_num@3x.png
│ │ │ ├── icon_secure_close.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── icon_secure_close@2x.png
│ │ │ │ └── icon_secure_close@3x.png
│ │ │ ├── icon_secure_visible.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── icon_secure_visible@2x.png
│ │ │ │ └── icon_secure_visible@3x.png
│ │ │ ├── icon_security_lock.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── icon_security_lock@2x.png
│ │ │ │ └── icon_security_lock@3x.png
│ │ │ └── icon_verity_code.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── icon_verity_code@2x.png
│ │ │ │ └── icon_verity_code@3x.png
│ │ ├── TabbarImage
│ │ │ ├── Contents.json
│ │ │ ├── icon_tabbar_default_credit.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── icon_tabbar_default_credit@2x.png
│ │ │ │ └── icon_tabbar_default_credit@3x.png
│ │ │ ├── icon_tabbar_default_personalCenter.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── icon_tabbar_default_personalCenter@2x.png
│ │ │ │ └── icon_tabbar_default_personalCenter@3x.png
│ │ │ ├── icon_tabbar_default_promotion.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── icon_tabbar_default_promotion@2x.png
│ │ │ │ └── icon_tabbar_default_promotion@3x.png
│ │ │ ├── icon_tabbar_default_unicom.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── icon_tabbar_default_unicom@2x.png
│ │ │ │ └── icon_tabbar_default_unicom@3x.png
│ │ │ ├── icon_tabbar_selected_credit.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── icon_tabbar_selected_credit@2x.png
│ │ │ │ └── icon_tabbar_selected_credit@3x.png
│ │ │ ├── icon_tabbar_selected_personalCenter.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── icon_tabbar_selected_personalCenter@2x.png
│ │ │ │ └── icon_tabbar_selected_personalCenter@3x.png
│ │ │ ├── icon_tabbar_selected_promotion.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── icon_tabbar_selected_promotion@2x.png
│ │ │ │ └── icon_tabbar_selected_promotion@3x.png
│ │ │ └── icon_tabbar_selected_unicom.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── icon_tabbar_selected_unicom@2x.png
│ │ │ │ └── icon_tabbar_selected_unicom@3x.png
│ │ └── UnicomImage
│ │ │ ├── Contents.json
│ │ │ ├── icon_flag_blue.imageset
│ │ │ ├── Contents.json
│ │ │ ├── icon_flag_blue@2x.png
│ │ │ └── icon_flag_blue@3x.png
│ │ │ ├── icon_gift_area.imageset
│ │ │ ├── Contents.json
│ │ │ ├── icon_gift_area@2x.png
│ │ │ └── icon_gift_area@3x.png
│ │ │ ├── icon_goods_default.imageset
│ │ │ ├── Contents.json
│ │ │ ├── icon_goods_default@2x.png
│ │ │ └── icon_goods_default@3x.png
│ │ │ ├── icon_home_banner_default.imageset
│ │ │ ├── Contents.json
│ │ │ ├── icon_home_banner_default@2x.png
│ │ │ └── icon_home_banner_default@3x.png
│ │ │ ├── icon_phone_area.imageset
│ │ │ ├── Contents.json
│ │ │ ├── icon_phone_area@2x.png
│ │ │ └── icon_phone_area@3x.png
│ │ │ └── icon_search.imageset
│ │ │ ├── Contents.json
│ │ │ ├── icon_search@2x.png
│ │ │ └── icon_search@3x.png
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ └── BimineData
│ │ ├── UnicomAreaDiscountZone.plist
│ │ ├── UnicomAreaRecommGoods.plist
│ │ ├── UnicomBanner.plist
│ │ ├── goodsJJYX.plist
│ │ ├── goodsMZXH.plist
│ │ ├── goodsPJZX.plist
│ │ ├── homeBanner.plist
│ │ └── menu.plist
└── Tool
│ ├── NetworkManager
│ ├── NetworkManager.swift
│ ├── NetworkManagerLoginRegister.swift
│ ├── NetworkManagerPromotion.swift
│ └── NetworkManagerUnicom.swift
│ ├── RealmTool
│ └── RealmManager.swift
│ ├── Regex
│ └── Regex.swift
│ └── ViewTool
│ ├── YXYBanner
│ └── YXYBanner.swift
│ └── YXYPageView
│ ├── YXYMenuTitleView.swift
│ ├── YXYPageContentView.swift
│ └── YXYPageView.swift
├── TQGOTests
├── Info.plist
└── TQGOTests.swift
└── TQGOUITests
├── Info.plist
└── TQGOUITests.swift
/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 | .DS_Store
3 | UserInterfaceState.xcuserstate
4 | # Xcode
5 | .DS_Store
6 | */build/*
7 | *.pbxuser
8 | !default.pbxuser
9 | *.mode1v3
10 | !default.mode1v3
11 | *.mode2v3
12 | !default.mode2v3
13 | *.perspectivev3
14 | !default.perspectivev3
15 | xcuserdata
16 | *.moved-aside
17 | DerivedData
18 | .idea/
19 | *.hmap
20 | *.xccheckout
21 | *.xcworkspace
22 | !default.xcworkspace
23 | Report.xml
24 | #CocoaPods
25 | Pods
26 | !Podfile
--------------------------------------------------------------------------------
/Podfile:
--------------------------------------------------------------------------------
1 | platform :ios, '10.0'
2 |
3 | target 'TQGO' do
4 | use_frameworks!
5 |
6 | pod 'MJRefresh', '~> 3.2.2'
7 |
8 | #pod 'RealmSwift', '~> 4.1.0'
9 | #pod 'SwiftyJSON', '~> 5.0.0'
10 | #pod 'Kingfisher', '~> 5.9.0'
11 | #pod 'Alamofire', '~> 5.0.0-rc.3'
12 | #pod 'SnapKit', '~> 5.0.1'
13 | #pod 'HandyJSON', '~> 5.0.1'
14 | #pod 'RxSwift', '~> 5.0.1'
15 | #pod 'RxCocoa', '~> 5.0.1'
16 | #pod 'Toast-Swift', '~> 5.0.0'
17 |
18 | target 'TQGOTests' do
19 | inherit! :search_paths
20 | # Pods for testing
21 | end
22 |
23 | target 'TQGOUITests' do
24 | inherit! :search_paths
25 | # Pods for testing
26 | end
27 |
28 | end
29 |
--------------------------------------------------------------------------------
/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - MJRefresh (3.2.2)
3 |
4 | DEPENDENCIES:
5 | - MJRefresh (~> 3.2.2)
6 |
7 | SPEC REPOS:
8 | https://github.com/CocoaPods/Specs.git:
9 | - MJRefresh
10 |
11 | SPEC CHECKSUMS:
12 | MJRefresh: 72a46ecaa2a0feaf48fc5198dff95f25f8bb27c6
13 |
14 | PODFILE CHECKSUM: 0d9159dd8014ff4b30edff92a7b714ed6ec6ad36
15 |
16 | COCOAPODS: 1.11.3
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SwiftProject
2 | 
3 |
4 | > swift项目实战
5 |
6 | #支持#
7 |
8 | **iOS 13.2 、swift5.1**
9 |
10 | >[简书](https://www.jianshu.com/p/ac7e9959646f)
11 |
12 | >拉取项目后,需自行根据podfile文件拉取pod,此过程需等待一会
13 |
14 | >网络请求部分:网络层封装的接口通信为笔者自行书写,包括公共参数、加密、加签过程,此部分需根据自己项目与后台协定方式为准,为模仿真实网络请求过程,设置Alamofire的超时时间为0.2s,且数据为本地plist文件读取。
15 |
16 | >本项目进行了关键数据脱敏,所以忽略相关数据
17 |
18 | >登录功能:MVVM+RxSwift
19 |
20 | >[使用Swift Package Manager管理第三方库](https://www.jianshu.com/p/b9ba7154f4c2)
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/TQGO.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/TQGO.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/TQGO.xcodeproj/project.xcworkspace/xcuserdata/yxy.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO.xcodeproj/project.xcworkspace/xcuserdata/yxy.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/TQGO.xcodeproj/xcuserdata/yxy.xcuserdatad/xcschemes/TQGO.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
42 |
48 |
49 |
50 |
52 |
58 |
59 |
60 |
61 |
62 |
72 |
74 |
80 |
81 |
82 |
83 |
89 |
91 |
97 |
98 |
99 |
100 |
102 |
103 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/TQGO.xcodeproj/xcuserdata/yxy.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | TQGO.xcscheme
8 |
9 | orderHint
10 | 9
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 9A70491320F2FD5600982DCB
16 |
17 | primary
18 |
19 |
20 | 9A70492720F2FD5800982DCB
21 |
22 | primary
23 |
24 |
25 | 9A70493220F2FD5800982DCB
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/TQGO.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/TQGO.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/TQGO.xcworkspace/xcuserdata/yxy.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
9 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/TQGO/Category/Date+Common.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Date+Common.swift
3 | // TQGO q 123
4 | //
5 | // Created by YXY on 2018/7/11.
6 | // Copyright © 2018年 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 | 不规范协助
12 | // 1
13 | enum kTimeFormat:String{
14 | case format_default = "yyyy-MM-dd HH:mm:ss"
15 | case format_yyMdHm = "yy-MM-dd HH:mm"
16 | case format_yyyyMdHm = "yyyy-MM-dd HH:mm"
17 | case format_yMd = "yyyy-MM-dd"
18 | case format_MdHms = "MM-dd HH:mm:ss"
19 | case format_MdHm = "MM-dd HH:mm"
20 | case format_Hms = "HH:mm:ss"
21 | case format_Hm = "HH:mm"
22 | case format_Md = "MM-dd"
23 | case format_yyMd = "yy-MM-dd"
24 | case format_YYMMdd = "yyyyMMdd"
25 | case format_yyyyMdHms = "yyyyMMddHHmmss"
26 | case format_yyyyMdHmsS = "yyyy-MM-dd HH:mm:ss.SSS"
27 | case format_yyyyMMddHHmmssSSS = "yyyyMMddHHmmssSSS"
28 | case format_yMdWithSlash = "yyyy/MM/dd"
29 | case format_yM = "yyyy-MM"
30 | case format_yMdChangeSeparator = "yyyy.MM.dd"
31 | }
32 | // 2
33 | extension Date{
34 |
35 | }
36 | //3
37 | //4
38 |
--------------------------------------------------------------------------------
/TQGO/Category/DispatchQueue+common.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DispatchQueue+common.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2019/3/25.
6 | // Copyright © 2019 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | // pick
12 | extension DispatchQueue{
13 | private static var _onceTracker = [String]()
14 | /// 单例 仅创建一次
15 | ///
16 | /// - Parameters:
17 | /// - token: token
18 | /// - block: 代码块
19 | public class func once(token: String, block:()->Void) {
20 | objc_sync_enter(self)
21 | defer { objc_sync_exit(self) }
22 | if _onceTracker.contains(token) {
23 | return
24 | }
25 | _onceTracker.append(token)
26 | block()
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/TQGO/Category/NSObject+Common.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+Common.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/7/20.
6 | // Copyright © 2018年 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | extension NSObject{
13 |
14 | /// 模型转JSONString
15 | var modelToJSONString : String {
16 | let jsonData = try? JSONSerialization.data(withJSONObject: self, options: [])
17 | let jsonStr = String(data: jsonData!, encoding: String.Encoding.utf8)
18 | return jsonStr!
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/TQGO/Category/Notification.Name+YXYCommon.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Notification.Name+YXYCommon.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2019/11/15.
6 | // Copyright © 2019 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | extension Notification.Name{
13 |
14 | // 通知key 避免key重复
15 | private enum kNotify_Key:String {
16 | case ShopcartNum //购物车角标数
17 | case RefreshData // 商品兑换成功或失败后刷新数据
18 | case RefreshGift // 一次性领取礼包后刷新数据
19 | case LoginOut // 退出登录后刷新数据
20 | case Login //登录后刷新数据
21 | case ChangeCity// 切换城市后刷新数据
22 | case RefreshGood // 兑换商品后刷新商品列表数据
23 | case WXpay // 微信支付处理数据
24 | case CityCode// 当前选择的城市编码
25 | case CurrentCity //// 当前选择的城市名称
26 | case LocationCity// 当前定位的城市名称
27 | case LocationCityCode /// 当前定位的城市编码
28 | case IsHiddenrechargeButton // 0 不可购买 1可购买
29 | case OrderNo // 下单流水号
30 | case More // 领取礼包点击查看更多
31 | case safeName //
32 | case safeIDNO //
33 | case LeaveTop //= "kLeaveTop" //首页滑动通知
34 | }
35 | public static let kLeaveTop = Notification.Name("com.techwis.\(kNotify_Key.LeaveTop)")
36 | public static let kShopcartNum = Notification.Name("com.techwis.\(kNotify_Key.ShopcartNum)")
37 | }
38 |
--------------------------------------------------------------------------------
/TQGO/Category/String+Common.swift:
--------------------------------------------------------------------------------
1 | //
2 | // String+Common.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/7/11.
6 | // Copyright © 2018年 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | extension String{
13 |
14 | var md5 : String{
15 | let str = self.cString(using: String.Encoding.utf8)
16 | let strLen = CC_LONG(self.lengthOfBytes(using: String.Encoding.utf8))
17 | let digestLen = Int(CC_MD5_DIGEST_LENGTH)
18 | let result = UnsafeMutablePointer.allocate(capacity: digestLen)
19 | CC_MD5(str!, strLen, result)
20 | let hash = NSMutableString()
21 | for i in 0 ..< digestLen {
22 | hash.appendFormat("%02x", result[i])
23 | }
24 | // result.deinitialize()
25 | result.deinitialize(count: 1)
26 | return String(format: hash as String)
27 | }
28 |
29 | static func nowTimeWithFormat(format:String) -> String {
30 | let dateFormatter:DateFormatter = DateFormatter()
31 | dateFormatter.dateFormat = format
32 | dateFormatter.locale = Locale(identifier: kDate_Location)
33 | return dateFormatter.string(from: Date())
34 | }
35 |
36 | /// 获取一段字符串的宽度
37 | ///
38 | /// - Parameter fontSize: 字体大小
39 | /// - Returns: 字符串宽度
40 | func width(fontSize:CGFloat) -> CGFloat {
41 | return self.size(withAttributes: [NSAttributedString.Key.font : UIFont.systemFont(ofSize: fontSize)]).width
42 | }
43 |
44 | }
45 |
46 | //MARK: 字符串截取
47 | extension String{
48 | /// 从某个位置开始截取:
49 | /// - Parameter index: 起始位置
50 | public func substring(from index: Int) -> String {
51 | if(self.count > index){
52 | let startIndex = self.index(self.startIndex,offsetBy: index)
53 | let subString = self[startIndex.. String {
63 | if(self.count > index){
64 | let endindex = self.index(self.startIndex, offsetBy: index)
65 | let subString = self[self.startIndex.. String{
75 | var string = String()
76 | if(rangs.location >= 0) && (count > (rangs.location + rangs.length)){
77 | let startIndex = self.index(self.startIndex,offsetBy: rangs.location)
78 | let endIndex = self.index(self.startIndex,offsetBy: (rangs.location + rangs.length))
79 | let subString = self[startIndex.. Bool {
91 | let pre :NSPredicate = NSPredicate(format: "SELF MATCHES %@", argumentArray: [regex])
92 | return pre.evaluate(with: self)
93 | }
94 |
95 | /// 手机号分服务商
96 | func isMobileNumberClassification() ->Bool{
97 | /**
98 | 15 * 手机号码
99 | 16 * 移动:134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188,1705
100 | 17 * 联通:130,131,132,152,155,156,185,186,1709
101 | 18 * 电信:133,1349,153,180,189,1700
102 | 19 */
103 | // NSString * MOBILE = @"^1((3//d|5[0-35-9]|8[025-9])//d|70[059])\\d{7}$";//总况
104 | /**
105 | 23 10 * 中国移动:China Mobile
106 | 24 11 * 134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188,1705
107 | 25 12 */
108 | let CM = "^((13[4-9])|(147)|(15[0-2,7-9])|(17[2,8])|(18[2-4,7-8]))\\d{8}|(1705)\\d{7}$";
109 | // NSString *CM = @"^((13[4-9])|(147)|(15[0-2,7-9])|(178)|(18[2-4,7-8]))\\d{8}|(1705)\\d{7}$";
110 | // NSString * CM = @"^1(34[0-8]|(3[5-9]|5[017-9]|78|8[278])\\d|705)\\d{7}$";
111 | /**
112 | 28 15 * 中国联通:China Unicom
113 | 29 16 * 130,131,132,152,155,156,185,186,1709
114 | 30 17 */
115 | let CU = "^((13[0-2])|(145)|(15[5-6])|(17[1,5,6])|(18[5,6]))\\d{8}|(1709)\\d{7}$";
116 | // NSString *CU = @"^((13[0-2])|(145)|(15[5-6])|(176)|(18[5,6]))\\d{8}|(1709)\\d{7}$";
117 | // NSString * CU = @"^1((3[0-2]|5[256]|8[56])\\d|709)\\d{7}$";
118 | /**
119 | 33 20 * 中国电信:China Telecom
120 | 34 21 * 133,1349,153,180,189,1700
121 | 35 22 */
122 | let CT = "^((133)|(149)|(153)|(17[3,7])|(18[0,1,9]))\\d{8}$";
123 | // NSString *CT = @"^((133)|(153)|(177)|(18[0,1,9]))\\d{8}$";
124 | // NSString * CT = @"^1((33|53|8[09])\\d|349|700)\\d{7}$";
125 | /**
126 | 40 25 * 大陆地区固话及小灵通
127 | 41 26 * 区号:010,020,021,022,023,024,025,027,028,029
128 | 42 27 * 号码:七位或八位
129 | 43 28 */
130 | let PHS = "^0(10|2[0-5789]|\\d{3})\\d{7,8}$";
131 | // NSPredicate *regextestmobile = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", MOBILE];
132 |
133 | if ( isValidateByRegex(regex: CM) || isValidateByRegex(regex:CU) || isValidateByRegex(regex:CT) || isValidateByRegex(regex:PHS)){
134 | return true
135 | }else {
136 | return false
137 | }
138 | }
139 | }
140 |
141 | //MARK: file
142 | extension String{
143 | /// 判断文件是否存在
144 | ///
145 | /// - Returns: 存在true 不存在false
146 | func fileExist() -> Bool {
147 | return FileManager.default.fileExists(atPath: self as String)
148 | }
149 |
150 | /// 创建文件夹
151 | func fileCreateDirectory() {
152 | try! FileManager.default.createDirectory(at: NSURL(fileURLWithPath:self , isDirectory: true, relativeTo: nil) as URL, withIntermediateDirectories: true, attributes: nil)
153 | }
154 |
155 | /// 拼接路径
156 | ///
157 | /// - Parameter byAppendingPaths: 要拼接的文件名
158 | /// - Returns: 拼接后的路径
159 | func fileByAppendingPaths(byAppendingPaths: String) -> String {
160 |
161 | return (self as NSString).strings(byAppendingPaths: [byAppendingPaths]).first!
162 | }
163 |
164 | /// 读取本地数据
165 | func getLocalPlistData() -> NSArray? {
166 | let path = Bundle.main.path(forResource: self, ofType: "plist")
167 | return NSArray(contentsOfFile: path!)
168 | }
169 | }
170 |
171 | ////MARK: 实现NSRange与Range的相互转换
172 | //extension String {
173 | //
174 | // //Range转换为NSRange
175 | // func nsRange(from range: Range) -> NSRange {
176 | // let from = range.lowerBound.samePosition(in: utf16)
177 | // let to = range.upperBound.samePosition(in: utf16)
178 | // return NSRange(location: utf16.distance(from: utf16.startIndex, to: from ?? 0),
179 | // length: utf16.distance(from: from, to: to))
180 | // }
181 | //
182 | // //Range转换为NSRange
183 | // func range(from nsRange: NSRange) -> Range? {
184 | // guard
185 | // let from16 = utf16.index(utf16.startIndex, offsetBy: nsRange.location,
186 | // limitedBy: utf16.endIndex),
187 | // let to16 = utf16.index(from16, offsetBy: nsRange.length,
188 | // limitedBy: utf16.endIndex),
189 | // let from = String.Index(from16, within: self),
190 | // let to = String.Index(to16, within: self)
191 | // else { return nil }
192 | // return from ..< to
193 | // }
194 | //}
195 |
--------------------------------------------------------------------------------
/TQGO/Category/UIButton+YXYCommon.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIButton+YXYCommon.swift
3 | // TQGO
4 | // UIButton通用分类
5 | // Created by YXY on 2019/10/22.
6 | // Copyright © 2019 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 |
13 | enum YXYButtonEdgeInsetsStyle {
14 | case YXYButtonEdgeInsetsStyleTop // image在上,label在下
15 | case YXYButtonEdgeInsetsStyleLeft // image在左,label在右
16 | case YXYButtonEdgeInsetsStyleBottom // image在下,label在上
17 | case YXYButtonEdgeInsetsStyleRight // image在右,label在左
18 | }
19 | //MARK: title image 位置布局
20 | extension UIButton{
21 |
22 | /// 调整文字和图片相对位置
23 | /// - Parameter style: 显示样式
24 | /// - Parameter imageTitleSpace: 间距
25 | func layoutButtonWithEdgeInsetsStyle(style:YXYButtonEdgeInsetsStyle,imageTitleSpace:CGFloat) {
26 | let imageWith:CGFloat = imageView?.frame.width ?? 0;
27 | let imageHeight:CGFloat = imageView?.frame.height ?? 0;
28 |
29 | var labelWidth:CGFloat = 0.0;
30 | var labelHeight:CGFloat = 0.0;
31 |
32 | if (kSystemVersion >= 8.0) {
33 | // 由于iOS8中titleLabel的size为0,用下面的这种设置
34 | labelWidth = titleLabel?.intrinsicContentSize.width ?? 0;
35 | labelHeight = titleLabel?.intrinsicContentSize.height ?? 0;
36 | } else {
37 | labelWidth = titleLabel?.frame.width ?? 0;
38 | labelHeight = titleLabel?.frame.height ?? 0;
39 | }
40 |
41 | // 2. 声明全局的imageEdgeInsets和labelEdgeInsets
42 | var imageEdgeInsets: UIEdgeInsets = UIEdgeInsets.zero;
43 | var labelEdgeInsets: UIEdgeInsets = UIEdgeInsets.zero;
44 |
45 | // 3. 根据style和space得到imageEdgeInsets和labelEdgeInsets的值
46 | switch style {
47 | case .YXYButtonEdgeInsetsStyleTop:
48 | imageEdgeInsets = UIEdgeInsets(top: -labelHeight-imageTitleSpace/2.0, left: 0, bottom: 0, right: -labelWidth)
49 | labelEdgeInsets = UIEdgeInsets(top: 0, left: -imageWith, bottom: -imageHeight-imageTitleSpace/2.0, right: 0)
50 | case .YXYButtonEdgeInsetsStyleLeft:
51 | imageEdgeInsets = UIEdgeInsets(top:0, left:-imageTitleSpace/2.0, bottom:0, right: imageTitleSpace/2.0);
52 | labelEdgeInsets = UIEdgeInsets(top:0,left: imageTitleSpace/2.0, bottom:0, right: -imageTitleSpace/2.0);
53 | case .YXYButtonEdgeInsetsStyleBottom:
54 | imageEdgeInsets = UIEdgeInsets(top:0, left:0, bottom:-labelHeight-imageTitleSpace/2.0, right: -labelWidth);
55 | labelEdgeInsets = UIEdgeInsets(top:-imageHeight-imageTitleSpace/2.0,left: -imageWith, bottom:0, right: 0);
56 | case .YXYButtonEdgeInsetsStyleRight:
57 | imageEdgeInsets = UIEdgeInsets(top:0,left: labelWidth+imageTitleSpace/2.0, bottom:0, right: -labelWidth-imageTitleSpace/2.0);
58 | labelEdgeInsets = UIEdgeInsets(top:0, left:-imageWith-imageTitleSpace/2.0, bottom:0, right: imageWith+imageTitleSpace/2.0);
59 | }
60 |
61 | // 4. 赋值
62 | titleEdgeInsets = labelEdgeInsets;
63 | self.imageEdgeInsets = imageEdgeInsets;
64 | }
65 |
66 | }
67 |
68 |
--------------------------------------------------------------------------------
/TQGO/Category/UIColor+YXYCommon.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIColor+YXYCommon.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2019/10/23.
6 | // Copyright © 2019 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 | extension UIColor {
12 |
13 | public func asImage(_ size:CGSize) -> UIImage? {
14 |
15 | var resultImage:UIImage? = nil
16 |
17 | let rect = CGRect(x:0, y:0, width: size.width, height: size.height)
18 | UIGraphicsBeginImageContextWithOptions(rect.size, false, UIScreen.main.scale)
19 | guard let context = UIGraphicsGetCurrentContext() else {
20 | return resultImage
21 | }
22 |
23 | context.setFillColor(self.cgColor)
24 | context.fill(rect)
25 | resultImage = UIGraphicsGetImageFromCurrentImageContext()
26 | UIGraphicsEndImageContext()
27 | return resultImage
28 |
29 | }
30 |
31 | }
32 |
33 |
34 |
--------------------------------------------------------------------------------
/TQGO/Category/UIDevice+Common.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIDevice+Common.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/7/11.
6 | // Copyright © 2018年 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 |
13 | extension UIDevice {
14 | /// 获取设备具体详细的型号
15 | var modelName: String {
16 | var systemInfo = utsname()
17 | uname(&systemInfo)
18 | let machineMirror = Mirror(reflecting: systemInfo.machine)
19 | let identifier = machineMirror.children.reduce("") { identifier, element in
20 | guard let value = element.value as? Int8, value != 0 else { return identifier }
21 | return identifier + String(UnicodeScalar(UInt8(value)))
22 | }
23 |
24 | // struct utsname systemInfo;
25 | // uname(&systemInfo);
26 | // NSString *platform = [NSString stringWithCString:systemInfo.machine
27 | // encoding:NSUTF8StringEncoding];
28 |
29 | switch identifier {
30 |
31 | case "iPhone3,1", "iPhone3,2", "iPhone3,3": return "iPhone 4"
32 | case "iPhone4,1": return "iPhone 4s"
33 | case "iPhone5,1", "iPhone5,2": return "iPhone 5"
34 | case "iPhone5,3", "iPhone5,4": return "iPhone 5c"
35 | case "iPhone6,1", "iPhone6,2": return "iPhone 5s"
36 | case "iPhone7,2": return "iPhone 6"
37 | case "iPhone7,1": return "iPhone 6 Plus"
38 | case "iPhone8,1": return "iPhone 6s"
39 | case "iPhone8,2": return "iPhone 6s Plus"
40 | case "iPhone9,1": return "iPhone 7 (CDMA)"
41 | case "iPhone9,3": return "iPhone 7 (GSM)"
42 | case "iPhone9,2": return "iPhone 7 Plus (CDMA)"
43 | case "iPhone9,4": return "iPhone 7 Plus (GSM)"
44 | case "iPhone10,1","iPhone10,4": return "iPhone 8"
45 | case "iPhone10,2","iPhone10,5": return "iPhone 8 Plus"
46 |
47 | case "iPhone10,3","iPhone10,6": return "iPhone X"
48 | case "iPhone11,8": return "iPhone XR"
49 | case "iPhone11,2": return "iPhone Xs"
50 | case "iPhone11,4","iPhone11,6": return "iPhone XsMax"
51 | case "iPhone12,1": return "iPhone 11"
52 | case "iPhone12,3": return "iPhone 11 Pro"
53 | case "iPhone12,5": return "iPhone 11 Pro Max"
54 |
55 | case "iPad1,1": return "iPad 1"
56 | case "iPad2,1": return "iPad 2"
57 | case "iPad2,2": return "iPad 2"
58 | case "iPad2,3": return "iPad 2"
59 | case "iPad2,4": return "iPad 2"
60 | case "iPad3,1": return "iPad 3rd"
61 | case "iPad3,2": return "iPad 3rd"
62 | case "iPad3,3": return "iPad 3rd"
63 | case "iPad3,4": return "iPad 4th"
64 | case "iPad3,5": return "iPad 4th"
65 | case "iPad3,6": return "iPad 4th"
66 | case "iPad6,11": return "iPad 5th"
67 | case "iPad6,12": return "iPad 5th"
68 | case "iPad7,5": return "iPad 6th"
69 | case "iPad7,6": return "iPad 6th"
70 | case "iPad7,11": return "iPad 7th"
71 | case "iPad7,12": return "iPad 7th"
72 |
73 | case "iPad2,5": return "iPad Mini"
74 | case "iPad2,6": return "iPad Mini"
75 | case "iPad2,7": return "iPad Mini"
76 | case "iPad4,4": return "iPad Mini 2"
77 | case "iPad4,5": return "iPad Mini 2"
78 | case "iPad4,6": return "iPad Mini 2"
79 | case "iPad4,7": return "iPad Mini 3"
80 | case "iPad4,8": return "iPad Mini 3"
81 | case "iPad4,9": return "iPad Mini 3"
82 | case "iPad5,1": return "iPad Mini 4"
83 | case "iPad5,2": return "iPad Mini 4"
84 | case "iPad11,1": return "iPad Mini 5"
85 | case "iPad11,2": return "iPad Mini 5"
86 |
87 | case "iPad4,1": return "iPad Air"
88 | case "iPad4,2": return "iPad Air"
89 | case "iPad4,3": return "iPad Air"
90 | case "iPad5,3": return "iPad Air 2"
91 | case "iPad5,4": return "iPad Air 2"
92 | case "iPad11,3": return "iPad Air 3rd"
93 | case "iPad11,4": return "iPad Air 3rd"
94 |
95 | case "iPad6,7": return "iPad Pro 12.9-inch 1st"
96 | case "iPad6,8": return "iPad Pro 12.9-inch 1st"
97 | case "iPad6,3": return "iPad Pro 9.7-inch"
98 | case "iPad6,4": return "iPad Pro 9.7-inch"
99 | case "iPad7,1": return "iPad Pro 12.9-inch 2nd"
100 | case "iPad7,2": return "iPad Pro 12.9-inch 2nd"
101 | case "iPad7,3": return "iPad Pro 10.5-inch"
102 | case "iPad7,4": return "iPad Pro 10.5-inch"
103 | case "iPad8,5": return "iPad Pro 12.9-inch 3rd"
104 | case "iPad8,6": return "iPad Pro 12.9-inch 3rd"
105 | case "iPad8,7": return "iPad Pro 12.9-inch 3rd"
106 | case "iPad8,8": return "iPad Pro 12.9-inch 3rd"
107 | case "iPad8,1": return "iPad Pro 11-inch"
108 | case "iPad8,2": return "iPad Pro 11-inch"
109 | case "iPad8,3": return "iPad Pro 11-inch"
110 | case "iPad8,4": return "iPad Pro 11-inch"
111 |
112 | case "iPod1,1": return "iPod Touch 1st"
113 | case "iPod2,1": return "iPod Touch 2nd"
114 | case "iPod3,1": return "iPod Touch 3rd"
115 | case "iPod4,1": return "iPod Touch 4th"
116 | case "iPod5,1": return "iPod Touch 5th"
117 | case "iPod7,1": return "iPod Touch 6th"
118 |
119 | case "i386", "x86_64": return "iPhone Simulator"
120 |
121 | default: return identifier
122 | }
123 | }
124 | }
125 |
126 |
--------------------------------------------------------------------------------
/TQGO/Category/UIImage+YYCommon.swift:
--------------------------------------------------------------------------------
1 |
2 | //
3 | // UIImage+YYCommon.swift
4 | // TQGO
5 | //
6 | // Created by YXY on 2019/10/23.
7 | // Copyright © 2019 Techwis. All rights reserved.
8 | //
9 |
10 | import Foundation
11 | import Photos
12 | import UIKit
13 | extension UIImage{
14 |
15 |
16 | /// 旋转image
17 | /// - Parameter orientation: 旋转方向
18 | func imageRotation(orientation:UIImage.Orientation) ->UIImage{
19 |
20 | var rotate: Double = 0.0;
21 | var rect : CGRect = CGRect.zero
22 | var translateX:CGFloat = 0;
23 | var translateY: CGFloat = 0;
24 | var scaleX :CGFloat = 1.0;
25 | var scaleY :CGFloat = 1.0;
26 |
27 | switch (orientation) {
28 | case .left:
29 | rotate = Double.pi/2;
30 | rect = CGRect(x: 0, y: 0, width: self.size.height, height: self.size.width)
31 | translateX = 0
32 | translateY = -(rect.size.width)
33 | scaleY = rect.size.width / rect.size.height
34 | scaleX = rect.size.height / rect.size.width
35 | break
36 | case .right:
37 | rotate = 3 * Double.pi/2;
38 | rect = CGRect(x: 0, y: 0, width: self.size.height, height: self.size.width)
39 | translateX = -(rect.size.height)
40 | translateY = 0
41 | scaleY = rect.size.width / rect.size.height
42 | scaleX = rect.size.height / rect.size.width
43 | break
44 | case .down:
45 | rotate = Double.pi;
46 | rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
47 | translateX = -(rect.size.width)
48 | translateY = -(rect.size.height)
49 | break
50 | default:
51 | rotate = 0.0;
52 | rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
53 | translateX = 0;
54 | translateY = 0;
55 | break;
56 | }
57 |
58 | UIGraphicsBeginImageContext(rect.size)
59 | let context:CGContext? = UIGraphicsGetCurrentContext()
60 | //做CTM变换
61 | context!.translateBy(x: 0, y: rect.size.height)
62 | context!.scaleBy(x: 1.0, y: -1.0)
63 | context!.rotate(by: CGFloat(rotate));
64 | context!.translateBy(x: translateX, y: translateY);
65 | context!.scaleBy(x: scaleX, y: scaleY);
66 | //绘制图片
67 | context?.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: rect.size.width, height: rect.size.height), byTiling: false)
68 | let newPic:UIImage? = UIGraphicsGetImageFromCurrentImageContext();
69 | UIGraphicsEndImageContext()
70 | return newPic!
71 | }
72 |
73 |
74 | /// 切圆角
75 | /// - Parameter radius: 角度
76 | func cornerRadius(radius: CGFloat) -> UIImage{
77 | let rect = CGRect(origin: CGPoint.zero, size: size)
78 | let bezierPath = UIBezierPath(roundedRect:rect , cornerRadius: radius)
79 | UIGraphicsBeginImageContextWithOptions(rect.size, false, UIScreen.main.scale);
80 | let context = UIGraphicsGetCurrentContext()
81 | context?.addPath(bezierPath.cgPath);
82 | context?.clip()
83 | draw(in: rect)
84 | context?.drawPath(using: CGPathDrawingMode.fillStroke)
85 | let output : UIImage? = UIGraphicsGetImageFromCurrentImageContext()
86 | UIGraphicsEndImageContext()
87 | return output!
88 |
89 |
90 | }
91 | }
92 |
93 |
94 | extension UIImage{
95 |
96 | /// 保存图片至相册
97 | /// - Parameter albumName: 相册名字
98 | func savePhoto(albumName:String) {
99 | var assetsID:String?
100 | PHPhotoLibrary.shared().performChanges({
101 | assetsID = PHAssetCreationRequest.creationRequestForAsset(from: self).placeholderForCreatedAsset?.localIdentifier
102 | }) { (success, error) in
103 | if success == false {return}
104 | let assetCollection = self.createAssetCollection(albumName: albumName)
105 | PHPhotoLibrary.shared().performChanges({
106 | guard assetsID != nil else{
107 | return
108 | }
109 | let asset = PHAsset.fetchAssets(withLocalIdentifiers: [assetsID!], options: nil)
110 | guard assetCollection != nil else{
111 | return
112 | }
113 | PHAssetCollectionChangeRequest(for:assetCollection!)?.addAssets(asset)
114 | }) { (success, error) in
115 |
116 | }
117 | }
118 | }
119 |
120 | /// 获取指定名字相册 存在直接返回 不存在则创建
121 | /// - Parameter albumName: 相册名字
122 | func createAssetCollection(albumName:String) -> PHAssetCollection? {
123 | let assetCollections = PHAssetCollection.fetchAssetCollections(with: PHAssetCollectionType.album, subtype: PHAssetCollectionSubtype.albumRegular, options: nil)
124 | for i in 0.. {
14 | var prepareForReuseKey: Int8 = 0
15 | if let prepareForReuseOB = objc_getAssociatedObject(base, &prepareForReuseKey) as? Observable {
16 | return prepareForReuseOB
17 | }
18 | let prepareForReuseOB = Observable.of(
19 | sentMessage(#selector(Base.prepareForReuse)).map { _ in }
20 | , deallocated)
21 | .merge()
22 | objc_setAssociatedObject(base, &prepareForReuseKey, prepareForReuseOB, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
23 |
24 | return prepareForReuseOB
25 | }
26 | // 提供一个重用垃圾回收袋
27 | public var reuseBag: DisposeBag {
28 | MainScheduler.ensureExecutingOnScheduler()
29 | var prepareForReuseBag: Int8 = 0
30 | if let bag = objc_getAssociatedObject(base, &prepareForReuseBag) as? DisposeBag {
31 | return bag
32 | }
33 |
34 | let bag = DisposeBag()
35 | objc_setAssociatedObject(base, &prepareForReuseBag, bag, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
36 |
37 | _ = sentMessage(#selector(Base.prepareForReuse))
38 | .subscribe(onNext: { [weak base] _ in
39 | let newBag = DisposeBag()
40 | guard let base = base else {return}
41 | objc_setAssociatedObject(base, &prepareForReuseBag, newBag, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
42 | })
43 | return bag
44 | }
45 | }
46 |
47 | /*
48 | 处理cell响应button事件时的 cell复用导致序列重复订阅响应
49 | 方式一:
50 | 重用响应prepareForReuse,只要发现我们的cell已发生重用,通过RxSwift就会接受到一个重用序列的响应,起到绑定效果
51 | 这里还合并了cell的销毁序列,毕竟cell都销毁了也就没有任何响应的意义
52 | cell.button.rx.tap.takeUntil(cell.rx.prepareForReuse)
53 | .subscribe(onNext: { () in
54 | print("点击了 \(indexPath)")
55 | })
56 | 通过takeUntil限定了button的点击响应能力
57 |
58 |
59 | 方式二:
60 | cell.button.rx.tap
61 | .subscribe(onNext: { () in
62 | print("点击了 \(indexPath)")
63 | })
64 | .disposed(by: cell.rx.reuseBag)
65 |
66 | 作者:Cooci_和谐学习_不急不躁
67 | 链接:https://www.jianshu.com/p/1c186afdae3b
68 | 来源:简书
69 | 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
70 |
71 | 方式三: 基类封装
72 | class LGCustomCell: UITableViewCell{
73 | var disposeBag = DisposeBag()
74 | override func prepareForReuse() {
75 | super.prepareForReuse()
76 |
77 | disposeBag = DisposeBag()
78 | }
79 | }
80 |
81 | 作者:Cooci_和谐学习_不急不躁
82 | 链接:https://www.jianshu.com/p/1c186afdae3b
83 | 来源:简书
84 | 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
85 | */
86 |
--------------------------------------------------------------------------------
/TQGO/Category/UITextField+YYCommon.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UITextField+YYCommon.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2019/10/23.
6 | // Copyright © 2019 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 | extension UITextField{
12 |
13 | func leftViewWithImgName(imgName:String , size:CGSize){
14 |
15 | let containerView = UIView(frame: CGRect(x: 0, y: 0, width: 60, height: self.frame.height))
16 | let y = (self.frame.height - size.height)/2;
17 | let imgV = UIImageView(frame: CGRect(x: 0, y: y, width: size.width, height: size.height))
18 | containerView.addSubview(imgV)
19 | self.leftViewMode = UITextField.ViewMode.always
20 | imgV.contentMode = UIView.ContentMode.left;
21 | imgV.image = kImage(name: imgName)
22 | self.leftView = containerView
23 |
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/TQGO/Category/UIView+Common.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+Common.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/7/11.
6 | // Copyright © 2018年 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | //MARK: Frame
13 | extension UIView {
14 | public var x: CGFloat{
15 | get{
16 | return self.frame.origin.x
17 | }
18 | set{
19 | var r = self.frame
20 | r.origin.x = newValue
21 | self.frame = r
22 | }
23 | }
24 |
25 | public var y: CGFloat{
26 | get{
27 | return self.frame.origin.y
28 | }
29 | set{
30 | var r = self.frame
31 | r.origin.y = newValue
32 | self.frame = r
33 | }
34 | }
35 | /// 右边界的x值
36 | public var rightX: CGFloat{
37 | get{
38 | return self.x + self.width
39 | }
40 | set{
41 | var r = self.frame
42 | r.origin.x = newValue - frame.width
43 | self.frame = r
44 | }
45 | }
46 | /// 下边界的y值
47 | public var bottomY: CGFloat{
48 | get{
49 | return self.y + self.height
50 | }
51 | set{
52 | var r = self.frame
53 | r.origin.y = newValue - frame.height
54 | self.frame = r
55 | }
56 | }
57 |
58 | public var centerX : CGFloat{
59 | get{
60 | return self.center.x
61 | }
62 | set{
63 | self.center = CGPoint(x: newValue, y: self.center.y)
64 | }
65 | }
66 |
67 | public var centerY : CGFloat{
68 | get{
69 | return self.center.y
70 | }
71 | set{
72 | self.center = CGPoint(x: self.center.x, y: newValue)
73 | }
74 | }
75 |
76 | public var width: CGFloat{
77 | get{
78 | return self.frame.width
79 | }
80 | set{
81 | var r = self.frame
82 | r.size.width = newValue
83 | self.frame = r
84 | }
85 | }
86 | public var height: CGFloat{
87 | get{
88 | return self.frame.height
89 | }
90 | set{
91 | var r = self.frame
92 | r.size.height = newValue
93 | self.frame = r
94 | }
95 | }
96 |
97 |
98 | public var origin: CGPoint{
99 | get{
100 | return self.frame.origin
101 | }
102 | set{
103 | self.x = newValue.x
104 | self.y = newValue.y
105 | }
106 | }
107 |
108 | public var size: CGSize{
109 | get{
110 | return self.frame.size
111 | }
112 | set{
113 | self.width = newValue.width
114 | self.height = newValue.height
115 | }
116 | }
117 |
118 | }
119 |
120 | extension UIView{
121 | /// 获取视图根控制器
122 | func viewController() -> UIViewController? {
123 | var next: UIResponder? = self.next
124 |
125 | repeat {
126 | if (next?.isKind(of: UIViewController.self) == true) {
127 | return next as? UIViewController
128 | }
129 | next = next?.next
130 | }while (next != nil)
131 | return nil
132 | }
133 | // extension UIView {
134 | // //返回该view所在VC
135 | // func firstViewController() -> UIViewController? {
136 | // for view in sequence(first: self.superview, next: { $0?.superview }) {
137 | // if let responder = view?.next {
138 | // if responder.isKind(of: UIViewController.self){
139 | // return responder as? UIViewController
140 | // }
141 | // }
142 | // }
143 | // return nil
144 | // }
145 | // }
146 |
147 | /// 截图
148 | func snapshotImage() -> UIImage {
149 | UIGraphicsBeginImageContextWithOptions(bounds.size, isOpaque, 0)
150 | layer.render(in: UIGraphicsGetCurrentContext()!)
151 | let snap : UIImage? = UIGraphicsGetImageFromCurrentImageContext()
152 | UIGraphicsEndImageContext()
153 | return snap!
154 | }
155 |
156 |
157 | /// 可设置指定位置圆角
158 | /// - Parameter corners: 圆角位置
159 | /// - Parameter radius: 角度
160 | func cornerRadius(corners: UIRectCorner = .allCorners , radius: CGFloat) {
161 | layoutIfNeeded()
162 | let maskPath = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
163 | let maskLayer = CAShapeLayer()
164 | maskLayer.frame = bounds
165 | maskLayer.path = maskPath.cgPath
166 | layer.mask = maskLayer
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/TQGO/Category/UIViewController+RXCommon.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIViewController+RXCommon.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2019/11/5.
6 | // Copyright © 2019 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | extension Reactive where Base: UIViewController {
13 | /// 用于 `startAnimating()` 和 `stopAnimating()` 方法的 binder
14 | public var isLoadingAnimating: Binder {
15 | return Binder(self.base, binding: { (vc, active) in
16 | vc.loadingAnimating(isAnimating: active)
17 | })
18 | }
19 | }
20 |
21 |
22 |
--------------------------------------------------------------------------------
/TQGO/Category/UIViewController+YXYCommon.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIViewController+YXYCommon.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2019/11/5.
6 | // Copyright © 2019 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | extension UIViewController{
13 |
14 | func loadingAnimating(isAnimating:Bool) {
15 | isAnimating ? self.view.makeToastActivity(ToastPosition.center) : self.view.hideToastActivity()
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/TQGO/Class/Base/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/7/9.
6 | // Copyright © 2018年 Techwis. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import RealmSwift
11 |
12 | @UIApplicationMain
13 | class AppDelegate: UIResponder, UIApplicationDelegate {
14 |
15 | var window: UIWindow?
16 |
17 | internal func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
18 | // 配置Realm
19 | RealmManager.config()
20 | window = UIWindow(frame:UIScreen.main.bounds)
21 | window?.rootViewController = ProjectTabBarVC();
22 | window?.makeKeyAndVisible()
23 |
24 | // 配置Toast显示位置
25 | ToastManager.shared.position = .center
26 | return true
27 | }
28 |
29 | func applicationWillResignActive(_ application: UIApplication) {
30 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
31 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
32 | }
33 |
34 | func applicationDidEnterBackground(_ application: UIApplication) {
35 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
36 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
37 | }
38 |
39 | func applicationWillEnterForeground(_ application: UIApplication) {
40 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
41 | }
42 |
43 | func applicationDidBecomeActive(_ application: UIApplication) {
44 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
45 | }
46 |
47 | func applicationWillTerminate(_ application: UIApplication) {
48 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
49 | }
50 |
51 |
52 | }
53 |
54 |
--------------------------------------------------------------------------------
/TQGO/Class/Base/BaseNavigationController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BaseNavigationController.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/7/9.
6 | // Copyright © 2018年 Techwis. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class BaseNavigationController: UINavigationController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 |
16 | }
17 |
18 | override func didReceiveMemoryWarning() {
19 | super.didReceiveMemoryWarning()
20 | // Dispose of any resources that can be recreated.
21 | }
22 |
23 | override func pushViewController(_ viewController: UIViewController, animated: Bool) {
24 | if(viewControllers.count > 0){
25 | // 隐藏底部tabBar
26 | viewController.hidesBottomBarWhenPushed = true
27 | }
28 | super.pushViewController(viewController, animated: animated)
29 | }
30 |
31 | override func popViewController(animated: Bool) -> UIViewController? {
32 | //判断即将到栈底
33 | if (viewControllers.count == 0) {
34 | //显示自定义的tabBar
35 | tabBarController?.tabBar.isHidden = false;
36 | }
37 | // pop出栈
38 | return super.popViewController(animated: animated)
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/TQGO/Class/Base/BaseTabBarVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BaseTabBarVC.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/7/9.
6 | // Copyright © 2018年 Techwis. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class BaseTabBarVC: UITabBarController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 |
16 | // Do any additional setup after loading the view.
17 | }
18 |
19 | override func didReceiveMemoryWarning() {
20 | super.didReceiveMemoryWarning()
21 | // Dispose of any resources that can be recreated.
22 | }
23 |
24 |
25 | /*
26 | // MARK: - Navigation
27 |
28 | // In a storyboard-based application, you will often want to do a little preparation before navigation
29 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
30 | // Get the new view controller using segue.destinationViewController.
31 | // Pass the selected object to the new view controller.
32 | }
33 | */
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/TQGO/Class/Base/BaseTableView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BaseTableView.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2019/4/9.
6 | // Copyright © 2019 Techwis. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class BaseTableView: UITableView {
12 |
13 | /*
14 | // Only override draw() if you perform custom drawing.
15 | // An empty implementation adversely affects performance during animation.
16 | override func draw(_ rect: CGRect) {
17 | // Drawing code
18 | }
19 | */
20 |
21 |
22 | }
23 |
24 | // 实现识别多手势代理
25 | extension BaseTableView:UIGestureRecognizerDelegate{
26 | func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
27 | return true
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/TQGO/Class/Base/BaseVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BaseVC.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/7/9.
6 | // Copyright © 2018年 Techwis. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class BaseVC: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 |
16 | // Do any additional setup after loading the view.
17 | }
18 |
19 | override func didReceiveMemoryWarning() {
20 | super.didReceiveMemoryWarning()
21 | // Dispose of any resources that can be recreated.
22 | }
23 |
24 | override func viewWillAppear(_ animated: Bool) {
25 | super.viewWillAppear(animated)
26 | if title == "我的" || title == "联通专区" {
27 | navigationController?.navigationBar.isHidden = true
28 | }
29 | }
30 |
31 | override func viewDidDisappear(_ animated: Bool) {
32 | super.viewDidDisappear(animated)
33 | if title == "我的" || title == "联通专区" {
34 | navigationController?.navigationBar.isHidden = false
35 | }
36 | }
37 |
38 | /*
39 | // MARK: - Navigation
40 |
41 | // In a storyboard-based application, you will often want to do a little preparation before navigation
42 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
43 | // Get the new view controller using segue.destinationViewController.
44 | // Pass the selected object to the new view controller.
45 | }
46 | */
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/TQGO/Class/Base/Common.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Common.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2019/12/13.
6 | // Copyright © 2019 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Contacts
11 | class Common {
12 |
13 | /// 通讯录授权
14 | static func getContactsAuthStatus() -> Bool {
15 | var authorizedMsg :String?
16 | var isAuthorized = false
17 |
18 | switch CNContactStore.authorizationStatus(for: CNEntityType.contacts) {
19 | case CNAuthorizationStatus.notDetermined:do {
20 | authorizedMsg = "用户未确定是否授权"
21 | let contactStore = CNContactStore()
22 | let semaphore = DispatchSemaphore(value: 0)
23 | contactStore.requestAccess(for: CNEntityType.contacts) { (granted, error) in
24 | if (error != nil) {
25 | isAuthorized = false
26 | DLog("contact 授权 error:\(String(describing: error))");
27 | }else if(granted == false){
28 | isAuthorized = false
29 | }else {
30 | isAuthorized = true
31 | }
32 | semaphore.signal()
33 | }
34 | semaphore.wait()
35 | }
36 | case CNAuthorizationStatus.restricted:
37 | authorizedMsg = "iOS 设备上一些许可配置阻止程序与通讯录数据库进行交互"
38 | isAuthorized = false
39 | case CNAuthorizationStatus.denied:
40 | authorizedMsg = "用户明确的拒绝了你的程序对通讯录的访问"
41 | isAuthorized = false
42 | case CNAuthorizationStatus.authorized:
43 | authorizedMsg = "default 未知信息"
44 | isAuthorized = true
45 | default:
46 | authorizedMsg = "default 未知信息"
47 | isAuthorized = false
48 | }
49 | DLog("在iOS 9及以上设备上,通讯录授权信息:\(authorizedMsg!)\(isAuthorized))");
50 | return isAuthorized
51 | }
52 | }
53 |
54 |
--------------------------------------------------------------------------------
/TQGO/Class/Base/ProjectTabBarVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ProjectTabBarVC.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/7/9.
6 | // Copyright © 2018年 Techwis. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ProjectTabBarVC: UITabBarController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 |
16 | let promVC = PromotionVC()
17 | let creditPay = CreditPayVC()
18 | let pcVC = PersonalCenterVC()
19 | let unicomAreaVC = UnicomAreaVC()
20 | let shopCartVC = ShopCartVC()
21 |
22 | let baseNav_1 = BaseNavigationController(rootViewController: promVC)
23 | let baseNav_2 = BaseNavigationController(rootViewController: unicomAreaVC)
24 | let baseNav_3 = BaseNavigationController(rootViewController: creditPay)
25 | let baseNav_4 = BaseNavigationController(rootViewController: shopCartVC)
26 | let baseNav_5 = BaseNavigationController(rootViewController: pcVC)
27 |
28 | let barItem_1 = UITabBarItem(title: "促销", image: UIImage(named:"icon_tabbar_default_promotion"), selectedImage: UIImage(named: "icon_tabbar_selected_promotion"))
29 | let barItem_2 = UITabBarItem(title: "联通专区", image: UIImage(named:"icon_tabbar_default_promotion"), selectedImage: UIImage(named: "icon_tabbar_selected_promotion"))
30 | let barItem_3 = UITabBarItem(title: "信用付", image: UIImage(named:"icon_tabbar_default_credit"), selectedImage: UIImage(named: "icon_tabbar_selected_credit"))
31 | let barItem_4 = UITabBarItem(title: "购物车", image: UIImage(named:"icon_tabbar_default_personalCenter"), selectedImage: UIImage(named: "icon_tabbar_selected_personalCenter"))
32 | let barItem_5 = UITabBarItem(title: "我的", image: UIImage(named:"icon_tabbar_default_personalCenter"), selectedImage: UIImage(named: "icon_tabbar_selected_personalCenter"))
33 |
34 | baseNav_1.tabBarItem = barItem_1
35 | baseNav_2.tabBarItem = barItem_2
36 | baseNav_3.tabBarItem = barItem_3
37 | baseNav_4.tabBarItem = barItem_4
38 | baseNav_5.tabBarItem = barItem_5
39 | viewControllers = [baseNav_1,baseNav_2,baseNav_3,baseNav_4,baseNav_5]
40 |
41 | }
42 |
43 | override func didReceiveMemoryWarning() {
44 | super.didReceiveMemoryWarning()
45 | // Dispose of any resources that can be recreated.
46 | }
47 |
48 |
49 | /*
50 | // MARK: - Navigation
51 |
52 | // In a storyboard-based application, you will often want to do a little preparation before navigation
53 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
54 | // Get the new view controller using segue.destinationViewController.
55 | // Pass the selected object to the new view controller.
56 | }
57 | */
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/TQGO/Class/CreditPayModule/Controller/CreditPayVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CreditPayVC.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/10/11.
6 | // Copyright © 2018年 Techwis. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class CreditPayVC: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 | self.title = "信用付"
16 | view.backgroundColor = .white
17 | // Do any additional setup after loading the view.
18 | }
19 |
20 | override func didReceiveMemoryWarning() {
21 | super.didReceiveMemoryWarning()
22 | // Dispose of any resources that can be recreated.
23 | }
24 |
25 |
26 | /*
27 | // MARK: - Navigation
28 |
29 | // In a storyboard-based application, you will often want to do a little preparation before navigation
30 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
31 | // Get the new view controller using segue.destinationViewController.
32 | // Pass the selected object to the new view controller.
33 | }
34 | */
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/TQGO/Class/LoginRegisterModule/Controller/RegisterVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RegisterVC.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2019/10/28.
6 | // Copyright © 2019 Techwis. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class RegisterVC: UIViewController {
12 |
13 | let registerVM = RegisterVM()
14 |
15 | override func viewDidLoad() {
16 | super.viewDidLoad()
17 | title = "注册"
18 | view.backgroundColor = .white
19 |
20 | }
21 |
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/TQGO/Class/LoginRegisterModule/ViewModel/LoginVM.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LoginVM.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2019/10/29.
6 | // Copyright © 2019 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 |
13 | class LoginVM {
14 |
15 |
16 | let phoneNumOB : Observable
17 | var phoneNumStrOB : Observable
18 | let passwordOB : Observable
19 | let passwordStrOB : Observable
20 | let securityCodeOB: Observable
21 | let securityCodeStrOB: Observable
22 | let loginEnableOB: Observable
23 | var requestErrorOB: ReplaySubject = ReplaySubject.create(bufferSize: 1)
24 | let loading : PublishSubject = PublishSubject()
25 | var disposeBag :DisposeBag?
26 |
27 | init(phoneNum: Observable,password: Observable,securityCode:Observable,segment:Observable) {
28 | phoneNumStrOB = phoneNum.map{
29 | $0.count > kLimitPhone ? $0.substring(to: kLimitPhone) : $0
30 | }.share(replay: 1)
31 |
32 | phoneNumOB = phoneNum
33 | .map { $0.count == kLimitPhone && $0.isMobileNumberClassification() }
34 | .share(replay: 1)
35 |
36 | passwordStrOB = password
37 | .map { $0.count > kLimitPassword ? $0.substring(to: kLimitPassword) : $0 }
38 | .share(replay: 1)
39 |
40 | passwordOB = password
41 | .map { $0.count < kLimitPassword && $0.count >= 8 }
42 | .share(replay: 1)
43 |
44 | securityCodeStrOB = securityCode.map{
45 | $0.count > kLimitSecurityCode ? $0.substring(to: kLimitSecurityCode) : $0
46 | }.share(replay: 1)
47 |
48 | securityCodeOB = securityCode
49 | .map { $0.count == kLimitSecurityCode}
50 | .share(replay: 1)
51 |
52 | let loginPasswordEnableOB = Observable.combineLatest(phoneNumOB, passwordOB,segment) { $0 && $1 && ($2 == 0) }
53 | .share(replay: 1)
54 | let loginsecurityCodeEnableOB = Observable.combineLatest(phoneNumOB, securityCodeOB,segment) { $0 && $1 && ($2 == 1)}
55 | .share(replay: 1)
56 | loginEnableOB = Observable.combineLatest(loginPasswordEnableOB, loginsecurityCodeEnableOB) { $0 || $1 }.share(replay: 1)
57 | }
58 |
59 | //MARK: 登录请求
60 | func loginRequest() {
61 | var phoneNo = ""
62 | var loginPwd = ""
63 | loading.onNext(true)
64 | phoneNumStrOB.subscribe(onNext: { (str) in
65 | phoneNo = str
66 | }).disposed(by: disposeBag!)
67 | passwordStrOB.subscribe(onNext: { (str) in
68 | loginPwd = str
69 | }).disposed(by: disposeBag!)
70 |
71 | let param = ["phoneNo":phoneNo,"loginPwd":loginPwd.md5,"loginType":"0"]
72 | NetworkManager.loadData(api: APIInterfaceLoginRegister.userLogin(params:param), completionClosure: {[weak self] (response) -> (Void) in
73 |
74 | self?.loading.onNext(false)
75 |
76 | let flag = response.returnCode == KErrorCode.KErrorCode_SUCCESSE.rawValue ? true : false
77 | self?.requestErrorOB.onNext(flag ? APIError.apiError_done : APIError.apiError_serverMessage(response.returnMsg ?? ""))
78 | guard flag == true else{return}
79 | // 存储用户信息
80 | guard let model = UserInfo.deserialize(from: response.toJSONString(), designatedPath: "data") else {return}
81 | let realm = RealmManager.instance
82 | try? realm.write {
83 | realm.add(model, update: Realm.UpdatePolicy.all)
84 | }
85 |
86 | }) {[weak self] (fail) -> (Void) in
87 | // 因未配置真正请求 所以请求必定失败 以下操作为模拟请求成功
88 | self?.loading.onNext(false)
89 | self?.requestErrorOB.onNext(APIError.apiError_done)
90 |
91 |
92 | // 此处为真正的请求失败后需做的做操
93 | // self?.loading.onNext(false)
94 | // self?.requestErrorOB.onNext(APIError.apiError_serverMessage("网络异常请重试"))
95 | }
96 | }
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/TQGO/Class/LoginRegisterModule/ViewModel/RegisterVM.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewModel.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2019/10/28.
6 | // Copyright © 2019 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | class RegisterVM {
13 | let phoneNumOB = Observable.create { (observer) -> Disposable in
14 |
15 |
16 | return Disposables.create()
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/TQGO/Class/PersonalCenterModule/Controller/PersonalCenterVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PersonalCenterVC.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/7/9.
6 | // Copyright © 2018年 Techwis. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class PersonalCenterVC: BaseVC {
12 |
13 | lazy var tableView:UITableView = {
14 | let tableView = UITableView()
15 | tableView.delegate = self
16 | tableView.dataSource = self
17 | tableView.register(MyHeaderCell.self, forCellReuseIdentifier:"k")
18 | tableView.separatorStyle = .none
19 | view.addSubview(tableView)
20 | tableView.snp.makeConstraints { (make) in
21 | make.edges.equalToSuperview()
22 | make.top.equalToSuperview().offset(-kNabBarHeight)
23 | }
24 | return tableView
25 | }()
26 |
27 | override func viewDidLoad() {
28 | super.viewDidLoad()
29 | title = "我的"
30 | view.backgroundColor = .white
31 | tableView.backgroundColor = .white
32 |
33 |
34 | }
35 |
36 | override func didReceiveMemoryWarning() {
37 | super.didReceiveMemoryWarning()
38 | // Dispose of any resources that can be recreated.
39 | }
40 |
41 | }
42 |
43 |
44 | extension PersonalCenterVC:UITableViewDataSource,UITableViewDelegate{
45 |
46 | func numberOfSections(in tableView: UITableView) -> Int {
47 | return 1
48 | }
49 |
50 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
51 | return 1
52 | }
53 |
54 | func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
55 |
56 | return kSafeAreaBottomHeight > 0 ? 150+24.0 :150.0
57 | }
58 |
59 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
60 |
61 | return tableView.dequeueReusableCell(withIdentifier: "k", for: indexPath)
62 | }
63 |
64 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
65 |
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/TQGO/Class/PersonalCenterModule/Model/UserInfo.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UserInfo.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/7/9.
6 | // Copyright © 2018年 Techwis. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import RealmSwift
11 |
12 | enum kUnicomStatus:NSInteger {
13 | case kUnicomStatus_open = 0 ,// 开通
14 | kUnicomStatus_unopen // 未开通
15 | }
16 |
17 | class UserInfo:Object,HandyJSON {
18 |
19 | @objc dynamic var userStatus:String? // 用户状态 1:银卡 2:金卡
20 | @objc dynamic var userNo:String?// 用户号
21 | @objc dynamic var phoneNo:String? // 手机号
22 | @objc dynamic var integral:String?// 余额
23 | @objc dynamic var currency:String?// T币额度
24 | @objc dynamic var unicomeStatus:String?// 0:开启联通专区 1:未开启联通专区
25 | @objc dynamic var realType:String?// 实名状态 0:未认证 1:认证
26 | @objc dynamic var userToken:String?
27 | @objc dynamic var firstBuyStatus:String?//0: 未人脸识别 1: 已做过人脸识别
28 | @objc dynamic var receiveStatus:String?// 0 未领取 1:已领取 礼包领取状态
29 | @objc dynamic var openCreditPayStatus:String?// 0: 未开通 1: 已开通 信用付
30 | @objc dynamic var creditUsableMoney:String?// 授信可用额度
31 | @objc dynamic var creditStatus:String?// 授信状态 0.失败。1成功。2,未处理 3,处理中 4.授信过期 5待人工审核
32 | @objc dynamic var forzenStatus:String?// 冻结状态 0:冻结 1:未冻结
33 | @objc dynamic var userName:String?// 用户姓名
34 | @objc dynamic var idNo:String?// 身份证号
35 | @objc dynamic var totalCreditAmount:String?// 总额度
36 | @objc dynamic var alreadyUseAmount:String?// 已使用额度
37 | @objc dynamic var forzenCreditAmount:String?// 冻结额度
38 | @objc dynamic var thisMonthRefundAmount:String?// 本月应还
39 | @objc dynamic var nextMonthRefundAmount:String?//下月应还
40 | @objc dynamic var waitPayOrderNums:String?//代付款订单数
41 | @objc dynamic var lastMonthLeftAmout:String?// 上月未还账单金额
42 | @objc dynamic var maxRefundAmount:String?//最大还款金额
43 |
44 |
45 | override class func primaryKey()->String?{
46 | return "userNo";
47 | }
48 |
49 | //重写 Object.ignoredProperties() 可以防止 Realm 存储数据模型的某个属性
50 | // override static func ignoredProperties() -> [String] {
51 | // return ["tempID"]
52 | // }
53 | }
54 |
55 | extension UserInfo{
56 | //MARK: 清空用户信息
57 | static func clearUserInfo(userNo:String?){
58 | let realm = RealmManager.instance
59 | realm.delete(UserInfo.instance!)
60 | }
61 |
62 | static var instance:UserInfo? = {
63 | let realm = RealmManager.instance
64 | return realm.objects(UserInfo.self).last
65 | }()
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/TQGO/Class/PersonalCenterModule/View/MyHeaderCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MyHeaderCell.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2019/10/21.
6 | // Copyright © 2019 Techwis. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class MyHeaderCell: UITableViewCell {
12 | let disposeBag = DisposeBag()
13 |
14 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
15 | super.init(style: style, reuseIdentifier: reuseIdentifier)
16 | contentView.backgroundColor = KCOLOR_Base.font_blue
17 | setupView()
18 | }
19 |
20 | required init?(coder: NSCoder) {
21 | fatalError("init(coder:) has not been implemented")
22 | }
23 |
24 | func setupView() {
25 | let iconImgV = UIImageView()
26 | iconImgV.image = UIImage(named: "icon_header")
27 | contentView.addSubview(iconImgV)
28 | iconImgV.snp.makeConstraints { (make) in
29 | make.left.equalToSuperview().offset(15)
30 | make.bottom.equalToSuperview().offset(-32)
31 | }
32 |
33 | let loginBtn = UIButton(type: UIButton.ButtonType.custom)
34 | loginBtn.isHidden = false
35 | loginBtn.setTitle("立即登录", for: UIControl.State.normal)
36 | loginBtn.setImage(kImage(name: "icon_arrow_right_white"), for: UIControl.State.normal)
37 | loginBtn.titleLabel?.font = kFont(size: 17)
38 | loginBtn.setTitleColor(.white, for: UIControl.State.normal)
39 | loginBtn.rx.tap.subscribe(onNext: {[weak self] (make) in
40 | self?.viewController()?.navigationController?.pushViewController(LoginVC(), animated: true)
41 | }).disposed(by: disposeBag)
42 |
43 | contentView.addSubview(loginBtn)
44 | loginBtn.snp.makeConstraints { (make) in
45 |
46 | make.left.equalTo(iconImgV.snp_rightMargin).offset(16)
47 | make.centerY.equalTo(iconImgV)
48 | }
49 | loginBtn.layoutButtonWithEdgeInsetsStyle(style: YXYButtonEdgeInsetsStyle.YXYButtonEdgeInsetsStyleRight, imageTitleSpace: 6)
50 |
51 | }
52 |
53 | override func setSelected(_ selected: Bool, animated: Bool) {
54 | super.setSelected(selected, animated: animated)
55 |
56 | // Configure the view for the selected state
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/TQGO/Class/PromotionModule/Controller/GoodsDetailVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GoodsDetailVC.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2019/1/15.
6 | // Copyright © 2019 Techwis. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | protocol GoodsDetailDelegate {
12 | func callback()
13 | }
14 |
15 | class GoodsDetailVC: UIViewController {
16 |
17 | var delegate:GoodsDetailDelegate?
18 |
19 |
20 | override func viewDidLoad() {
21 | super.viewDidLoad()
22 | view.backgroundColor = .white
23 | title = "商品详情"
24 | self.delegate?.callback()
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/TQGO/Class/PromotionModule/Controller/PromotionSubVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PromotionSubVC.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2019/3/22.
6 | // Copyright © 2019 Techwis. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 |
12 | let kPromotionSubCell_id = "kPromotionSubCell_id"
13 |
14 | class PromotionSubVC: UIViewController {
15 |
16 | var promotionModel:PromotionModel?
17 | var menuCode:String?
18 | var taskId :String?
19 | var vcCanScroll = false
20 |
21 | lazy var collectionView: UICollectionView = {
22 |
23 | var layout = UICollectionViewFlowLayout()
24 |
25 | var height:CGFloat = 213+34+8+12;
26 | if(kScreenWidth <= 320) {
27 | height = 213-28+40;
28 | }else if(kScreenWidth >= 414){
29 | height = 213+34+20+8;
30 | }
31 | layout.itemSize = CGSize(width: (kScreenWidth-15*3)/2.0, height: height)
32 | layout.minimumInteritemSpacing = 15
33 | layout.minimumLineSpacing = 0
34 | layout.sectionInset = UIEdgeInsets(top: 0, left: 15, bottom: 0, right: 15);
35 |
36 | let collectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: view.width, height: kScreenHeight - kSafeAreaTopHeight - kSafeAreaBottomHeight), collectionViewLayout: layout)
37 | collectionView.backgroundColor = .white
38 | collectionView.bounces = false;
39 | collectionView.delegate = self
40 | collectionView.dataSource = self
41 | collectionView.register(PromotionSubCell.self, forCellWithReuseIdentifier:kPromotionSubCell_id)
42 |
43 | return collectionView
44 | }()
45 |
46 | override func viewDidLoad() {
47 | super.viewDidLoad()
48 | view.backgroundColor = .white
49 | view.addSubview(collectionView)
50 | loadData()
51 | }
52 | /// 请求数据
53 | func loadData() {
54 | let params = ["userNo": "01645200948672000591",
55 | "area":"110000",
56 | "taskId":taskId ?? "a3e17811155f699c451b",
57 | "menuCode": menuCode!]
58 | NetworkManager.loadData(api: APIInterfacePromotion.queryPromoIndex(params:params ), completionClosure: { [weak self] (respone) -> (Void) in
59 |
60 | if respone.returnCode == KErrorCode.KErrorCode_SUCCESSE.rawValue{
61 | self!.promotionModel = respone.data as? PromotionModel
62 | self!.collectionView.reloadData()
63 | }else{
64 | self!.readDataFromLocal()
65 | }
66 | }) {[weak self] (fail) -> (Void) in
67 | self!.readDataFromLocal()
68 | }
69 | }
70 |
71 | // 读取本地数据
72 | func readDataFromLocal(){
73 | DispatchQueue.global().async {
74 | let tempArr = JSONDeserializer.deserializeModelArrayFrom(array: "goods\(self.menuCode!)".getLocalPlistData()) as! Array
75 | let tempModel = PromotionModel()
76 | tempModel.activityGoods = tempArr
77 | self.promotionModel = tempModel
78 | DispatchQueue.main.async {
79 | self.collectionView.reloadData()
80 | }
81 | }
82 | }
83 |
84 | }
85 |
86 | extension PromotionSubVC:UICollectionViewDelegate,UICollectionViewDataSource{
87 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
88 | return self.promotionModel?.activityGoods?.count ?? 0
89 | }
90 |
91 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
92 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: kPromotionSubCell_id, for: indexPath) as! PromotionSubCell
93 | let model = self.promotionModel?.activityGoods?[indexPath.row]
94 | cell.model = model
95 | return cell
96 | }
97 |
98 | func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
99 | navigationController?.pushViewController(GoodsDetailVC(), animated: true)
100 | }
101 | }
102 |
103 | extension PromotionSubVC{
104 | func scrollViewDidScroll(_ scrollView: UIScrollView) {
105 | if vcCanScroll == false {
106 | scrollView.contentOffset = CGPoint(x: 0, y: 0)
107 | }
108 | if scrollView.contentOffset.y <= 0 {
109 | vcCanScroll = false
110 | scrollView.contentOffset = CGPoint(x: 0, y: 0)
111 | //到顶通知父视图改变状态
112 | NotificationCenter.default.post(name:.kLeaveTop, object: nil)
113 | }
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/TQGO/Class/PromotionModule/Controller/PromotionVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PromotionVC.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/7/9.
6 | // Copyright © 2018年 Techwis. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import RealmSwift
11 | import MJRefresh
12 |
13 | private let kSlideViewH = (kScreenWidth * 135/375)
14 | private let kPageViewCell_id = "kPageViewCell_id"
15 | private let kADCell_id = "kADCell_id"
16 |
17 | class PromotionVC: UIViewController {
18 | var promotionModel:PromotionModel?
19 | var pageView:YXYPageContentView?
20 | var menuTitleView:YXYMenuTitleView?
21 | var canScroll = true
22 |
23 | lazy var tableView:BaseTableView = {
24 | let tableView = BaseTableView(frame: view.bounds, style: UITableView.Style.plain)
25 | tableView.backgroundColor = .white
26 | tableView.delegate = self
27 | tableView.dataSource = self
28 | tableView.bounces = true
29 | tableView.showsVerticalScrollIndicator = false
30 | tableView.register(ADCell.self, forCellReuseIdentifier: kADCell_id)
31 | tableView.register(UITableViewCell.self, forCellReuseIdentifier: kPageViewCell_id)
32 | view.addSubview(tableView)
33 | return tableView
34 | }()
35 |
36 | override func viewDidLoad() {
37 | super.viewDidLoad()
38 | view.backgroundColor = .white
39 | title = "促销"
40 |
41 | kNotife.addObserver(self, selector: #selector(changeScrollStatus), name: .kLeaveTop, object: nil)
42 | // navigationController?.navigationBar.isTranslucent = false
43 | // if #available(iOS 13.0, *) {
44 | // navigationController?.navigationBar.showsLargeContentViewer = false
45 | // } else {
46 | // // Fallback on earlier versions
47 | // }
48 | // tableView.mj_header?.ignoredScrollViewContentInsetTop = 164
49 | tableView.backgroundColor = .white
50 | // tableView.mj_header = MJRefreshNormalHeader(refreshingBlock: {
51 | // [unowned self] in
52 | // self.tableView.mj_header?.endRefreshing()
53 | // })
54 | loadData()
55 | }
56 |
57 | func loadData() {
58 | var params = ["area":"110000",
59 | "taskId": "",
60 | "menuCode": ""]
61 | if let userNo = UserInfo.instance?.userNo {
62 | params.updateValue(userNo, forKey: kUserNo)
63 | }
64 |
65 | NetworkManager.loadData(api: APIInterfacePromotion.queryPromoIndex(params:params), completionClosure: { [weak self] (respone) -> (Void) in
66 | if respone.returnCode == KErrorCode.KErrorCode_SUCCESSE.rawValue{
67 | if let model = PromotionModel.deserialize(from: respone.toJSONString(), designatedPath: "data") {
68 | self?.promotionModel = model
69 | self?.tableView.reloadData()
70 | }
71 | }else{
72 | self?.readDataFromLocal()
73 | }
74 | }) {[weak self] (fail) -> (Void) in
75 | self?.readDataFromLocal()
76 | }
77 | }
78 |
79 | /// 子线程读取本地数据 主线程刷新
80 | func readDataFromLocal(){
81 | let tempModel = PromotionModel()
82 | DispatchQueue.global().async {
83 | let tempArr = JSONDeserializer.deserializeModelArrayFrom(array: "menu".getLocalPlistData()) as! Array
84 | tempModel.menus = tempArr
85 | let tempArrBanner = JSONDeserializer.deserializeModelArrayFrom(array: "homeBanner".getLocalPlistData()) as! Array
86 | tempModel.banners = tempArrBanner
87 | self.promotionModel = tempModel
88 | DispatchQueue.main.async {
89 | self.tableView.reloadData()
90 | }
91 | }
92 | }
93 |
94 | deinit {
95 | NotificationCenter.default.removeObserver(self)
96 | }
97 | override func didReceiveMemoryWarning() {
98 | super.didReceiveMemoryWarning()
99 | // Dispose of any resources that can be recreated.
100 | }
101 |
102 | }
103 |
104 | extension PromotionVC:UITableViewDelegate,UITableViewDataSource{
105 |
106 | func numberOfSections(in tableView: UITableView) -> Int {
107 | return 2
108 | }
109 |
110 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
111 | if section == 0{
112 | return 1
113 | }else{
114 | return 1
115 | }
116 |
117 | }
118 |
119 | func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
120 | if section == 0{
121 | return 0
122 | }else{
123 | return 40
124 | }
125 | }
126 |
127 | func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
128 | if indexPath.section == 0 {
129 | return kSlideViewH
130 | }else{
131 | return kScreenHeight
132 | }
133 | }
134 |
135 | func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
136 | if section == 0 {
137 | return nil
138 | }
139 | var titleArr = [String]()
140 | promotionModel?.menus?.forEach({ (menu) in
141 | if let title = menu.name{
142 | titleArr.append(title)
143 | }
144 | })
145 | menuTitleView = YXYMenuTitleView(frame: CGRect(x: 0, y: 0, width: kScreenWidth, height: 40), titleArr: titleArr)
146 | menuTitleView!.menuMoveDelegate = self
147 | menuTitleView!.indicatorType = .YXYIndicatorTypeCustom
148 | menuTitleView!.indicatorExtension = 30;
149 |
150 | return menuTitleView
151 | }
152 |
153 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
154 | if indexPath.section == 0 {
155 | let adCell = tableView.dequeueReusableCell(withIdentifier: kADCell_id, for: indexPath) as! ADCell
156 | if self.promotionModel?.banners?.isEmpty == false{
157 | adCell.setSlideArr(banner: self.promotionModel?.banners)
158 | }
159 |
160 | return adCell
161 | }else{
162 | let contentCell = tableView.dequeueReusableCell(withIdentifier:kPageViewCell_id , for: indexPath)
163 | var subVCArr = [PromotionSubVC]()
164 | _ = promotionModel?.menus?.map({ (model) in
165 | let vc = PromotionSubVC()
166 | vc.title = model.code
167 | vc.menuCode = model.code
168 | vc.taskId = promotionModel?.promos?.first?.taskId
169 | subVCArr.append(vc)
170 | })
171 | pageView?.removeFromSuperview()
172 | pageView = YXYPageContentView(frame: CGRect(x: 0, y: 0, width: kScreenWidth, height: kScreenHeight), subVCArr:subVCArr, parentVC: self)
173 | contentCell.contentView.addSubview(pageView!)
174 | pageView!.pageContenViewDelegate = self
175 | return contentCell
176 | }
177 | }
178 | }
179 |
180 | extension PromotionVC:YXYMenuMoveProtocol,YXYContenViewProtocol{
181 | func pageContenViewDidScroll(fromIndex: NSInteger, toIndex: NSInteger) {
182 | menuTitleView!.selectIndex = toIndex
183 | }
184 |
185 | func menuMoveProtocol(formIndex: NSInteger, toIndex: NSInteger) {
186 | pageView!.contentViewCurrentIndex = toIndex
187 | }
188 | }
189 |
190 |
191 | extension PromotionVC{
192 | @objc func changeScrollStatus(){
193 | canScroll = true;
194 | _ = pageView?.subVCArr.map({ (vc) in
195 | vc.vcCanScroll = false
196 | })
197 | }
198 |
199 | func scrollViewDidScroll(_ scrollView: UIScrollView) {
200 |
201 | let bottomCellOffset = tableView.rect(forSection: 1).origin.y
202 | if (scrollView.contentOffset.y) >= bottomCellOffset {
203 | scrollView.contentOffset = CGPoint(x: 0, y: bottomCellOffset)
204 | if (canScroll) {
205 | canScroll = false;
206 | _ = pageView?.subVCArr.map({ (vc) in
207 | vc.vcCanScroll = true
208 | })
209 | }
210 | }else{
211 | if (!canScroll) {
212 | //子视图没到顶部
213 | scrollView.contentOffset = CGPoint(x: 0, y: bottomCellOffset)
214 | }
215 | }
216 | }
217 | }
218 |
--------------------------------------------------------------------------------
/TQGO/Class/PromotionModule/Model/MenuModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MenuModel.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2019/3/20.
6 | // Copyright © 2019 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | class MenuModel: HandyJSON {
11 | var code:String?
12 | var name:String?
13 | required init() {}
14 | }
15 |
--------------------------------------------------------------------------------
/TQGO/Class/PromotionModule/Model/PromosModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PromosModel.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2019/3/20.
6 | // Copyright © 2019 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | class PromosModel: HandyJSON {
11 | var taskId:String?
12 | var taskTitleName:String?
13 | var taskTagName:String?
14 | required init() {}
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/TQGO/Class/PromotionModule/Model/PromotionModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PromotionModel.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2019/3/20.
6 | // Copyright © 2019 Techwis. All rights reserved.
7 | //
8 |
9 | //import Foundation
10 |
11 | class PromotionModel: HandyJSON {
12 | var promos:Array?
13 | var banners:Array?
14 | var menus:Array?
15 | var activityGoods:Array?
16 | required init() {}
17 |
18 | func mapping(mapper: HelpingMapper) {
19 | // mapper.specify(property: &promos, name: "id")
20 | // mapper <<< self.promos <-- "id"
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/TQGO/Class/PromotionModule/View/PromotionSubCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PromotionSubCell.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2019/3/22.
6 | // Copyright © 2019 Techwis. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class PromotionSubCell: UICollectionViewCell {
12 |
13 | var icon:UIImageView!
14 | var flagTwoLabel:UILabel!
15 | var goodsNameLabel:UILabel!
16 | var flagOneLabel:UILabel!
17 | var specialPriceLabel:UILabel!
18 | var buyGoodsBtn:UIButton!
19 | var officialPriceLabel:UILabel!
20 | var salesCountLabel:UILabel!
21 |
22 | var model:GoodsModel?{
23 | didSet{
24 |
25 | icon.kf.setImage(with: URL(string: (model?.imgUrl ?? "")), placeholder: UIImage.init(named: "icon_goods_default"), options: nil, progressBlock: nil) { (result) in
26 |
27 | }
28 | salesCountLabel.text = "月销" + (model?.goodsSell ?? "") + "件"
29 | goodsNameLabel.text = model?.goodsName ?? ""
30 | var tagArr = [String]()
31 | if (model?.tags?.isEmpty == false) {
32 | flagOneLabel.isHidden = false;
33 | flagTwoLabel.isHidden = false;
34 | tagArr = (model?.tags?.components(separatedBy:",")) ?? []
35 | if (tagArr.count > 1) {
36 | self.flagOneLabel.text = " " + (tagArr.last ?? "") + " "
37 | self.flagTwoLabel.text = " " + (tagArr.first ?? "") + " "
38 | }else if (tagArr.count > 0) {
39 | self.flagOneLabel.text = " " + (tagArr.first ?? "") + " "
40 | }
41 | }else{
42 | flagOneLabel.isHidden = true;
43 | flagTwoLabel.isHidden = true;
44 | }
45 |
46 | let attStr = NSMutableAttributedString(string: ("¥" + (model?.payPrice ?? "")))
47 | attStr.addAttributes([NSAttributedString.Key.font : UIFont.systemFont(ofSize: 10)], range: NSRange(location: 0, length: 1))
48 | attStr.addAttributes([NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)], range: NSMakeRange(1, attStr.length-1))
49 |
50 | specialPriceLabel.attributedText = attStr;
51 | let newPrice = NSMutableAttributedString(string: ("¥" + (model?.payPrice ?? "")))
52 | newPrice.addAttributes([.font : UIFont.systemFont(ofSize: 10)], range: NSMakeRange(0, newPrice.length))
53 | newPrice.addAttributes([.strikethroughStyle:2], range: NSMakeRange(0, newPrice.length))
54 | officialPriceLabel.attributedText = newPrice;
55 | }
56 | }
57 |
58 | override init(frame: CGRect) {
59 | super.init(frame:frame)
60 | setupView()
61 | }
62 |
63 | required init?(coder aDecoder: NSCoder) {
64 | fatalError("init(coder:) has not been implemented")
65 | }
66 |
67 | func setupView() -> Void {
68 | // 商品图片
69 | icon = UIImageView();
70 | self.contentView.addSubview(icon)
71 | icon.snp.makeConstraints { (make) in
72 | make.left.right.equalTo(self.contentView)
73 | make.top.equalTo(9)
74 | make.height.equalTo(icon.snp.width)
75 | }
76 |
77 | // 商品名
78 | goodsNameLabel = UILabel()
79 | goodsNameLabel.textColor = KCOLOR_Base.font_black
80 | goodsNameLabel.font = UIFont.systemFont(ofSize: 14)
81 | goodsNameLabel.lineBreakMode = .byTruncatingTail
82 | self.contentView.addSubview(goodsNameLabel)
83 | goodsNameLabel.snp.makeConstraints { (make) in
84 | make.left.equalToSuperview().offset(5)
85 | make.right.equalToSuperview().offset(-5)
86 | make.top.equalTo(icon.snp.bottom).offset(9)
87 | }
88 |
89 | //特价
90 | specialPriceLabel = UILabel()
91 | specialPriceLabel.textColor = KCOLOR_Base.font_red;
92 | self.contentView.addSubview(specialPriceLabel);
93 | specialPriceLabel.snp.makeConstraints { (make) in
94 | make.left.equalTo(goodsNameLabel);
95 | make.top.equalTo(goodsNameLabel.snp.bottom).offset(15-2);
96 | }
97 |
98 | // 标签一
99 | flagOneLabel = UILabel()
100 | flagOneLabel.layer.cornerRadius = 8
101 | flagOneLabel.layer.masksToBounds = true
102 | flagOneLabel.font = UIFont.systemFont(ofSize: 10)
103 | flagOneLabel.textColor = KCOLOR_Base.font_blue
104 | flagOneLabel.backgroundColor = KRGBHEXCOLOR(rgbValue: 0xE8F3FF)
105 | self.contentView.addSubview(flagOneLabel)
106 | flagOneLabel.snp.makeConstraints { (make) in
107 | make.right.equalTo(goodsNameLabel);
108 | make.centerY.equalTo(specialPriceLabel)
109 | make.height.equalTo(18)
110 | if (kScreenWidth <= 375) {
111 | make.width.lessThanOrEqualTo(70)
112 | }else{
113 | make.width.lessThanOrEqualTo(80)
114 | }
115 | }
116 |
117 | // // 标签二
118 | flagTwoLabel = UILabel()
119 | flagTwoLabel.layer.cornerRadius = 8
120 | flagTwoLabel.layer.masksToBounds = true
121 | flagTwoLabel.font = UIFont.systemFont(ofSize: 10)
122 | flagTwoLabel.textColor = KRGBHEXCOLOR(rgbValue:0xff6c6c)
123 | flagTwoLabel.backgroundColor = kRGBCOLOR(r: 253, g: 240, b: 240)
124 | self.contentView.addSubview(flagTwoLabel)
125 | flagTwoLabel.snp.makeConstraints { (make) in
126 | make.right.equalTo(flagOneLabel.snp.left).offset(-5)
127 | make.top.equalTo(flagOneLabel)
128 | make.height.equalTo(flagOneLabel)
129 | if (kScreenWidth <= 375) {
130 | make.width.lessThanOrEqualTo(70)
131 | }else{
132 | make.width.lessThanOrEqualTo(80)
133 | }
134 | }
135 |
136 | // 官方价格
137 | officialPriceLabel = UILabel()
138 | officialPriceLabel.font = UIFont.systemFont(ofSize: 10)
139 | officialPriceLabel.textColor = KCOLOR_Base.font_textField;
140 | officialPriceLabel.textAlignment = .center
141 | self.contentView.addSubview(officialPriceLabel)
142 | officialPriceLabel.snp.makeConstraints { (make) in
143 | make.top.equalTo(specialPriceLabel.snp.bottom).offset(8-2)
144 | make.left.equalTo(specialPriceLabel)
145 | }
146 |
147 | // 月销量
148 | salesCountLabel = UILabel()
149 | salesCountLabel.textColor = KCOLOR_Base.font_textField;
150 | salesCountLabel.font = UIFont.systemFont(ofSize: 10)
151 | self.contentView.addSubview(salesCountLabel)
152 | salesCountLabel.snp.makeConstraints { (make) in
153 | make.top.equalTo(officialPriceLabel);
154 | make.right.equalTo(goodsNameLabel);
155 | }
156 | }
157 |
158 | }
159 |
--------------------------------------------------------------------------------
/TQGO/Class/ShopCartModule/Controller/ShopCartVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ShopCartVC.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/11/8.
6 | // Copyright © 2018年 Techwis. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ShopCartVC: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 | view.backgroundColor = .white
16 | title = "购物车"
17 | // Do any additional setup after loading the view.
18 | }
19 |
20 |
21 | /*
22 | // MARK: - Navigation
23 |
24 | // In a storyboard-based application, you will often want to do a little preparation before navigation
25 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
26 | // Get the new view controller using segue.destination.
27 | // Pass the selected object to the new view controller.
28 | }
29 | */
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/TQGO/Class/UnicomAreaModule/Controller/UnicomAreaVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UnicomAreaVC.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/7/9.
6 | // Copyright © 2018年 Techwis. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import MJRefresh
11 |
12 | private let kUnicomADCell_id = "kUnicomADCell_id"
13 | private let kUnicomMenuCell_id = "kUnicomMenuCell_id"
14 | private let kHotGoodsCell_id = "kHotGoodsCell_id"
15 | private let kDiscountAreaCell_id = "kDiscountAreaCell_id"
16 |
17 | class UnicomAreaVC: UIViewController,UITextFieldDelegate,GoodsDetailDelegate{
18 |
19 | var navbarView:UIView?
20 | var searchTF:UITextField?
21 | var unicomIndexModel:UnicomIndexModel?
22 |
23 | lazy var tableView : UITableView = {
24 | let tableView = UITableView()
25 | tableView.separatorStyle = .none
26 | tableView.dataSource = self
27 | tableView.delegate = self
28 | tableView.register(ADCell.self, forCellReuseIdentifier: kUnicomADCell_id)
29 | tableView.register(UnicomMenuCell.self, forCellReuseIdentifier: kUnicomMenuCell_id)
30 | tableView.register(HotGoodsCell.self, forCellReuseIdentifier: kHotGoodsCell_id)
31 | tableView.register(DiscountAreaCell.self, forCellReuseIdentifier: kDiscountAreaCell_id)
32 | view.addSubview(tableView)
33 | tableView.snp.makeConstraints({ make in
34 | make.top.equalTo(navbarView!.snp.bottom)
35 | make.left.right.bottom.equalToSuperview()
36 | })
37 | return tableView
38 | }()
39 |
40 | override func viewDidLoad() {
41 | super.viewDidLoad()
42 | title = "联通专区"
43 | view.backgroundColor = .white
44 | addSearchNav()
45 | tableView.backgroundColor = .white
46 | tableView.mj_header = MJRefreshNormalHeader(refreshingBlock: {
47 | self.loadData()
48 | })
49 | loadData()
50 | }
51 |
52 | func loadData() -> Void {
53 |
54 | let dict = [kUserNo:"YXY" , "area": "110000"]
55 | NetworkManager.loadData(api: APIInterfaceUnicom.queryUnicomZoneIndex(params: dict), completionClosure: {[weak self] (respone) -> (Void) in
56 | self!.tableView.mj_header?.endRefreshing()
57 | if respone.returnCode == KErrorCode.KErrorCode_SUCCESSE.rawValue{
58 | self!.unicomIndexModel = respone.data as? UnicomIndexModel
59 | self!.tableView.reloadData()
60 |
61 | }else{
62 | self!.readDataFromLocal()
63 | }
64 | }) {[weak self] (fail) -> (Void) in
65 | self!.tableView.mj_header?.endRefreshing()
66 | self!.readDataFromLocal()
67 | }
68 | }
69 |
70 | /// 读取本地数据
71 | func readDataFromLocal(){
72 | let homeDiscountZone = Bundle.main.path(forResource: "UnicomAreaDiscountZone", ofType: "plist")
73 | let menuArrDiscountZone = NSArray(contentsOfFile: homeDiscountZone!)
74 | let tempArrDiscountZone = JSONDeserializer.deserializeModelArrayFrom(array: menuArrDiscountZone) as! Array
75 | let tempModel = UnicomIndexModel()
76 | tempModel.discountZone = tempArrDiscountZone
77 |
78 | let homeRecommGoods = Bundle.main.path(forResource: "UnicomAreaRecommGoods", ofType: "plist")
79 | let menuArrRecommGoods = NSArray(contentsOfFile: homeRecommGoods!)
80 | let tempArrRecommGoods = JSONDeserializer.deserializeModelArrayFrom(array: menuArrRecommGoods) as! Array
81 | tempModel.recommGoods = tempArrRecommGoods
82 |
83 | let homeBanner = Bundle.main.path(forResource: "UnicomBanner", ofType: "plist")
84 | let menuArrBanner = NSArray(contentsOfFile: homeBanner!)
85 | let tempArrBanner = JSONDeserializer.deserializeModelArrayFrom(array: menuArrBanner) as! Array
86 | tempModel.banners = tempArrBanner
87 | self.unicomIndexModel = tempModel
88 | self.tableView.reloadData()
89 | }
90 |
91 | override func viewWillAppear(_ animated: Bool) {
92 | super.viewWillAppear(animated)
93 | navigationController?.setNavigationBarHidden(true, animated: false)
94 | }
95 | override func viewWillDisappear(_ animated: Bool) {
96 | super.viewWillDisappear(animated)
97 | navigationController?.setNavigationBarHidden(false, animated: false)
98 | }
99 |
100 | override func didReceiveMemoryWarning() {
101 | super.didReceiveMemoryWarning()
102 | // Dispose of any resources that can be recreated.
103 | }
104 | func addSearchNav() -> Void {
105 |
106 | var y = 20.0;
107 | if kSafeAreaBottomHeight != 0{
108 | y = 44.0;
109 | }
110 | navbarView = UIView.init(frame: CGRect(x: 0.0, y: y, width:Double(CGFloat(kScreenWidth)), height: 44.0))
111 | navbarView!.backgroundColor = .white
112 |
113 | // 搜索框
114 | let radiusValue:CGFloat = 15;
115 | searchTF = UITextField();
116 | searchTF!.delegate = self ;
117 | searchTF!.font = UIFont.systemFont(ofSize: 14);
118 | searchTF!.textColor = KCOLOR_Base.font_textField;
119 | searchTF!.backgroundColor = KRGBHEXCOLOR(rgbValue:0xf3f3f3);
120 | searchTF!.layer.cornerRadius = radiusValue;
121 | searchTF!.placeholder = "商品搜索";
122 | let bgV:UIView = UIView(frame: CGRect(x: 0, y: 0, width: 36, height: 30))
123 | bgV.backgroundColor = KRGBHEXCOLOR(rgbValue:0xf3f3f3);
124 | bgV.layer.cornerRadius = radiusValue;
125 | bgV.layer.masksToBounds = true;
126 |
127 | let imageV = UIImageView(image: UIImage.init(imageLiteralResourceName:"icon_search" ))
128 | bgV.addSubview(imageV)
129 | imageV.snp.makeConstraints { (make) in
130 | make.centerX.equalTo(bgV);
131 | make.centerY.equalTo(bgV);
132 | }
133 |
134 | searchTF!.leftView = bgV;
135 | searchTF!.leftViewMode = .always;
136 | navbarView!.addSubview(searchTF!)
137 | searchTF!.snp.makeConstraints { (make) in
138 | make.left.equalTo(15);
139 | make.centerY.equalTo(navbarView!);
140 | make.right.equalTo(-15);
141 | make.height.equalTo(30);
142 | }
143 | view.addSubview(navbarView!);
144 | }
145 | }
146 |
147 | extension UnicomAreaVC:UITableViewDelegate,UITableViewDataSource{
148 |
149 | func numberOfSections(in tableView: UITableView) -> Int {
150 | return 4
151 | }
152 |
153 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
154 | if section == 0 || section == 1 || section == 2 {
155 | return 1
156 | }else{
157 | return unicomIndexModel?.discountZone?.count ?? 0
158 | }
159 | }
160 |
161 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
162 | if indexPath.section == 0 {
163 | let adCell = tableView.dequeueReusableCell(withIdentifier: kUnicomADCell_id, for: indexPath) as! ADCell
164 | let count = self.unicomIndexModel?.banners?.count
165 | if count ?? 0 > 0 {
166 | adCell.setSlideArr(banner: (self.unicomIndexModel?.banners!)!)
167 | }
168 | return adCell
169 | }else if indexPath.section == 1 {
170 | let menuCell = tableView.dequeueReusableCell(withIdentifier: kUnicomMenuCell_id, for: indexPath)
171 | return menuCell
172 | }else if indexPath.section == 2 {
173 | let hotcell = tableView.dequeueReusableCell(withIdentifier: kHotGoodsCell_id, for: indexPath) as? HotGoodsCell
174 | if (unicomIndexModel?.recommGoods?.count) != nil{
175 | hotcell?.setDataArr(dataArr:(unicomIndexModel?.recommGoods)!)
176 | }
177 | return hotcell!
178 | }else{
179 | let discountCell = tableView.dequeueReusableCell(withIdentifier: kDiscountAreaCell_id, for: indexPath) as? DiscountAreaCell
180 | if (unicomIndexModel?.discountZone?.count) != nil{
181 | discountCell?.setModel(goodsModel: (unicomIndexModel?.discountZone![indexPath.row])!)
182 | }
183 | return discountCell!
184 | }
185 | }
186 |
187 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
188 | tableView.deselectRow(at: indexPath, animated: true)
189 | let goodsDetailVC = GoodsDetailVC()
190 | goodsDetailVC.delegate = self
191 | self.navigationController?.pushViewController(goodsDetailVC, animated: true)
192 | }
193 |
194 | func callback() {
195 | DLog("++++++++++++++++++____________+++++++++++++++++")
196 | }
197 |
198 | }
199 |
--------------------------------------------------------------------------------
/TQGO/Class/UnicomAreaModule/Model/GoodsModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GoodsModel.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/11/28.
6 | // Copyright © 2018 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | enum KGoodsType:String{
12 | case KGoodsType_GiftBag = "0"// 打包商品 礼包商品
13 | case KGoodsType_Virtual = "1"// 虚拟商品
14 | case KGoodsType_Entity = "2"// 实物商品
15 | case KGoodsType_3C = "3"// 3商品
16 | }
17 |
18 | enum KHideStatus:String{
19 | case KHideStatus_hide = "0"// 隐藏
20 | case KHideStatus_show = "1"// 显示
21 | }
22 |
23 |
24 | enum kShopcartstatus:String{
25 | case kShopcartstatus_normal = "0"// 0 有货
26 | case kShopcartstatus_wait = "1"// 1 补货中
27 | case kShopcartstatus_notEnough = "2"// 2 库存不足
28 | case kShopcartstatus_invalid = "3"// 已下架
29 | }
30 |
31 |
32 | class GoodsModel:HandyJSON{
33 | var goodsCode : String?
34 | var goodsName : String?
35 | var goodsType : String?
36 | var payPrice : String?
37 | var goodsNums : String?
38 | var goodsSell : String?
39 | var thumbnailUrl : String?
40 | var indexUrl : String?
41 | var hideStatus : String?
42 | var officialPrice : String?
43 | var imgUrl : String?
44 | var tags : String?
45 | var price : String?
46 | var tag : String?
47 | var goodsArea : String?
48 | var homeTitle : String?
49 | var homeContent : String?
50 | var cityStr : String?
51 | var menuCode : String?
52 | var bigPictureUrl : String?
53 | var goodsClassifyCode : String?
54 | var alreadySpec : String?
55 | var count : String?
56 | var goodsImgUrl : String?
57 | var taskId : String?
58 | var stock : String?
59 | var status : String?
60 | var isSelected : String?
61 | var token : String?
62 | var amount : String?
63 | var goodsImg : String?
64 | var unicomZoneType : String?
65 |
66 | required init() {}
67 | }
68 |
--------------------------------------------------------------------------------
/TQGO/Class/UnicomAreaModule/Model/SlideShowModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SlideShowModel.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/11/28.
6 | // Copyright © 2018 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | //import HandyJSON
11 |
12 | class SlideShowModel: HandyJSON {
13 | var imgUrl:String? // 图片路径
14 | var contentTitle:String?// 内容标题
15 | var descriptionInfo:String?// 描述
16 | var linkUrl:String?
17 | var showType:String?// 展示类型
18 | var endTime:String?// 结束时间
19 | var beginTime:String?// 开始时间
20 | var state:String?// 状态 0:下线 1上线
21 | var urlType:String?// 链接类型 1:内链接 2:外链接
22 | var bannerName:String?//标题
23 | var openType:String?// 1: APP内(各功能内跳转) 2: 外链(H5,其他外部链接)
24 | var openUrl:String?// 打开链接
25 | required init() {}
26 | }
27 |
--------------------------------------------------------------------------------
/TQGO/Class/UnicomAreaModule/Model/UnicomIndexModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UnicomIndexModel.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/11/28.
6 | // Copyright © 2018 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | //import HandyJSON
11 |
12 |
13 |
14 | class UnicomIndexModel: HandyJSON {
15 | var banners:Array?
16 | var recommGoods:Array?
17 | var discountZone:Array?
18 | required init() {}
19 | }
20 |
--------------------------------------------------------------------------------
/TQGO/Class/UnicomAreaModule/View/ADCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ADCell.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/11/12.
6 | // Copyright © 2018年 Techwis. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ADCell: UITableViewCell {
12 | var cycleScrollView:YXYBanner?
13 |
14 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
15 | super.init(style: style, reuseIdentifier: reuseIdentifier)
16 | self.setupView()
17 | }
18 |
19 | func setupView() -> Void {
20 | cycleScrollView = YXYBanner()
21 | contentView.addSubview(cycleScrollView!)
22 | cycleScrollView?.placeholderImage = UIImage(named: "icon_home_banner_default")
23 | cycleScrollView!.snp.makeConstraints { (make) in
24 | make.size.equalTo(CGSize(width: kScreenWidth, height: kScreenWidth*150/375))
25 | make.edges.equalToSuperview()
26 | }
27 | }
28 |
29 | required init?(coder aDecoder: NSCoder) {
30 | fatalError("init(coder:) has not been implemented")
31 | }
32 |
33 | override func setSelected(_ selected: Bool, animated: Bool) {
34 | super.setSelected(selected, animated: animated)
35 |
36 | // Configure the view for the selected state
37 | }
38 | //
39 | func setSlideArr(banner:[SlideShowModel]?) -> Void {
40 | var urlsArr : [String] = []
41 | if banner?.count != 0{
42 | for model in banner! {
43 | if model.imgUrl?.isEmpty == false{
44 | urlsArr.append(model.imgUrl!)
45 | }
46 | }
47 | }
48 |
49 | self.cycleScrollView!.imageURLStringsGroup = urlsArr
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/TQGO/Class/UnicomAreaModule/View/DiscountAreaCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DiscountAreaCell.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/11/30.
6 | // Copyright © 2018 Techwis. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class DiscountAreaCell: UITableViewCell {
12 | var iconImgV :UIImageView?
13 | var goodsNameLabel : UILabel?
14 | var goodsDescLabel :UILabel?
15 | var specialPriceLabel : UILabel?
16 | var counLabel : UILabel?
17 |
18 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
19 | super.init(style: style, reuseIdentifier: reuseIdentifier)
20 | setupView()
21 | }
22 |
23 | required init?(coder aDecoder: NSCoder) {
24 | fatalError("init(coder:) has not been implemented")
25 | }
26 |
27 | func setupView() -> Void {
28 | iconImgV = UIImageView()
29 | contentView.addSubview(iconImgV!)
30 | iconImgV?.snp.makeConstraints { (make) in
31 | make.top.equalToSuperview().offset(16)
32 | make.left.equalToSuperview().offset(15)
33 | make.bottom.equalToSuperview().offset(-16)
34 | make.size.equalTo(CGSize(width: 130, height: 104))
35 | }
36 |
37 | goodsNameLabel = UILabel()
38 | goodsNameLabel?.textColor = KCOLOR_Base.font_black
39 | goodsNameLabel?.font = .systemFont(ofSize: 14)
40 | contentView.addSubview(goodsNameLabel!)
41 | goodsNameLabel?.snp.makeConstraints({ (make) in
42 | make.top.equalTo(iconImgV!).offset(10)
43 | make.left.equalTo(iconImgV!.snp.right).offset(15)
44 | make.right.equalToSuperview().offset(-21)
45 | })
46 |
47 | goodsDescLabel = UILabel()
48 | goodsDescLabel?.textColor = KCOLOR_Base.font_gray
49 | goodsDescLabel?.font = .systemFont(ofSize: 12)
50 | contentView.addSubview(goodsDescLabel!)
51 | goodsDescLabel?.snp.makeConstraints({ (make) in
52 | make.top.equalTo(goodsNameLabel!.snp.bottom).offset(8)
53 | make.left.equalTo(goodsNameLabel!)
54 | make.right.equalTo(goodsNameLabel!)
55 | })
56 |
57 | counLabel = UILabel()
58 | counLabel?.textColor = KCOLOR_Base.font_gray
59 | counLabel?.font = .systemFont(ofSize: 10)
60 | contentView.addSubview(counLabel!)
61 | counLabel?.snp.makeConstraints({ (make) in
62 | make.top.equalTo(goodsDescLabel!.snp.bottom).offset(16)
63 | make.left.equalTo(goodsDescLabel!)
64 | })
65 |
66 | specialPriceLabel = UILabel()
67 | specialPriceLabel?.textColor = KCOLOR_Base.font_red
68 | specialPriceLabel?.font = .systemFont(ofSize: 10)
69 | contentView.addSubview(specialPriceLabel!)
70 | specialPriceLabel?.snp.makeConstraints({ (make) in
71 | make.top.equalTo(counLabel!.snp.bottom).offset(8)
72 | make.left.equalTo(counLabel!)
73 | })
74 |
75 | let view = UIView()
76 | view.backgroundColor = KCOLOR_Base.line
77 | contentView.addSubview(view)
78 | view.snp.makeConstraints { (make) in
79 | make.right.equalToSuperview().offset(-15)
80 | make.left.equalToSuperview().offset(15)
81 | make.bottom.equalToSuperview()
82 | make.height.equalTo(0.5)
83 | }
84 |
85 |
86 | }
87 |
88 | func setModel(goodsModel:GoodsModel) -> Void {
89 | iconImgV?.kf.setImage(with: URL(string: goodsModel.imgUrl!), placeholder: UIImage(named: "icon_goods_default"), options: nil, progressBlock: nil, completionHandler: { (result) in
90 |
91 | })
92 | goodsNameLabel?.text = goodsModel.goodsName
93 | goodsDescLabel?.text = goodsModel.tag
94 | specialPriceLabel?.text = goodsModel.payPrice
95 | counLabel?.text = goodsModel.goodsSell
96 | }
97 |
98 |
99 |
100 | override func awakeFromNib() {
101 | super.awakeFromNib()
102 | // Initialization code
103 | }
104 |
105 | override func setSelected(_ selected: Bool, animated: Bool) {
106 | super.setSelected(selected, animated: animated)
107 |
108 | // Configure the view for the selected state
109 | }
110 |
111 | }
112 |
--------------------------------------------------------------------------------
/TQGO/Class/UnicomAreaModule/View/HotCollectionViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HotCollectionViewCell.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/11/20.
6 | // Copyright © 2018 Techwis. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class HotCollectionViewCell: UICollectionViewCell {
12 | var goodsNameLabel:UILabel?
13 | var goodsDescLabel:UILabel?
14 | var goodsImg:UIImageView?
15 |
16 | override init(frame: CGRect) {
17 | super.init(frame: frame)
18 | setupView()
19 | }
20 |
21 | required init?(coder aDecoder: NSCoder) {
22 | fatalError("init(coder:) has not been implemented")
23 | }
24 |
25 | func setupView() -> Void {
26 | goodsImg = UIImageView()
27 | contentView.addSubview(goodsImg!)
28 | goodsImg?.snp.makeConstraints { (make) in
29 | make.top.equalToSuperview().offset(8)
30 | make.right.equalToSuperview().offset(-15)
31 | make.bottom.equalToSuperview().offset(-8)
32 | make.size.equalTo(CGSize(width: 56, height: 56))
33 | }
34 |
35 | goodsNameLabel = UILabel()
36 | goodsNameLabel?.textColor = KCOLOR_Base.font_black
37 | goodsNameLabel?.font = .systemFont(ofSize: 14)
38 | contentView.addSubview(goodsNameLabel!)
39 | goodsNameLabel?.snp.makeConstraints({ (make) in
40 | make.top.equalToSuperview().offset(11)
41 | make.left.equalToSuperview().offset(15)
42 | make.right.equalTo(goodsImg!.snp.left)
43 | })
44 |
45 | goodsDescLabel = UILabel()
46 | goodsDescLabel?.textColor = KCOLOR_Base.font_gray
47 | goodsDescLabel?.font = .systemFont(ofSize: 12)
48 | contentView.addSubview(goodsDescLabel!)
49 | goodsDescLabel?.snp.makeConstraints({ (make) in
50 | make.top.equalTo(goodsNameLabel!.snp.bottom).offset(8)
51 | make.left.equalTo(goodsNameLabel!)
52 | make.right.equalTo(goodsImg!.snp.left)
53 | })
54 | }
55 |
56 | func setModel(goodsModel:GoodsModel) -> Void {
57 | goodsImg?.kf.setImage(with: URL(string: goodsModel.imgUrl!), placeholder: UIImage(named: "icon_goods_default"), options: nil, progressBlock: nil, completionHandler: { (result) in
58 |
59 | })
60 | goodsNameLabel?.text = goodsModel.goodsName
61 | goodsDescLabel?.text = goodsModel.tag
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/TQGO/Class/UnicomAreaModule/View/HotGoodsCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HotGoodsCell.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/11/19.
6 | // Copyright © 2018 Techwis. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | let kHotCollectionViewCell_id = "kHotCollectionViewCell_id"
12 |
13 | class HotGoodsCell: UITableViewCell {
14 | var dataArr:Array?
15 |
16 | lazy var collectionView:UICollectionView = {
17 |
18 | let layout = UICollectionViewFlowLayout()
19 | layout.itemSize = CGSize(width: kScreenWidth/2, height: 80)
20 | // layout.headerReferenceSize = CGSize(width: kScreenWidth, height: 48+8)
21 | layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
22 | layout.minimumLineSpacing = 0;
23 | layout.minimumInteritemSpacing = 0;
24 | let collectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: kScreenWidth, height: 80*2), collectionViewLayout: layout)
25 | collectionView.register(HotCollectionViewCell.self, forCellWithReuseIdentifier: kHotCollectionViewCell_id)
26 | collectionView.backgroundColor = UIColor.white
27 |
28 | return collectionView
29 | }()
30 |
31 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
32 | super.init(style:style , reuseIdentifier: reuseIdentifier)
33 | self.setupView()
34 | }
35 |
36 | required init?(coder aDecoder: NSCoder) {
37 | fatalError("init(coder:) has not been implemented")
38 | }
39 |
40 | func setupView() -> Void {
41 |
42 | let containerView = UIView()
43 | containerView.backgroundColor = .white
44 | contentView.addSubview(containerView)
45 | containerView.snp.makeConstraints { (make) in
46 | make.edges.equalToSuperview()
47 | make.height.equalTo(80*2)
48 | }
49 | containerView.addSubview(collectionView)
50 | collectionView.delegate = self
51 | collectionView.dataSource = self
52 | }
53 |
54 | override func setSelected(_ selected: Bool, animated: Bool) {
55 | super.setSelected(selected, animated: animated)
56 |
57 | // Configure the view for the selected state
58 | }
59 |
60 | }
61 |
62 | extension HotGoodsCell:UICollectionViewDelegate,UICollectionViewDataSource{
63 |
64 | func setDataArr(dataArr:Array) -> Void {
65 | self.dataArr = dataArr
66 | collectionView.reloadData()
67 | }
68 | func numberOfSections(in collectionView: UICollectionView) -> Int {
69 | return 1
70 | }
71 |
72 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
73 | let num = self.dataArr?.count ?? 0
74 | return num
75 | }
76 |
77 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
78 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: kHotCollectionViewCell_id, for: indexPath) as? HotCollectionViewCell
79 | cell?.setModel(goodsModel: dataArr![indexPath.row])
80 | return cell!
81 | }
82 | }
83 |
84 |
85 |
--------------------------------------------------------------------------------
/TQGO/Class/UnicomAreaModule/View/UnicomMenuCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UnicomMenuCell.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/11/13.
6 | // Copyright © 2018年 Techwis. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class UnicomMenuCell: UITableViewCell {
12 |
13 | var giftlabel:UILabel?
14 | var giftDescLabel:UILabel?
15 | var giftImagV : UIImageView?
16 |
17 | var phonelabel:UILabel?
18 | var phoneDescLabel:UILabel?
19 | var phoneImagV : UIImageView?
20 |
21 |
22 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
23 | super.init(style:style , reuseIdentifier: reuseIdentifier)
24 | self.setupView()
25 | }
26 |
27 | required init?(coder aDecoder: NSCoder) {
28 | fatalError("init(coder:) has not been implemented")
29 | }
30 |
31 |
32 | func setupView() -> Void {
33 | giftlabel = UILabel()
34 | giftlabel?.text = "礼包专区"
35 | giftlabel?.textColor = KCOLOR_Base.font_black
36 | giftlabel?.font = .systemFont(ofSize: 16)
37 | contentView.addSubview(giftlabel!)
38 | giftlabel?.snp.makeConstraints({ (make) in
39 | make.top.equalToSuperview().offset(16)
40 | make.centerX.equalToSuperview().offset(-kScreenWidth/4)
41 | })
42 | giftDescLabel = UILabel()
43 | giftDescLabel?.text = "礼包随心选"
44 | giftDescLabel?.textColor = KCOLOR_Base.font_gray
45 | giftDescLabel?.font = .systemFont(ofSize: 12)
46 | contentView.addSubview(giftDescLabel!)
47 | giftDescLabel?.snp.makeConstraints({ (make) in
48 | make.top.equalTo(giftlabel!.snp.bottom).offset(8)
49 | make.centerX.equalTo(giftlabel!)
50 | })
51 |
52 | giftImagV = UIImageView()
53 | giftImagV?.image = UIImage.init(imageLiteralResourceName: "icon_gift_area")
54 | contentView.addSubview(giftImagV!)
55 | giftImagV?.snp.makeConstraints({ (make) in
56 | make.top.equalTo(giftDescLabel!.snp.bottom).offset(16)
57 | make.bottom.equalToSuperview().offset(-5)
58 | make.size.equalTo(CGSize(width: 110, height: 60))
59 | make.centerX.equalTo(giftDescLabel!)
60 | })
61 |
62 | phonelabel = UILabel()
63 | phonelabel?.text = "手机专区"
64 | phonelabel?.textColor = KCOLOR_Base.font_black
65 | phonelabel?.font = .systemFont(ofSize: 16)
66 | contentView.addSubview(phonelabel!)
67 | phonelabel?.snp.makeConstraints({ (make) in
68 | make.top.equalToSuperview().offset(16)
69 | make.centerX.equalToSuperview().offset(kScreenWidth/4)
70 | })
71 | phoneDescLabel = UILabel()
72 | phoneDescLabel?.text = "手机畅想购"
73 | phoneDescLabel?.textColor = KCOLOR_Base.font_gray
74 | phoneDescLabel?.font = .systemFont(ofSize: 12)
75 | contentView.addSubview(phoneDescLabel!)
76 | phoneDescLabel?.snp.makeConstraints({ (make) in
77 | make.top.equalTo(phonelabel!.snp.bottom).offset(8)
78 | make.centerX.equalTo(phonelabel!)
79 | })
80 |
81 | phoneImagV = UIImageView()
82 | phoneImagV?.image = UIImage.init(imageLiteralResourceName: "icon_phone_area")
83 | contentView.addSubview(phoneImagV!)
84 | phoneImagV?.snp.makeConstraints({ (make) in
85 | make.top.equalTo(phoneDescLabel!.snp.bottom).offset(16)
86 | make.bottom.equalToSuperview().offset(-5)
87 | make.size.equalTo(CGSize(width: 110, height: 60))
88 | make.centerX.equalTo(phoneDescLabel!)
89 | })
90 | }
91 |
92 | override func setSelected(_ selected: Bool, animated: Bool) {
93 | super.setSelected(selected, animated: animated)
94 |
95 | // Configure the view for the selected state
96 | }
97 |
98 |
99 | }
100 |
--------------------------------------------------------------------------------
/TQGO/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleDisplayName
8 | 必买BEMINE
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 4.0.0
21 | CFBundleVersion
22 | 20
23 | LSRequiresIPhoneOS
24 |
25 | NSAppTransportSecurity
26 |
27 | NSAllowsArbitraryLoads
28 |
29 |
30 | UILaunchStoryboardName
31 | LaunchScreen
32 | UIRequiredDeviceCapabilities
33 |
34 | armv7
35 |
36 | UISupportedInterfaceOrientations
37 |
38 | UIInterfaceOrientationPortrait
39 |
40 | UISupportedInterfaceOrientations~ipad
41 |
42 | UIInterfaceOrientationPortrait
43 | UIInterfaceOrientationPortraitUpsideDown
44 | UIInterfaceOrientationLandscapeLeft
45 | UIInterfaceOrientationLandscapeRight
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/TQGO/Macro/AppConstant.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppConstant.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/7/10.
6 | // Copyright © 2018年 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 |
13 | #if DEBUG
14 |
15 | let API_BASE = "http://www.YXY.com" // 测试
16 |
17 | #else
18 | let API_BASE = "http://www.YXY.com" // 正式
19 | #endif
20 |
21 |
22 | #if DEBUG
23 |
24 |
25 | let API_UAPKEY = "YXY"//测试 uapkey
26 | let API_SECRET_KEY = "key=YXY" //测试环境 商户签名秘钥- key
27 |
28 | let KDebugMode = true // debug 模式下,开启调试模式
29 | let KBuglyChannel = "Debug"
30 | let kDEBUGTYPE = true // 调试环境
31 | let kJPUSH_ISProduction = false // 极光推送环境变量
32 | let KBaiduMobStatLog_switch = true // 百度统计 测试环境开启日志输出 上线打开为yes 测试关闭为NO
33 | let kFUPayKey = "YXY"
34 |
35 | #else
36 |
37 |
38 | let API_UAPKEY = "YXY" //正式 uapkey
39 | let API_SECRET_KEY = "key=YXY" //正式环境 商户签名秘钥- key
40 |
41 | #endif
42 |
43 | let KFooterHeight = 48
44 | let kDeliveryTime = 1 // 预计发货时间
45 | let kArrivaTime = 5 // 预计到货时间
46 | let kUserNo = "kUserNo"
47 |
48 | // 接口通用参数配置
49 | let kPLATFORM_CODE = "YXY" // 平台编码
50 | let kIP = "YXY" // 真实来源
51 | let kAPI_ImageServer = "http://YXY/static"
52 | let KBuglyAppId = "YXY" // BuglyAppId
53 | let KWXAppId = "YXY"// WXAppId
54 | let KBaiduMobStatAppKey = "YXY"
55 | let KJPUSHAppKey = "YXY"
56 | let KAppScheme = "YXY"
57 | let KStagesPrice = "50"
58 | let kAES128KEY = "YXY" // AES128KEY 与向量kInitVector值相同
59 |
60 | // 百度统计时间ID
61 | enum KBaiduMobStatID:String{
62 | case Promotion_Category_One = "Promotion_Category_One"
63 | case Promotion_Category_Two = "Promotion_Category_Two"
64 | case Banner = "Banner"
65 | case UnicomBanner = "UnicomBanner"
66 | case HotListView = "HotListView"
67 | case DiscountArea = "DiscountArea"
68 | case GoodsDetailShare = "GoodsDetailShare"
69 | case ViewTextDetailShare = "ViewTextDetailShare"
70 | case GoodsDetailBuy = "GoodsDetailBuy"
71 | case GiftCardExchange = "GiftCardExchange"
72 | case Recharge = "Recharge"
73 | case Login = "Login"
74 | case Register = "Register"
75 | case GetGiftBag = "GetGiftBag"
76 | case PhoneMenu = "PhoneMenu"
77 | case GiftBagMenu = "GiftBagMenu"
78 | case GoodsSearch = "GoodsSearch"
79 | case SubmitOrder = "SubmitOrder"
80 | case CreditPayList = "CreditPayList"
81 | case MakeSurePay = "MakeSurePay"
82 | case AuthActivate = "AuthActivate"
83 | case Repay = "Repay"
84 | }
85 |
86 | // 基础配色
87 | struct KCOLOR_Base {
88 | static let viewBackground = KRGBHEXCOLOR(rgbValue:0xf7f7f7) // f5f5f5
89 | static let font_golden = KRGBHEXCOLOR(rgbValue:0xd2aa60)
90 | static let statusBar = kRGBCOLOR(r:0,g:11,b:15)
91 | static let font_red = KRGBHEXCOLOR(rgbValue:0xff6c6c)
92 | static let line = KRGBHEXCOLOR(rgbValue:0xe7e8ed)
93 | static let font_black = KRGBHEXCOLOR(rgbValue:0x3a404c)
94 | static let font_blue = KRGBHEXCOLOR(rgbValue:0x3b9afe)
95 | static let font_gray = KRGBHEXCOLOR(rgbValue:0x92969f)
96 | static let font_textField = KRGBHEXCOLOR(rgbValue:0xb9bdc6)
97 | }
98 |
99 |
100 |
--------------------------------------------------------------------------------
/TQGO/Macro/Macro.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Macro.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/7/10.
6 | // Copyright © 2018年 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 | import SnapKit
12 |
13 | @_exported import RxSwift
14 | @_exported import RxCocoa
15 | @_exported import RealmSwift
16 | @_exported import HandyJSON
17 | @_exported import SwiftyJSON
18 | @_exported import Kingfisher
19 | @_exported import Toast
20 |
21 | let kScreenHeight = UIScreen.main.bounds.height
22 | let kScreenWidth = UIScreen.main.bounds.width
23 | let kSafeAreaBottomHeight:CGFloat = (((kScreenHeight == 812.0 ) || (kScreenHeight == 896.0)) ? 34 : 0)
24 | let kSafeAreaTopHeight:CGFloat = (((kScreenHeight == 812.0 ) || (kScreenHeight == 896.0)) ? 88 : 64)
25 | let kSystemVersion = (UIDevice.current.systemVersion as NSString).floatValue
26 | let kStatusBarHeight = UIApplication.shared.statusBarFrame.height
27 | let kMainScreenScale = UIScreen.main.scale
28 | let kNavgationHeight = (CGFloat(kStatusBarHeight) + CGFloat(kNabBarHeight))
29 | let kUserDefaults = UserDefaults.standard
30 | let kNotife = NotificationCenter.default
31 | let kAppVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString")
32 | let kUUID = UIDevice.current.identifierForVendor?.uuidString.replacingOccurrences(of: "-", with: "")
33 | let kDate_Location = "zh_CN"
34 | let kTabbarHeight = 49
35 | let kNabBarHeight = 44
36 | let kLineHeight = 0.5
37 | let kSectionHeight:CGFloat = 48
38 | let kMarginHeight = 8
39 | let kLimitPhone = 11
40 | let kLimitPassword = 16
41 | let kLimitSecurityCode = 4
42 |
43 | //获取命名空间,在info.plist文件里就是Executable file
44 | let nameSpace = Bundle.main.infoDictionary!["CFBundleExecutable"] as! String
45 | //拼接成固定格式
46 | func YXYClassFromString(name:String) -> AnyClass{
47 | return NSClassFromString(nameSpace + "." + name)!
48 | }
49 |
50 | // 文件夹路径
51 | struct kDirectoryPath {
52 | static let Documents = NSSearchPathForDirectoriesInDomains(.documentDirectory,.userDomainMask, true).last
53 | static let Library = NSSearchPathForDirectoriesInDomains(.libraryDirectory,.userDomainMask, true).last
54 | static let Tmp = NSTemporaryDirectory()
55 | static let Caches = NSSearchPathForDirectoriesInDomains(.cachesDirectory,.userDomainMask, true).last
56 | }
57 |
58 | // 打印内容,并包含类名和打印所在行数
59 | func DLog(_ message : T,file : String = #file,function:String = #function, lineNumber : Int = #line) {
60 | #if DEBUG
61 | let fileName = (file as NSString).lastPathComponent
62 | let functionStr = function.split(separator: "(").first
63 | print("\n**************自定义日志输出:\(fileName):\(functionStr ?? "")():[\(lineNumber)]************** \n\(message) \n**************************************************")
64 | #endif
65 | }
66 |
67 | func kImage(name:String) -> UIImage?{
68 | return UIImage(named: name)
69 | }
70 |
71 | func kFont(size:CGFloat) -> UIFont{
72 | return UIFont.systemFont(ofSize: size)
73 | }
74 |
75 | func kRGBCOLOR(r:CGFloat,g:CGFloat,b:CGFloat) -> UIColor{
76 | return UIColor(red: r/255.0, green: g/255.0, blue: b/255.0, alpha: 1)
77 | }
78 |
79 | func kRGBACOLOR(r:CGFloat,g:CGFloat,b:CGFloat, a:CGFloat) -> UIColor{
80 | return UIColor(red: r/255.0, green: g/255.0, blue: b/255.0, alpha: a)
81 | }
82 |
83 | //RGB 16进制转换
84 | func KRGBHEXCOLOR(rgbValue: UInt) -> UIColor {
85 | return UIColor(
86 | red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
87 | green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
88 | blue: CGFloat(rgbValue & 0x0000FF) / 255.0,
89 | alpha: CGFloat(1.0)
90 | )
91 | }
92 |
93 |
94 |
--------------------------------------------------------------------------------
/TQGO/Macro/TQGO-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Use this file to import your target's public headers that you would like to expose to Swift.
3 | //
4 |
5 |
6 | #import
7 |
--------------------------------------------------------------------------------
/TQGO/Model/APIModel/APIResultModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // APIResultModel.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/11/28.
6 | // Copyright © 2018 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | //import HandyJSON
11 |
12 | class APIResultModel: HandyJSON {
13 | var data : Any?
14 | var returnCode : String?
15 | var returnMsg :String?
16 |
17 | required init() {}
18 | }
19 |
20 | enum KErrorCode:String{
21 |
22 | case KErrorCode_SUCCESSE = "1000" // 成功
23 | case KErrorCode_CODE1001 = "1001" // 传入参数为空或不合法
24 | case KErrorCode_CODE1002 = "1002" // 数据异常
25 | case KErrorCode_CODE1003 = "1003" // 验签失败
26 | case KErrorCode_CODE1004 = "1004" // 组件编码错误
27 |
28 | case KErrorCode_CODE1005 = "1005" // 重复提交
29 | case KErrorCode_CODE1006 = "1006" // 商品售罄
30 | case KErrorCode_CODE1007 = "1007" // 商品已过期
31 | case KErrorCode_CODE1008 = "1008" // 商品已下线
32 | case KErrorCode_CODE1009 = "1009" // T币余额不足
33 | case KErrorCode_CODE1030 = "1030" // 无效卡
34 | case KErrorCode_CODE1031 = "1031" // 已失效
35 |
36 | case KErrorCode_CODE2000 = "2000" // 验证码发送失败
37 | case KErrorCode_CODE2001 = "2001" // 您已注册请登录
38 | case KErrorCode_CODE2002 = "2002" // 登录密码错误"
39 | case KErrorCode_CODE2003 = "2003" // 用户不存在
40 | case KErrorCode_CODE2004 = "2004" // 验证码错误
41 | case KErrorCode_CODE2005 = "2005" // 验证码超时
42 | case KErrorCode_CODE2006 = "2006" // 请注册之后再登陆
43 | case KErrorCode_CODE2007 = "2007" // 用户未实名
44 |
45 | case KErrorCode_CODE3000 = "3000" // 不支持该银行卡
46 | case KErrorCode_CODE3001 = "3001" // 绑卡失败
47 | case KErrorCode_CODE3002 = "3002" // 该银行卡已签约
48 | case KErrorCode_CODE3003 = "3003" // 银行验证失败
49 | case KErrorCode_CODE3004 = "3004" // 购买失败
50 | case KErrorCode_CODE3005 = "3005" // 购买金额不能大于剩余金额
51 | case KErrorCode_CODE3006 = "3006" // 加密错误
52 | case KErrorCode_CODE3007 = "3007" // 该证件号码已被实名
53 | case KErrorCode_CODE3008 = "3008" // 该银行卡未签约
54 | case KErrorCode_CODE3009 = "3009" // 该优惠劵不可用
55 | case KErrorCode_CODE3010 = "3010" // 该用户未绑定银行卡
56 | case KErrorCode_CODE3011 = "3011" // 该身份证已认证其他用户
57 | case KErrorCode_CODE3012 = "3012" // 身份证认证失败
58 |
59 | case KErrorCode_CODE4000 = "4000" // 产品已售罄
60 | case KErrorCode_CODE4001 = "4001" // 产品不存在
61 | case KErrorCode_CODE4002 = "4002" // 募集时间已结束
62 |
63 | case KErrorCode_CODE5001 = "5001" // 邀请人未参加邀请活动
64 | case KErrorCode_CODE5002 = "5002" // 活动已结束
65 |
66 | case KErrorCode_CODE6001 = "6001" // 请更新版本
67 | case KErrorCode_CODE6002 = "6002" // 已是最新版本
68 |
69 | case KErrorCode_CODE8001 = "8001" // 用户不在白名单内
70 | case KErrorCode_CODE8002 = "8002" // 用户在黑名单中
71 | case KErrorCode_CODE8003 = "8003" // 授信申请失败
72 | case KErrorCode_CODE8004 = "8004" // 启动活体识别验证失败
73 |
74 | case KErrorCode_CODE9998 = "9998" // 数据异常,请稍后
75 | case KErrorCode_CODE9999 = "9999" // 系统异常,请重试
76 |
77 | case KErrorCode_Login_INVALID = "9990" // 登录信息有误
78 |
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "icon-20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "icon-20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "icon-29@2x.png",
19 | "scale" : "2x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "icon-29@3x.png",
25 | "scale" : "3x"
26 | },
27 | {
28 | "size" : "40x40",
29 | "idiom" : "iphone",
30 | "filename" : "icon-40@2x.png",
31 | "scale" : "2x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "icon-40@3x.png",
37 | "scale" : "3x"
38 | },
39 | {
40 | "size" : "60x60",
41 | "idiom" : "iphone",
42 | "filename" : "icon-60@2x.png",
43 | "scale" : "2x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "icon-60@3x.png",
49 | "scale" : "3x"
50 | },
51 | {
52 | "size" : "1024x1024",
53 | "idiom" : "ios-marketing",
54 | "filename" : "icon_1024.png",
55 | "scale" : "1x"
56 | }
57 | ],
58 | "info" : {
59 | "version" : 1,
60 | "author" : "xcode"
61 | }
62 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/AppIcon.appiconset/icon_1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/AppIcon.appiconset/icon_1024.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/LanchIcon/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/LanchIcon/icon_launch.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "icon_launch@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "icon_launch@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/LanchIcon/icon_launch.imageset/icon_launch@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/LanchIcon/icon_launch.imageset/icon_launch@2x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/LanchIcon/icon_launch.imageset/icon_launch@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/LanchIcon/icon_launch.imageset/icon_launch@3x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/MyImage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/MyImage/icon_arrow_right_white.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "icon_arrow_right_white@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "icon_arrow_right_white@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/MyImage/icon_arrow_right_white.imageset/icon_arrow_right_white@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/MyImage/icon_arrow_right_white.imageset/icon_arrow_right_white@2x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/MyImage/icon_arrow_right_white.imageset/icon_arrow_right_white@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/MyImage/icon_arrow_right_white.imageset/icon_arrow_right_white@3x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/MyImage/icon_header.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "icon_header@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "icon_header@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/MyImage/icon_header.imageset/icon_header@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/MyImage/icon_header.imageset/icon_header@2x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/MyImage/icon_header.imageset/icon_header@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/MyImage/icon_header.imageset/icon_header@3x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/MyImage/icon_phone_num.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "icon_phone_num@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "icon_phone_num@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/MyImage/icon_phone_num.imageset/icon_phone_num@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/MyImage/icon_phone_num.imageset/icon_phone_num@2x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/MyImage/icon_phone_num.imageset/icon_phone_num@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/MyImage/icon_phone_num.imageset/icon_phone_num@3x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/MyImage/icon_secure_close.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "icon_secure_close@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "icon_secure_close@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/MyImage/icon_secure_close.imageset/icon_secure_close@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/MyImage/icon_secure_close.imageset/icon_secure_close@2x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/MyImage/icon_secure_close.imageset/icon_secure_close@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/MyImage/icon_secure_close.imageset/icon_secure_close@3x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/MyImage/icon_secure_visible.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "icon_secure_visible@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "icon_secure_visible@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/MyImage/icon_secure_visible.imageset/icon_secure_visible@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/MyImage/icon_secure_visible.imageset/icon_secure_visible@2x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/MyImage/icon_secure_visible.imageset/icon_secure_visible@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/MyImage/icon_secure_visible.imageset/icon_secure_visible@3x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/MyImage/icon_security_lock.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "icon_security_lock@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "icon_security_lock@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/MyImage/icon_security_lock.imageset/icon_security_lock@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/MyImage/icon_security_lock.imageset/icon_security_lock@2x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/MyImage/icon_security_lock.imageset/icon_security_lock@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/MyImage/icon_security_lock.imageset/icon_security_lock@3x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/MyImage/icon_verity_code.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "icon_verity_code@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "icon_verity_code@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/MyImage/icon_verity_code.imageset/icon_verity_code@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/MyImage/icon_verity_code.imageset/icon_verity_code@2x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/MyImage/icon_verity_code.imageset/icon_verity_code@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/MyImage/icon_verity_code.imageset/icon_verity_code@3x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/TabbarImage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_default_credit.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "icon_tabbar_default_credit@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "icon_tabbar_default_credit@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_default_credit.imageset/icon_tabbar_default_credit@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_default_credit.imageset/icon_tabbar_default_credit@2x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_default_credit.imageset/icon_tabbar_default_credit@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_default_credit.imageset/icon_tabbar_default_credit@3x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_default_personalCenter.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "icon_tabbar_default_personalCenter@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "icon_tabbar_default_personalCenter@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | },
22 | "properties" : {
23 | "template-rendering-intent" : "original"
24 | }
25 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_default_personalCenter.imageset/icon_tabbar_default_personalCenter@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_default_personalCenter.imageset/icon_tabbar_default_personalCenter@2x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_default_personalCenter.imageset/icon_tabbar_default_personalCenter@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_default_personalCenter.imageset/icon_tabbar_default_personalCenter@3x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_default_promotion.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "icon_tabbar_default_promotion@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "icon_tabbar_default_promotion@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | },
22 | "properties" : {
23 | "template-rendering-intent" : "original"
24 | }
25 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_default_promotion.imageset/icon_tabbar_default_promotion@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_default_promotion.imageset/icon_tabbar_default_promotion@2x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_default_promotion.imageset/icon_tabbar_default_promotion@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_default_promotion.imageset/icon_tabbar_default_promotion@3x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_default_unicom.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "icon_tabbar_default_unicom@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "icon_tabbar_default_unicom@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | },
22 | "properties" : {
23 | "template-rendering-intent" : "original"
24 | }
25 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_default_unicom.imageset/icon_tabbar_default_unicom@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_default_unicom.imageset/icon_tabbar_default_unicom@2x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_default_unicom.imageset/icon_tabbar_default_unicom@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_default_unicom.imageset/icon_tabbar_default_unicom@3x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_selected_credit.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "icon_tabbar_selected_credit@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "icon_tabbar_selected_credit@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_selected_credit.imageset/icon_tabbar_selected_credit@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_selected_credit.imageset/icon_tabbar_selected_credit@2x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_selected_credit.imageset/icon_tabbar_selected_credit@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_selected_credit.imageset/icon_tabbar_selected_credit@3x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_selected_personalCenter.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "icon_tabbar_selected_personalCenter@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "icon_tabbar_selected_personalCenter@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | },
22 | "properties" : {
23 | "template-rendering-intent" : "original"
24 | }
25 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_selected_personalCenter.imageset/icon_tabbar_selected_personalCenter@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_selected_personalCenter.imageset/icon_tabbar_selected_personalCenter@2x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_selected_personalCenter.imageset/icon_tabbar_selected_personalCenter@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_selected_personalCenter.imageset/icon_tabbar_selected_personalCenter@3x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_selected_promotion.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "icon_tabbar_selected_promotion@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "icon_tabbar_selected_promotion@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | },
22 | "properties" : {
23 | "template-rendering-intent" : "original"
24 | }
25 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_selected_promotion.imageset/icon_tabbar_selected_promotion@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_selected_promotion.imageset/icon_tabbar_selected_promotion@2x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_selected_promotion.imageset/icon_tabbar_selected_promotion@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_selected_promotion.imageset/icon_tabbar_selected_promotion@3x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_selected_unicom.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "icon_tabbar_selected_unicom@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "icon_tabbar_selected_unicom@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | },
22 | "properties" : {
23 | "template-rendering-intent" : "original"
24 | }
25 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_selected_unicom.imageset/icon_tabbar_selected_unicom@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_selected_unicom.imageset/icon_tabbar_selected_unicom@2x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_selected_unicom.imageset/icon_tabbar_selected_unicom@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/TabbarImage/icon_tabbar_selected_unicom.imageset/icon_tabbar_selected_unicom@3x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/UnicomImage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/UnicomImage/icon_flag_blue.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "icon_flag_blue@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "icon_flag_blue@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/UnicomImage/icon_flag_blue.imageset/icon_flag_blue@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/UnicomImage/icon_flag_blue.imageset/icon_flag_blue@2x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/UnicomImage/icon_flag_blue.imageset/icon_flag_blue@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/UnicomImage/icon_flag_blue.imageset/icon_flag_blue@3x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/UnicomImage/icon_gift_area.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "icon_gift_area@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "icon_gift_area@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/UnicomImage/icon_gift_area.imageset/icon_gift_area@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/UnicomImage/icon_gift_area.imageset/icon_gift_area@2x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/UnicomImage/icon_gift_area.imageset/icon_gift_area@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/UnicomImage/icon_gift_area.imageset/icon_gift_area@3x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/UnicomImage/icon_goods_default.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "icon_goods_default@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "icon_goods_default@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/UnicomImage/icon_goods_default.imageset/icon_goods_default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/UnicomImage/icon_goods_default.imageset/icon_goods_default@2x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/UnicomImage/icon_goods_default.imageset/icon_goods_default@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/UnicomImage/icon_goods_default.imageset/icon_goods_default@3x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/UnicomImage/icon_home_banner_default.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "icon_home_banner_default@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "icon_home_banner_default@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/UnicomImage/icon_home_banner_default.imageset/icon_home_banner_default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/UnicomImage/icon_home_banner_default.imageset/icon_home_banner_default@2x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/UnicomImage/icon_home_banner_default.imageset/icon_home_banner_default@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/UnicomImage/icon_home_banner_default.imageset/icon_home_banner_default@3x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/UnicomImage/icon_phone_area.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "icon_phone_area@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "icon_phone_area@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/UnicomImage/icon_phone_area.imageset/icon_phone_area@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/UnicomImage/icon_phone_area.imageset/icon_phone_area@2x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/UnicomImage/icon_phone_area.imageset/icon_phone_area@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/UnicomImage/icon_phone_area.imageset/icon_phone_area@3x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/UnicomImage/icon_search.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "icon_search@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "icon_search@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/UnicomImage/icon_search.imageset/icon_search@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/UnicomImage/icon_search.imageset/icon_search@2x.png
--------------------------------------------------------------------------------
/TQGO/Resource/Assets.xcassets/UnicomImage/icon_search.imageset/icon_search@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeYXY/SwiftProject/4757db11655c36b1de7f2b1678ece499ddcb5d8f/TQGO/Resource/Assets.xcassets/UnicomImage/icon_search.imageset/icon_search@3x.png
--------------------------------------------------------------------------------
/TQGO/Resource/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 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/TQGO/Resource/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 |
--------------------------------------------------------------------------------
/TQGO/Resource/BimineData/UnicomAreaDiscountZone.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | goodsCode
7 | JXPZ_358
8 | goodsName
9 | “匠心品质”
10 | goodsSell
11 | 2
12 | goodsType
13 | 0
14 | hideStatus
15 | 1
16 | imgUrl
17 | http://www.tequango.com/privilegeGo/image/1530849358155.jpg
18 | payPrice
19 | 358
20 | price
21 | 358
22 | tag
23 | 匠心之道,让家更有味道
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/TQGO/Resource/BimineData/UnicomAreaRecommGoods.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | goodsCode
7 | HW_Mate10Pro
8 | goodsName
9 | 华为 Mate10 Pro 全网通
10 | goodsType
11 | 3
12 | hideStatus
13 | 1
14 | imgUrl
15 | http://www.tequango.com/privilegeGo/image/1514193683322.png
16 | tag
17 | 防溅抗水,卓越性能
18 |
19 |
20 | goodsCode
21 | HW_P20
22 | goodsName
23 | 华为 P20 AI智慧全面屏 全网通4G手机 双卡双待
24 | goodsType
25 | 3
26 | hideStatus
27 | 1
28 | imgUrl
29 | http://www.tequango.com/privilegeGo/image/1532488849868.jpg
30 | tag
31 | 高颜值,高性能
32 |
33 |
34 | goodsCode
35 | NXNW_180
36 | goodsName
37 | “暖心暖胃”
38 | goodsType
39 | 0
40 | hideStatus
41 | 1
42 | imgUrl
43 | http://www.tequango.com/privilegeGo/image/1530503853959.jpg
44 | tag
45 | 高颜值,超实用
46 |
47 |
48 | goodsCode
49 | LXWC_80
50 | goodsName
51 | “两小无猜”
52 | goodsType
53 | 0
54 | hideStatus
55 | 1
56 | imgUrl
57 | http://www.tequango.com/privilegeGo/image/1530512272780.jpg
58 | tag
59 | 甜美清新,便捷实用
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/TQGO/Resource/BimineData/UnicomBanner.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | bannerName
7 | 华为P20
8 | imgUrl
9 | http://www.tequango.com/privilegeGo/image/content/1537257775785.jpg
10 | openType
11 | 1
12 | openUrl
13 | HW_P20/3
14 |
15 |
16 | bannerName
17 | 华为荣耀10
18 | imgUrl
19 | http://www.tequango.com/privilegeGo/image/content/1526380127239.png
20 | openType
21 | 1
22 | openUrl
23 | HW_RY10/3
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/TQGO/Resource/BimineData/homeBanner.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | bannerName
7 | cpb隔离专柜日版
8 | imgUrl
9 | http://www.tequango.com/privilegeGo/image/content/1551262998626.png
10 | openType
11 | 1
12 | openUrl
13 | RB_CPB_gls_black/2/eb4f99bb199bf4c9014e/MZXH
14 |
15 |
16 | bannerName
17 | club晚安粉-彩色玫瑰
18 | imgUrl
19 | http://www.tequango.com/privilegeGo/image/content/1551262911182.png
20 | openType
21 | 1
22 | openUrl
23 | club_waf_rose/2/eb4f99bb199bf4c9014e/MZXH
24 |
25 |
26 | bannerName
27 | 祖玛龙香水英国梨与小苍兰
28 | imgUrl
29 | http://www.tequango.com/privilegeGo/image/content/1533294325809.jpg
30 | openType
31 | 1
32 | openUrl
33 | HZP_mz_19220/2/eb4f99bb199bf4c9014e/MZXH
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/TQGO/Resource/BimineData/menu.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | code
7 | MZXH
8 | name
9 | 美妆洗护
10 |
11 |
12 | code
13 | PJZX
14 | name
15 | 配件专享
16 |
17 |
18 | code
19 | JJYX
20 | name
21 | 居家优享
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/TQGO/Tool/NetworkManager/NetworkManager.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NetworkManager.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/11/14.
6 | // Copyright © 2018年 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Alamofire
11 | import UIKit
12 |
13 | typealias successClosure = (APIResultModel) -> (Void)
14 | typealias failClosure = (Any) -> (Void)
15 |
16 | public enum APIError {
17 | case apiError_done // 请求成功
18 | case apiError_netError(String) // 请求失败 网络 原因
19 | case apiError_serverMessage(String) // 请求失败 服务器原因
20 | }
21 |
22 | protocol APIInterfaceProtocol {
23 | var path:String {get}
24 | var parameters: [String: String]? { get }
25 |
26 | }
27 |
28 | class NetworkManager {
29 |
30 | private static var sharedSessionManager: SessionManager = {
31 | let configuration = URLSessionConfiguration.default
32 | configuration.timeoutIntervalForRequest = 0.2//请求超时时间
33 | return SessionManager(configuration: configuration)
34 | }()
35 |
36 | private static func commonAPIParameters()->Dictionary{
37 | let userInfo = UserInfo.instance
38 |
39 | var parameters = [String : String]()
40 | parameters.updateValue(API_UAPKEY, forKey: "uapkey")
41 | parameters.updateValue(flowNumber(), forKey: "flowNo")
42 | parameters.updateValue(kPLATFORM_CODE, forKey: "platformCode")
43 | parameters.updateValue("2", forKey: "terminalType")
44 | parameters.updateValue(String.nowTimeWithFormat(format: kTimeFormat.format_yyyyMdHms.rawValue), forKey: "ts")
45 | parameters.updateValue(kIP, forKey: "ip")
46 | parameters.updateValue(kUUID!, forKey: "mac")
47 | parameters.updateValue("1", forKey: "dtype")
48 | parameters.updateValue(UIDevice.current.modelName, forKey: "brand")
49 | parameters.updateValue(kAppVersion as! String, forKey: "ver")
50 | if userInfo?.userNo != nil {
51 | parameters.updateValue("1", forKey: "userToken")
52 | }
53 | return parameters
54 | }
55 |
56 | // 生成随机数 yyyyMMddHHmmss+6位数
57 | private static func flowNumber()-> String {
58 | let timeSpan = String.nowTimeWithFormat(format:"yyyyMMddHHmmss")
59 | let randomNum = String(format: "%d", 100000 + (arc4random() % 100001))
60 | let flowNumber = String(format: "%@%@", timeSpan,randomNum)
61 | return flowNumber
62 | }
63 |
64 | // 生成签名参数
65 | private static func SignParameters(params:[String:AnyObject])->Dictionary{//Dictionary
66 | //参数排序
67 | var parameters = params
68 | let keyArray = params.keys.sorted()
69 | var jointParamsStr = ""
70 | for key in keyArray {
71 | var val:AnyObject
72 | if key == "appMap" {
73 | val = ((params[key]! as! Dictionary) as NSObject).modelToJSONString as AnyObject
74 | val = (val as! String).replacingOccurrences(of: "\\/", with: "/") as AnyObject// 过滤AESBase64加密后带\字符的情况
75 | }else{
76 | val = params[key]!;
77 | }
78 | let itemUrl = String(format: "%@=%@",key,val as! String)
79 | jointParamsStr = String(format: "%@%@|", jointParamsStr,itemUrl)
80 | }
81 | // 拼接商户的秘钥
82 | jointParamsStr = String(format: "%@%@", jointParamsStr,API_SECRET_KEY);
83 | DLog("\n************拼接商户的秘钥后的管道数据************:\n \(jointParamsStr)")
84 | // MD5加密
85 | let signStr = jointParamsStr.md5;
86 | parameters["sign"] = signStr as AnyObject
87 | DLog("\n************完成签名参数************:\n\(parameters)");
88 | return parameters
89 | }
90 |
91 | private static func postRequest(interface:String,params:Dictionary,completion:@escaping successClosure,failed:@escaping failClosure){
92 | // 构建全部参数
93 | var commonParas = commonAPIParameters() as [String : AnyObject]
94 | commonParas["operation"] = interface as AnyObject
95 |
96 | if params.isEmpty {
97 | commonParas.updateValue( "" as AnyObject, forKey: "appMap")
98 | }else{
99 | commonParas["appMap"] = params as AnyObject
100 | }
101 |
102 | // 生成签名参数sign
103 | let paramDict = SignParameters(params: commonParas )
104 | let headers: HTTPHeaders = [
105 | "Accept": "application/json,text/json,text/javascript,text/plain,text/html",
106 | "Content-type" : "application/json"
107 | ]
108 |
109 | sharedSessionManager.request(API_BASE ,
110 | method: .post,
111 | parameters: paramDict,
112 | encoding:JSONEncoding.default,
113 | headers:headers).responseJSON{ (response) in
114 | switch response.result {
115 | case .success(let value):
116 | DLog("接口路径:||-------------" + interface + "-------------||")
117 | DLog(JSON(value))
118 | completion(APIResultModel.deserialize(from:value as? Dictionary) ?? APIResultModel())
119 | return
120 | case .failure(let error):
121 | DLog(String(describing: error))
122 | failed(error)
123 |
124 | return
125 | }
126 | }
127 |
128 | // Alamofire.request(API_BASE ,
129 | // method: .post,
130 | // parameters: paramDict,
131 | // encoding:JSONEncoding.default,
132 | // headers:headers).responseString { (response) in
133 | // switch response.result {
134 | // case .success(let value):
135 | // if value.isEmpty{
136 | // DLog(message: "-------请求结果为空------")
137 | // return
138 | // }else{
139 | // let str = try? JSON(data: value.data(using: String.Encoding.utf8)!, options: JSONSerialization.ReadingOptions.mutableContainers)
140 | // DLog(message:"接口路径:||-------------" + interface + "-------------||")
141 | // DLog(message: str)
142 | // completion(APIResultModel.deserialize(from:value)!)
143 | // return
144 | // }
145 | // case .failure(let error):
146 | // DLog(message: String(describing: error))
147 | // failed(error)
148 | // return
149 | // }
150 | // }
151 | }
152 |
153 | static func loadData(api:APIInterfaceProtocol,completionClosure: @escaping successClosure,failClosure:@escaping failClosure) -> Void {
154 | var paramsDict = [String:String]()
155 | _ = api.parameters?.map({ (key, value) in
156 | if !value.isEmpty {
157 | paramsDict.updateValue(value , forKey: key)
158 | }
159 | })
160 | NetworkManager.postRequest(interface:api.path , params: paramsDict, completion: { (resopne) -> (Void) in
161 | completionClosure(resopne)
162 | }) { (fail) -> (Void) in
163 | failClosure(fail)
164 | }
165 | }
166 | }
167 |
--------------------------------------------------------------------------------
/TQGO/Tool/NetworkManager/NetworkManagerLoginRegister.swift:
--------------------------------------------------------------------------------
1 |
2 | //
3 | // NetworkManagerLoginRegister.swift
4 | // TQGO
5 | //
6 | // Created by YXY on 2019/10/31.
7 | // Copyright © 2019 Techwis. All rights reserved.
8 | //
9 |
10 | import Foundation
11 |
12 |
13 | enum APIInterfaceLoginRegister {
14 | case userLogin(params:[String:String])
15 |
16 | }
17 |
18 |
19 |
20 | extension APIInterfaceLoginRegister:APIInterfaceProtocol{
21 |
22 | var path:String{
23 | switch self {
24 | case .userLogin(_):
25 | return "userLogin"
26 | }
27 | }
28 | var parameters: [String : String]?{
29 | switch self {
30 | case .userLogin(let params):
31 | return params
32 | }
33 | }
34 |
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/TQGO/Tool/NetworkManager/NetworkManagerPromotion.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NetworkManagerPromotion.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2019/3/19.
6 | // Copyright © 2019 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import SwiftyJSON
11 |
12 |
13 | enum APIInterfacePromotion {
14 | case queryPromoIndex(params:[String:String])
15 | }
16 |
17 | extension APIInterfacePromotion:APIInterfaceProtocol{
18 | var path:String{
19 | switch self {
20 | case .queryPromoIndex:
21 | return "queryPromoIndex"
22 | }
23 | }
24 |
25 | var parameters: [String : String]?{
26 | switch self {
27 | case .queryPromoIndex(let params):
28 | return params
29 | }
30 | }
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/TQGO/Tool/NetworkManager/NetworkManagerUnicom.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NetworkManagerUnicom.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2018/11/15.
6 | // Copyright © 2018年 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import SwiftyJSON
11 |
12 | enum APIInterfaceUnicom {
13 | case queryUnicomZoneIndex(params:[String:String])
14 | }
15 |
16 | extension APIInterfaceUnicom:APIInterfaceProtocol{
17 | var path:String{
18 | switch self {
19 | case .queryUnicomZoneIndex(_):
20 | return "queryUnicomZoneIndex"
21 | }
22 | }
23 | var parameters: [String : String]?{
24 | switch self {
25 | case .queryUnicomZoneIndex(let params):
26 | return params
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/TQGO/Tool/RealmTool/RealmManager.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RealmManager.swift
3 | // TQGO
4 | // realm工具类
5 | // Created by YXY on 2019/11/15.
6 | // Copyright © 2019 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | class RealmManager {
13 | //MARK: db路径
14 | static var url:URL = {
15 | let path = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).first?.fileByAppendingPaths(byAppendingPaths: "/Realm")
16 | path?.fileCreateDirectory()
17 | let dbPath = path?.fileByAppendingPaths(byAppendingPaths:"/TQGODB.realm")
18 | return URL(string: dbPath!)!
19 | }()
20 | //MARK: realm单例
21 | static let instance :Realm = {
22 |
23 | let realm = try! Realm()
24 | DLog("realm数据库存储路径:\(realm.configuration.fileURL!.absoluteString)")
25 | return realm
26 | // 获取 Realm 文件的父目录
27 | // let folderPath = realm.configuration.fileURL!.deletingLastPathComponent().path
28 | // // 禁用此目录的文件保护
29 | // try? FileManager.default.setAttributes([FileAttributeKey.protectionKey : FileProtectionType.none], ofItemAtPath: folderPath)
30 |
31 | }()
32 |
33 | }
34 |
35 | extension RealmManager{
36 | //MARK: 配置Realm 用于数据库迁移
37 | static func config () {
38 |
39 | Realm.Configuration.defaultConfiguration = Realm.Configuration(
40 | fileURL: url,
41 | schemaVersion: 1,
42 | migrationBlock: { migration, oldSchemaVersion in
43 | // We haven’t migrated anything yet, so oldSchemaVersion == 0
44 | if (oldSchemaVersion < 1) {
45 | // 1
46 | // Nothing to do!
47 | // Realm will automatically detect new properties and removed properties
48 | // And will update the schema on disk automatically
49 | // 2
50 | // 合并两个属性为一个新属性
51 | // migration.enumerateObjects(ofType: UserInfo.className()) { oldObject, newObject in
52 | // // combine name fields into a single field
53 | // let firstName = oldObject!["firstName"] as! String
54 | // let lastName = oldObject!["lastName"] as! String
55 | // newObject!["fullName"] = "\(firstName) \(lastName)"
56 | // }
57 | // 3
58 | // 属性重命名
59 | // The renaming operation should be done outside of calls to `enumerateObjects(ofType: _:)`.
60 | // migration.renameProperty(onType: UserInfo.className(), from: "yearsSinceBirth", to: "age")
61 | }
62 | })
63 |
64 |
65 | Realm.asyncOpen { (realm, error) in
66 | if let _ = realm {
67 | print("Realm 服务器配置成功!")
68 | }else if let error = error {
69 | print("Realm 数据库配置失败:\(error.localizedDescription)")
70 | }
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/TQGO/Tool/Regex/Regex.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Regex.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2019/11/22.
6 | // Copyright © 2019 Techwis. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /// 基于NSRegularExpression api 的正则处理工具类
12 | struct Regex {
13 | private let regularExpression: NSRegularExpression
14 |
15 | //使用正则表达式进行初始化
16 | public init(_ pattern: String, options: Options = []) throws {
17 | regularExpression = try NSRegularExpression(
18 | pattern: pattern,
19 | options: options.toNSRegularExpressionOptions
20 | )
21 | }
22 |
23 | //正则匹配验证(true表示匹配成功)
24 | public func matches(_ string: String) -> Bool {
25 | return firstMatch(in: string) != nil
26 | }
27 |
28 | //获取第一个匹配结果
29 | public func firstMatch(in string: String) -> Match? {
30 | let firstMatch = regularExpression
31 | .firstMatch(in: string, options: [],
32 | range: NSRange(location: 0, length: string.utf16.count))
33 | .map { Match(result: $0, in: string) }
34 | return firstMatch
35 | }
36 |
37 | //获取所有的匹配结果
38 | public func matches(in string: String) -> [Match] {
39 | let matches = regularExpression
40 | .matches(in: string, options: [],
41 | range: NSRange(location: 0, length: string.utf16.count))
42 | .map { Match(result: $0, in: string) }
43 | return matches
44 | }
45 |
46 | //正则替换
47 | public func replacingMatches(in input: String, with template: String,
48 | count: Int? = nil) -> String {
49 | var output = input
50 | let matches = self.matches(in: input)
51 | let rangedMatches = Array(matches[0.. = {
112 | return Range(self.result.range, in: self.baseString)!
113 | }()
114 |
115 | //正则表达式中每个捕获组匹配的字符串
116 | public lazy var captures: [String?] = {
117 | let captureRanges = stride(from: 0, to: result.numberOfRanges, by: 1)
118 | .map(result.range)
119 | .dropFirst()
120 | .map { [unowned self] in
121 | Range($0, in: self.baseString)
122 | }
123 |
124 | return captureRanges.map { [unowned self] captureRange in
125 | if let captureRange = captureRange {
126 | return String(describing: self.baseString[captureRange])
127 | }
128 |
129 | return nil
130 | }
131 | }()
132 |
133 | private let result: NSTextCheckingResult
134 |
135 | private let baseString: String
136 |
137 | //初始化
138 | internal init(result: NSTextCheckingResult, in string: String) {
139 | precondition(
140 | result.regularExpression != nil,
141 | "NSTextCheckingResult必需使用正则表达式"
142 | )
143 |
144 | self.result = result
145 | self.baseString = string
146 | }
147 |
148 | //返回一个新字符串,根据“模板”替换匹配的字符串。
149 | public func string(applyingTemplate template: String) -> String {
150 | let replacement = result.regularExpression!.replacementString(
151 | for: result,
152 | in: baseString,
153 | offset: 0,
154 | template: template
155 | )
156 |
157 | return replacement
158 | }
159 |
160 | //藐视信息
161 | public var description: String {
162 | return "Match<\"\(string)\">"
163 | }
164 | }
165 | }
166 |
167 | ////初始化正则工具类 下面样例验证一个邮箱地址的格式是否正确。
168 | //let pattern = "^([a-z0-9_\\.-]+)@([\\da-z\\.-]+)\\.([a-z\\.]{2,6})$"
169 | //let regex = try! Regex(pattern)
170 | //
171 | ////验证邮箱地址
172 | //let mailAddress = "admin@hangge.com"
173 | //if regex.matches(mailAddress) {
174 | // print("邮箱地址格式正确")
175 | //}else{
176 | // print("邮箱地址格式有误")
177 | //}
178 |
--------------------------------------------------------------------------------
/TQGO/Tool/ViewTool/YXYPageView/YXYMenuTitleView.swift:
--------------------------------------------------------------------------------
1 |
2 | //
3 | // YXYMenuTitleView.swift
4 | // TQGO
5 | //
6 | // Created by YXY on 2019/3/21.
7 | // Copyright © 2019 Techwis. All rights reserved.
8 | //
9 |
10 | import Foundation
11 | import UIKit
12 |
13 | protocol YXYMenuMoveProtocol:class {
14 | func menuMoveProtocol(formIndex:NSInteger,toIndex:NSInteger)
15 | }
16 |
17 |
18 | enum YXYIndicatorType:NSInteger {
19 | case YXYIndicatorTypeDefault = 0,//默认与按钮长度相同
20 | YXYIndicatorTypeEqualTitle,//与文字长度相同
21 | YXYIndicatorTypeCustom,//自定义文字边缘延伸宽度
22 | YXYIndicatorTypeNone
23 | }//指示器类型枚举
24 |
25 | class YXYMenuTitleView: UIView {
26 |
27 | var indicatorType:YXYIndicatorType = .YXYIndicatorTypeDefault{
28 | didSet{
29 | moveIndicatorView()
30 | }
31 | }
32 | var titleArr: Array = [String]()
33 | var menuArr :Array = [UIButton]()
34 | var menuWidth:CGFloat = 60.0
35 | var selectIndex:NSInteger = 0{
36 | didSet{
37 | moveIndicatorView()
38 | }
39 | }
40 | var indicatorHeight:CGFloat = 2
41 | var indicatorExtension:CGFloat = 0 {
42 | didSet{
43 | moveIndicatorView()
44 | }
45 | }
46 |
47 | weak var menuMoveDelegate:YXYMenuMoveProtocol?
48 | // 按钮间距离
49 | var menuMargin:CGFloat = 20{
50 | didSet{
51 |
52 | }
53 | }
54 | // 字体大小
55 | var menuFont:CGFloat = 14{
56 | didSet{
57 |
58 | }
59 | }
60 |
61 | lazy var menuScrollView: UIScrollView = {
62 | let menuScrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: self.width, height: self.height))
63 | menuScrollView.showsHorizontalScrollIndicator = false
64 | menuScrollView.contentSize = CGSize(width: width, height: self.height)
65 | return menuScrollView
66 | }()
67 |
68 | lazy var indicatorView: UIView = {
69 | let indicatorView = UIView()
70 | indicatorView.backgroundColor = KCOLOR_Base.font_blue
71 | menuScrollView.addSubview(indicatorView)
72 | return indicatorView
73 | }()
74 |
75 |
76 |
77 | var menuScrollCount:CGFloat = 5 {
78 | didSet{
79 | menuScrollView.contentSize = CGSize(width: menuScrollCount*menuWidth, height: self.height)
80 | }
81 | }
82 |
83 | override init(frame: CGRect) {
84 | super.init(frame: frame)
85 |
86 | }
87 |
88 | required init?(coder aDecoder: NSCoder) {
89 | fatalError("init(coder:) has not been implemented")
90 | }
91 |
92 | convenience init(frame:CGRect,titleArr:[String]) {
93 | self.init(frame:frame)
94 | self.backgroundColor = .white
95 | self.addSubview(self.menuScrollView)
96 | self.setupMenu(titleArr: titleArr)
97 |
98 | let line = UIView()
99 | line.backgroundColor = KCOLOR_Base.line
100 | self.addSubview(line)
101 | line.snp.makeConstraints { (make) in
102 | make.left.right.bottom.equalToSuperview()
103 | make.height.equalTo(0.5)
104 | }
105 | }
106 |
107 | override func layoutSubviews() {
108 | super.layoutSubviews()
109 | moveIndicatorView()
110 | }
111 |
112 | func moveIndicatorView(){
113 | if menuArr.isEmpty {
114 | return
115 | }
116 | let selectedBtn = menuArr[selectIndex]
117 | let indicatorWidth:CGFloat = (selectedBtn.titleLabel?.text?.width(fontSize: menuFont))!
118 |
119 | UIView.animate(withDuration: 0.05, animations: {
120 | switch self.indicatorType {
121 | case .YXYIndicatorTypeDefault:
122 | self.indicatorView.frame = CGRect(x: selectedBtn.x, y: selectedBtn.bottomY-self.indicatorHeight, width: selectedBtn.width, height: self.indicatorHeight)
123 | break
124 | case .YXYIndicatorTypeEqualTitle:
125 | self.indicatorView.center = CGPoint(x: selectedBtn.centerX, y: selectedBtn.bottomY-self.indicatorHeight/2)
126 | self.indicatorView.bounds = CGRect(x: 0, y: 0,width:indicatorWidth , height: self.indicatorHeight)
127 | break
128 | case .YXYIndicatorTypeCustom:
129 | self.indicatorView.center = CGPoint(x: selectedBtn.centerX, y: selectedBtn.bottomY-self.indicatorHeight/2)
130 | self.indicatorView.bounds = CGRect(x: 0, y: 0,width:self.indicatorExtension , height: self.indicatorHeight)
131 | break
132 | case .YXYIndicatorTypeNone:
133 | self.indicatorView.frame = CGRect(x: 0, y: 0, width: 0, height: 0);
134 | break
135 | }
136 | }) { (finished) in
137 |
138 | }
139 | }
140 |
141 | func setupMenu(titleArr:[String]) {
142 | let _ = menuArr.map { (make) -> Void in
143 | make.removeFromSuperview()
144 | }
145 | menuArr.removeAll()
146 | if titleArr.isEmpty {
147 | return
148 | }
149 | var totalMenuWidth:CGFloat = 0
150 | for (_, val) in titleArr.enumerated() {
151 | let menuWidth = val.width(fontSize: menuFont) + menuMargin
152 | let menu = UIButton(type: UIButton.ButtonType.custom)
153 | menu.frame = CGRect(x: totalMenuWidth, y: 0.0, width: menuWidth, height: height)
154 | menu.setTitle(val, for: UIControl.State.normal)
155 | menu.setTitleColor(.black, for: .normal)
156 | menu.titleLabel?.font = UIFont.systemFont(ofSize: 14)
157 | menu.addTarget(self, action: #selector(menuAction), for: UIControl.Event.touchUpInside)
158 | menuScrollView.addSubview(menu)
159 | menuArr.append(menu)
160 | totalMenuWidth = totalMenuWidth + menuWidth
161 | }
162 | menuScrollView.contentSize.width = totalMenuWidth
163 | }
164 |
165 | @objc func menuAction(sender:UIButton){
166 | let index = menuArr.firstIndex(of: sender)
167 | if selectIndex == index {
168 | return
169 | }
170 | if menuMoveDelegate != nil{
171 | menuMoveDelegate?.menuMoveProtocol(formIndex: selectIndex, toIndex: index!)
172 | }
173 | selectIndex = index!
174 | moveIndicatorView()
175 | }
176 | }
177 |
--------------------------------------------------------------------------------
/TQGO/Tool/ViewTool/YXYPageView/YXYPageContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // YXYPageContentView.swift
3 | // TQGO
4 | //
5 | // Created by YXY on 2019/3/21.
6 | // Copyright © 2019 Techwis. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | protocol YXYContenViewProtocol:class {
12 | func pageContenViewDidScroll(fromIndex:NSInteger,toIndex:NSInteger)
13 | }
14 |
15 | let pageContentCollectionCell_id = "pageContentCollectionCell_id"
16 |
17 | class YXYPageContentView: UIView {
18 | var subVCArr:Array!
19 | private var parentVC:UIViewController!
20 | private var startOffsetX:CGFloat = 0;
21 | weak var pageContenViewDelegate:YXYContenViewProtocol?
22 |
23 | var contentViewCurrentIndex = 0{
24 | didSet{
25 | if (contentViewCurrentIndex < 0 || contentViewCurrentIndex > subVCArr.count-1) {
26 | return;
27 | }
28 | collectionView.scrollToItem(at: IndexPath(item: contentViewCurrentIndex, section: 0), at: .centeredHorizontally,animated: true)
29 |
30 | // [self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:contentViewCurrentIndex inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
31 | }
32 | }
33 |
34 | lazy var collectionView: UICollectionView = {
35 |
36 | var layout = UICollectionViewFlowLayout()
37 | layout.itemSize = self.bounds.size
38 | layout.minimumInteritemSpacing = 0
39 | layout.minimumLineSpacing = 0
40 | layout.scrollDirection = .horizontal
41 |
42 | let collectionView = UICollectionView(frame: self.bounds, collectionViewLayout: layout)
43 | collectionView.bounces = false;
44 | collectionView.delegate = self
45 | collectionView.dataSource = self
46 | collectionView.isPagingEnabled = true
47 | collectionView.backgroundColor = .white
48 | collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier:pageContentCollectionCell_id )
49 |
50 | return collectionView
51 | }()
52 |
53 | convenience init(frame:CGRect,subVCArr:[PromotionSubVC],parentVC:UIViewController) {
54 | self.init(frame: frame)
55 | self.subVCArr = subVCArr
56 | self.parentVC = parentVC
57 | self.addSubview(self.collectionView)
58 | let _ = subVCArr.map { (vc) -> Void in
59 | self.parentVC.addChild(vc)
60 | }
61 | }
62 | }
63 |
64 | extension YXYPageContentView:UICollectionViewDelegate,UICollectionViewDataSource{
65 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
66 | return subVCArr.count
67 | }
68 |
69 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
70 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: pageContentCollectionCell_id, for: indexPath)
71 | cell.addSubview((self.subVCArr?[indexPath.row].view)!)
72 | return cell
73 |
74 | }
75 |
76 | func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
77 | startOffsetX = scrollView.contentOffset.x;
78 |
79 | }
80 |
81 | func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
82 | let scrollView_W = scrollView.bounds.size.width;
83 | let currentOffsetX = scrollView.contentOffset.x;
84 | let startIndex = floor(startOffsetX/scrollView_W);
85 | let endIndex = floor(currentOffsetX/scrollView_W);
86 | if pageContenViewDelegate != nil {
87 | pageContenViewDelegate!.pageContenViewDidScroll(fromIndex: NSInteger(startIndex), toIndex: NSInteger(endIndex))
88 | }
89 | }
90 | }
91 |
92 |
--------------------------------------------------------------------------------
/TQGO/Tool/ViewTool/YXYPageView/YXYPageView.swift:
--------------------------------------------------------------------------------
1 |
2 | //
3 | // YXYPageView.swift
4 | // TQGO
5 | //
6 | // Created by YXY on 2019/3/21.
7 | // Copyright © 2019 Techwis. All rights reserved.
8 | //
9 | import UIKit
10 |
11 | class YXYPageView: UIView {
12 |
13 | lazy var segmentBarView: UIView = {
14 | let segmentBarView = UIView()
15 | return segmentBarView
16 | }()
17 |
18 | override init(frame: CGRect) {
19 | super.init(frame: frame)
20 |
21 | }
22 |
23 | required init?(coder aDecoder: NSCoder) {
24 | fatalError("init(coder:) has not been implemented")
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/TQGOTests/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 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/TQGOTests/TQGOTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TQGOTests.swift
3 | // TQGOTests
4 | //
5 | // Created by YXY on 2018/7/9.
6 | // Copyright © 2018年 Techwis. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import TQGO
11 |
12 | class TQGOTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 | }
18 |
19 | override func tearDown() {
20 | // Put teardown code here. This method is called after the invocation of each test method in the class.
21 | super.tearDown()
22 | }
23 |
24 | func testExample() {
25 | // This is an example of a functional test case.
26 | // Use XCTAssert and related functions to verify your tests produce the correct results.
27 |
28 | }
29 |
30 | func testPerformanceExample() {
31 | // This is an example of a performance test case.
32 | self.measure {
33 | // Put the code you want to measure the time of here.
34 | }
35 | }
36 |
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/TQGOUITests/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 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/TQGOUITests/TQGOUITests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TQGOUITests.swift
3 | // TQGOUITests
4 | //
5 | // Created by YXY on 2018/7/9.
6 | // Copyright © 2018年 Techwis. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | class TQGOUITests: XCTestCase {
12 |
13 | override func setUp() {
14 | super.setUp()
15 |
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 |
18 | // In UI tests it is usually best to stop immediately when a failure occurs.
19 | continueAfterFailure = false
20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
21 | XCUIApplication().launch()
22 |
23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
24 | }
25 |
26 | override func tearDown() {
27 | // Put teardown code here. This method is called after the invocation of each test method in the class.
28 | super.tearDown()
29 | }
30 |
31 | func testExample() {
32 | // Use recording to get started writing UI tests.
33 | // Use XCTAssert and related functions to verify your tests produce the correct results.
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------