Commit 687a581d authored by 曹云霄's avatar 曹云霄

登陆页、首页、业务、我的、部分界面搭建

parent a3947df5
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## Build generated
build/
DerivedData/
## Various settings
.DS_Store
*/build/*
*.pbxuser
!default.pbxuser
*.mode1v3
......@@ -15,54 +9,15 @@ DerivedData/
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata/
## Other
xcuserdata
profile
*.moved-aside
*.xccheckout
*.xcscmblueprint
## Obj-C/Swift specific
DerivedData
.idea/
*.hmap
*.ipa
*.dSYM.zip
*.dSYM
## Playgrounds
timeline.xctimeline
playground.xcworkspace
# Swift Package Manager
#
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
# Packages/
# Package.pins
# Package.resolved
.build/
# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/
# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts
fastlane/iPA
Carthage/Build
# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/#source-control
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output
#CocoaPods
Pods
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:IFS.xcodeproj">
</FileRef>
</Workspace>
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:IFS.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>
//
// AppDelegate.swift
// IFS
//
// Created by 曹云霄 on 2017/12/20.
// Copyright © 2017年 上海勾芒信息科技有限公司. All rights reserved.
//
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
AppManager.shareInstance.openLoginVc();
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// 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.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// 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.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// 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.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// 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.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}
//
// BaseColletionViewPullController.Swift
// GitHub
//
// Created by 曹云霄 on 2017/12/8.
// Copyright © 2017年 曹云霄. All rights reserved.
//
import UIKit
import MJRefresh
import DZNEmptyDataSet
class BaseColletionViewPullController: BaseViewController {
/// 公共CollectionView
@IBOutlet final weak var collectionView: UICollectionView!
/// 分页下标
final var pullPageIndex: Int = 1
override func viewDidLoad() {
super.viewDidLoad()
setupCollectionView()
setupCollectionViewHeader()
setupCollectionViewFooter()
}
// MARK: - 设置CollectionView
fileprivate final func setupCollectionView() {
collectionView.delegate = self
collectionView.dataSource = self
collectionView.alwaysBounceVertical = true
}
// MARK: - 加载网络数据 需要重载
func loadWebDataSource() {
if collectionView.isEmptyDataSetVisible {
collectionView.reloadEmptyDataSet()
}
}
// MARK: - 添加下拉刷新
func setupCollectionViewHeader() {
let header = MJRefreshNormalHeader(refreshingTarget: self, refreshingAction: #selector(BaseColletionViewPullController.loadCollectionViewHeader))
header?.lastUpdatedTimeLabel.isHidden = true
header?.stateLabel.isHidden = true
header?.stateLabel.textColor = kNavColor
collectionView.mj_header = header
}
// MARK: - 添加上拉加载更多
func setupCollectionViewFooter() {
let footer = MJRefreshAutoNormalFooter.init(refreshingTarget: self, refreshingAction: #selector(BaseColletionViewPullController.loadCollectionViewFooter))
footer?.setTitle("~ 加载更多 ~", for: .idle)
footer?.setTitle("~ 加载中 ~", for: .refreshing)
footer?.setTitle("~ end ~", for: .noMoreData)
footer?.stateLabel.textColor = kNavColor
collectionView.mj_footer = footer
}
// MARK: - 上拉加载回调
@objc func loadCollectionViewFooter() {
setupNotDataDelegate()
pullPageIndex += kONE
loadWebDataSource()
}
// MARK: - 下拉刷新回调
@objc func loadCollectionViewHeader() {
setupNotDataDelegate()
collectionView.mj_footer.resetNoMoreData()
pullPageIndex = kZERO
loadWebDataSource()
}
// MARK: - 设置无数据代理
final func setupNotDataDelegate() {
collectionView.emptyDataSetSource = self
collectionView.emptyDataSetDelegate = self
}
// MARK: - 结束刷新
func endRefresh() {
if collectionView.mj_header.isRefreshing {
collectionView.mj_header.endRefreshing()
}
if collectionView.mj_footer.isRefreshing {
collectionView.mj_footer.endRefreshing()
}
}
// MARK: - 结束刷新切显示无更多的数据
func endRefreshNomoreData() {
collectionView.mj_footer.endRefreshingWithNoMoreData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
extension BaseColletionViewPullController: DZNEmptyDataSetSource,DZNEmptyDataSetDelegate {
func image(forEmptyDataSet scrollView: UIScrollView!) -> UIImage! {
return UIImage(named: "logo-github")
}
func description(forEmptyDataSet scrollView: UIScrollView!) -> NSAttributedString! {
let dict: [NSAttributedStringKey: Any] = [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 15),NSAttributedStringKey.foregroundColor: kNavColor]
let attrString = NSAttributedString(string: "对不起,真的没有数据!", attributes: dict)
return attrString
}
func emptyDataSetShouldAllowScroll(_ scrollView: UIScrollView!) -> Bool {
return true
}
}
extension BaseColletionViewPullController: UICollectionViewDataSource,UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return kONE
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
return UICollectionViewCell()
}
}
//
// BaseModel.swift
// GitHub
//
// Created by 曹云霄 on 2017/12/4.
// Copyright © 2017年 曹云霄. All rights reserved.
//
import UIKit
import HandyJSON
class BaseModel:HandyJSON {
public required init() {}
}
//
// BaseNavigationController.swift
// GitHub
//
// Created by 曹云霄 on 2017/11/29.
// Copyright © 2017年 曹云霄. All rights reserved.
//
import UIKit
class BaseNavigationController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK: - 自定义push方法
override func pushViewController(_ viewController: UIViewController, animated: Bool) {
if childViewControllers.count > 0 {
addBackButtonItem(viewController);
}
super.pushViewController(viewController, animated: animated)
}
// MARK: - 添加返回按钮
fileprivate func addBackButtonItem(_ viewController: UIViewController) {
let backBtn = UIBarButtonItem(image: UIImage(named: "back_icon"), style: .done, target: self, action: #selector(BaseNavigationController.backBtnClick))
viewController.navigationItem.leftBarButtonItem = backBtn
viewController.hidesBottomBarWhenPushed = true
}
//MARK: 默认返回上一层页面
@objc open func backBtnClick() {
popViewController(animated: true)
}
}
//
// BaseTableViewPullController.swift
// GitHub
//
// Created by 曹云霄 on 2017/12/8.
// Copyright © 2017年 曹云霄. All rights reserved.
//
import UIKit
import MJRefresh
import DZNEmptyDataSet
class BaseTableViewPullController: BaseViewController {
/// 公共Tableview
@IBOutlet weak var tableView: UITableView!
/// 分页下标
final var pullPageIndex: Int = kONE
override func viewDidLoad() {
super.viewDidLoad()
setupTableView()
setupTableViewHeader()
setupTableViewFooter()
}
// MARK: - 设置TableView
func setupTableView() {
tableView.delegate = self
tableView.dataSource = self
tableView.tableFooterView = UIView()
tableView.register(UINib(nibName: EmptyTableViewCell.name(), bundle: nil), forCellReuseIdentifier: EmptyTableViewCell.name())
}
// MARK: - 加载网络数据 需要重载
func loadWebDataSource() {
if tableView.isEmptyDataSetVisible {
tableView.reloadEmptyDataSet()
}
}
// MARK: - 添加下拉刷新
func setupTableViewHeader() {
let header = MJRefreshNormalHeader(refreshingTarget: self, refreshingAction: #selector(BaseTableViewPullController.loadTableViewHeader))
header?.lastUpdatedTimeLabel.isHidden = true
header?.stateLabel.isHidden = true
header?.stateLabel.textColor = kNavColor
header?.beginRefreshing()
tableView.mj_header = header
}
// MARK: - 添加上拉加载更多
func setupTableViewFooter() {
let footer = MJRefreshAutoNormalFooter.init(refreshingTarget: self, refreshingAction: #selector(BaseTableViewPullController.loadTableViewFooter))
footer?.setTitle("~ 加载更多 ~", for: .idle)
footer?.setTitle("~ 加载中 ~", for: .refreshing)
footer?.setTitle("~ end ~", for: .noMoreData)
footer?.stateLabel.textColor = kNavColor
tableView.mj_footer = footer
}
// MARK: - 上拉加载回调
@objc func loadTableViewFooter() {
setupNotDataDelegate()
pullPageIndex += kONE
loadWebDataSource()
}
// MARK: - 下拉刷新回调
@objc func loadTableViewHeader() {
setupNotDataDelegate()
tableView.mj_footer.resetNoMoreData()
pullPageIndex = kONE
loadWebDataSource()
}
// MARK: - 设置无数据代理
final func setupNotDataDelegate() {
tableView.emptyDataSetSource = self
tableView.emptyDataSetDelegate = self
}
// MARK: - 结束刷新
func endRefresh() {
if tableView.mj_header.isRefreshing {
tableView.mj_header.endRefreshing()
}
if tableView.mj_footer.isRefreshing {
tableView.mj_footer.endRefreshing()
}
}
// MARK: - 结束刷新切显示无更多的数据
func endRefreshNomoreData() {
endRefresh()
tableView.mj_footer.endRefreshingWithNoMoreData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
extension BaseTableViewPullController: DZNEmptyDataSetSource,DZNEmptyDataSetDelegate {
func image(forEmptyDataSet scrollView: UIScrollView!) -> UIImage! {
return UIImage(named: "logo-github")
}
func description(forEmptyDataSet scrollView: UIScrollView!) -> NSAttributedString! {
let dict: [NSAttributedStringKey: Any] = [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 15),NSAttributedStringKey.foregroundColor: kNavColor]
let attrString = NSAttributedString(string: "对不起,真的没有数据!", attributes: dict)
return attrString
}
func emptyDataSetShouldAllowScroll(_ scrollView: UIScrollView!) -> Bool {
return true
}
}
extension BaseTableViewPullController: UITableViewDataSource,UITableViewDelegate {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return UITableViewCell()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return kONE
}
}
//
// BaseViewController.swift
// GitHub
//
// Created by 曹云霄 on 2017/11/29.
// Copyright © 2017年 曹云霄. All rights reserved.
//
import UIKit
class BaseViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.automaticallyAdjustsScrollViewInsets = false
}
override var prefersStatusBarHidden: Bool {
return false
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return UIStatusBarStyle.lightContent
}
}
//
// BaseViewModel.swift
// GitHub
//
// Created by 曹云霄 on 2017/12/11.
// Copyright © 2017年 曹云霄. All rights reserved.
//
import UIKit
class BaseViewModel: NSObject {
}
//
// UIImage+Category.h
// GitHub
//
// Created by 曹云霄 on 2017/12/6.
// Copyright © 2017年 曹云霄. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIImage (Category)
/**
* 对图片进行模糊
*
* @param image 要处理图片
* @param blur 模糊系数 (0.0-1.0)
*
* @return 处理后的图片
*/
+ (UIImage *)blurryImage:(UIImage *)image withBlurLevel:(CGFloat)blur;
@end
//
// UIImage+Category.m
// GitHub
//
// Created by 曹云霄 on 2017/12/6.
// Copyright © 2017年 曹云霄. All rights reserved.
//
#import "UIImage+Category.h"
#import <Accelerate/Accelerate.h>
@implementation UIImage (Category)
/**
* 对图片进行模糊
*
* @param image 要处理图片
* @param blur 模糊系数 (0.0-1.0)
*
* @return 处理后的图片
*/
+ (UIImage *)blurryImage:(UIImage *)image withBlurLevel:(CGFloat)blur {
if (!image) {
return nil;
}
if ((blur < 0.0f) || (blur > 1.0f)) {
blur = 0.5f;
}
int boxSize = (int)(blur * 200);
boxSize -= (boxSize % 2) + 1;
CGImageRef img = image.CGImage;
vImage_Buffer inBuffer, outBuffer;
vImage_Error error;
void *pixelBuffer;
CGDataProviderRef inProvider = CGImageGetDataProvider(img);
CFDataRef inBitmapData = CGDataProviderCopyData(inProvider);
inBuffer.width = CGImageGetWidth(img);
inBuffer.height = CGImageGetHeight(img);
inBuffer.rowBytes = CGImageGetBytesPerRow(img);
inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData);
pixelBuffer = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img));
outBuffer.data = pixelBuffer;
outBuffer.width = CGImageGetWidth(img);
outBuffer.height = CGImageGetHeight(img);
outBuffer.rowBytes = CGImageGetBytesPerRow(img);
error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, NULL,
0, 0, boxSize, boxSize, NULL,
kvImageEdgeExtend);
if (error) {
NSLog(@"error from convolution %ld", error);
}
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef ctx = CGBitmapContextCreate(
outBuffer.data,
outBuffer.width,
outBuffer.height,
8,
outBuffer.rowBytes,
colorSpace,
CGImageGetBitmapInfo(image.CGImage));
CGImageRef imageRef = CGBitmapContextCreateImage (ctx);
UIImage *returnImage = [UIImage imageWithCGImage:imageRef];
//clean up
CGContextRelease(ctx);
CGColorSpaceRelease(colorSpace);
free(pixelBuffer);
CFRelease(inBitmapData);
CGColorSpaceRelease(colorSpace);
CGImageRelease(imageRef);
return returnImage;
}
@end
//
// ConstKey.swift
// GitHub
//
// Created by 曹云霄 on 2017/12/1.
// Copyright © 2017年 曹云霄. All rights reserved.
//
import Foundation
//
// Enums.swift
// GitHub
//
// Created by 曹云霄 on 2017/11/29.
// Copyright © 2017年 曹云霄. All rights reserved.
//
import Foundation
//
// Notification.swift
// GitHub
//
// Created by 曹云霄 on 2017/11/29.
// Copyright © 2017年 曹云霄. All rights reserved.
//
import Foundation
//
// Public.swift
// GitHub
//
// Created by 曹云霄 on 2017/11/29.
// Copyright © 2017年 曹云霄. All rights reserved.
//
import Foundation
import UIKit
import RxSwift
// MARK: - 常用颜色
public var kNavColor: UIColor = UIColor.RGB(44, g: 48, b: 52)
public let kMainColor: UIColor = UIColor.RGB(67, g: 132, b: 196)
public let kBlueColor: UIColor = UIColor.RGB(77, g: 131, b: 242)
public let kGaryColor: UIColor = UIColor.RGB(240, g: 240, b: 240)
// MARK: - 全局常用属性
public let kNavHeight: CGFloat = 64
public let kCellHeight: CGFloat = 44
public let kTabBarHeight: CGFloat = 49
public let kROWS: Int = 15
public let kONE: Int = 1
public let kZERO: Int = 0
public let kEmptyHeight: CGFloat = 108
public let kWidth: CGFloat = UIScreen.main.bounds.size.width
public let kHeight: CGFloat = UIScreen.main.bounds.size.height
public let kWindow: UIWindow = ((UIApplication.shared.delegate?.window)!)!
//
// Urls.swift
// GitHub
//
// Created by 曹云霄 on 2017/11/29.
// Copyright © 2017年 曹云霄. All rights reserved.
//
import Foundation
//
// UIView+Extension.swift
// Tool_Swift
//
// Created by 曹云霄 on 2017/2/17.
// Copyright © 2017年 曹云霄. All rights reserved.
import UIKit
extension UIColor {
class func RGB(_ r: CGFloat, g:CGFloat, b:CGFloat) -> UIColor {
return UIColor(red: r / 255.0, green: g / 255.0, blue: b / 255.0, alpha: 1)
}
class func randomColor() -> UIColor {
let r = CGFloat(arc4random_uniform(256))
let g = CGFloat(arc4random_uniform(256))
let b = CGFloat(arc4random_uniform(256))
return UIColor.RGB(r, g: g, b: b)
}
}
//
// DateExtensions.swift
// EZSwiftExtensions
//
// Created by Goktug Yilmaz on 15/07/15.
// Copyright (c) 2015 Goktug Yilmaz. All rights reserved.
//
import Foundation
extension Date {
public static let minutesInAWeek = 24 * 60 * 7
/// EZSE: Initializes Date from string and format
public init?(fromString string: String,
format: String,
timezone: TimeZone = TimeZone.autoupdatingCurrent,
locale: Locale = Locale.current) {
let formatter = DateFormatter()
formatter.timeZone = timezone
formatter.locale = locale
formatter.dateFormat = format
if let date = formatter.date(from: string) {
self = date
} else {
return nil
}
}
/// EZSE: Initializes Date from string returned from an http response, according to several RFCs / ISO
public init?(httpDateString: String) {
if let rfc1123 = Date(fromString: httpDateString, format: "EEE',' dd' 'MMM' 'yyyy HH':'mm':'ss zzz") {
self = rfc1123
return
}
if let rfc850 = Date(fromString: httpDateString, format: "EEEE',' dd'-'MMM'-'yy HH':'mm':'ss z") {
self = rfc850
return
}
if let asctime = Date(fromString: httpDateString, format: "EEE MMM d HH':'mm':'ss yyyy") {
self = asctime
return
}
if let iso8601DateOnly = Date(fromString: httpDateString, format: "yyyy-MM-dd") {
self = iso8601DateOnly
return
}
if let iso8601DateHrMinOnly = Date(fromString: httpDateString, format: "yyyy-MM-dd'T'HH:mmxxxxx") {
self = iso8601DateHrMinOnly
return
}
if let iso8601DateHrMinSecOnly = Date(fromString: httpDateString, format: "yyyy-MM-dd'T'HH:mm:ssxxxxx") {
self = iso8601DateHrMinSecOnly
return
}
if let iso8601DateHrMinSecMs = Date(fromString: httpDateString, format: "yyyy-MM-dd'T'HH:mm:ss.SSSxxxxx") {
self = iso8601DateHrMinSecMs
return
}
//self.init()
return nil
}
/// EZSE: Converts Date to String
public func toString(dateStyle: DateFormatter.Style = .medium, timeStyle: DateFormatter.Style = .medium) -> String {
let formatter = DateFormatter()
formatter.dateStyle = dateStyle
formatter.timeStyle = timeStyle
return formatter.string(from: self)
}
/// EZSE: Converts Date to String, with format
public func toString(format: String) -> String {
let formatter = DateFormatter()
formatter.dateFormat = format
return formatter.string(from: self)
}
/// EZSE: Calculates how many days passed from now to date
public func daysInBetweenDate(_ date: Date) -> Double {
var diff = self.timeIntervalSince1970 - date.timeIntervalSince1970
diff = fabs(diff/86400)
return diff
}
/// EZSE: Calculates how many hours passed from now to date
public func hoursInBetweenDate(_ date: Date) -> Double {
var diff = self.timeIntervalSince1970 - date.timeIntervalSince1970
diff = fabs(diff/3600)
return diff
}
/// EZSE: Calculates how many minutes passed from now to date
public func minutesInBetweenDate(_ date: Date) -> Double {
var diff = self.timeIntervalSince1970 - date.timeIntervalSince1970
diff = fabs(diff/60)
return diff
}
/// EZSE: Calculates how many seconds passed from now to date
public func secondsInBetweenDate(_ date: Date) -> Double {
var diff = self.timeIntervalSince1970 - date.timeIntervalSince1970
diff = fabs(diff)
return diff
}
/// EZSE: Easy creation of time passed String. Can be Years, Months, days, hours, minutes or seconds
public func timePassed() -> String {
let date = Date()
let calendar = Calendar.autoupdatingCurrent
let components = (calendar as NSCalendar).components([.year, .month, .day, .hour, .minute, .second], from: self, to: date, options: [])
var str: String
if components.year! >= 1 {
components.year == 1 ? (str = "year") : (str = "years")
return "\(components.year!) \(str) ago"
} else if components.month! >= 1 {
components.month == 1 ? (str = "month") : (str = "months")
return "\(components.month!) \(str) ago"
} else if components.day! >= 1 {
components.day == 1 ? (str = "day") : (str = "days")
return "\(components.day!) \(str) ago"
} else if components.hour! >= 1 {
components.hour == 1 ? (str = "hour") : (str = "hours")
return "\(components.hour!) \(str) ago"
} else if components.minute! >= 1 {
components.minute == 1 ? (str = "minute") : (str = "minutes")
return "\(components.minute!) \(str) ago"
} else if components.second! >= 1 {
components.second == 1 ? (str = "second") : (str = "seconds")
return "\(components.second!) \(str) ago"
} else {
return "Just now"
}
}
/// EZSE: Check if date is in future.
public var isFuture: Bool {
return self > Date()
}
/// EZSE: Check if date is in past.
public var isPast: Bool {
return self < Date()
}
// EZSE: Check date if it is today
public var isToday: Bool {
let format = DateFormatter()
format.dateFormat = "yyyy-MM-dd"
return format.string(from: self) == format.string(from: Date())
}
/// EZSE: Check date if it is yesterday
public var isYesterday: Bool {
let format = DateFormatter()
format.dateFormat = "yyyy-MM-dd"
let yesterDay = Calendar.current.date(byAdding: .day, value: -1, to: Date())
return format.string(from: self) == format.string(from: yesterDay!)
}
/// EZSE: Check date if it is tomorrow
public var isTomorrow: Bool {
let format = DateFormatter()
format.dateFormat = "yyyy-MM-dd"
let tomorrow = Calendar.current.date(byAdding: .day, value: 1, to: Date())
return format.string(from: self) == format.string(from: tomorrow!)
}
/// EZSE: Check date if it is within this month.
public var isThisMonth: Bool {
let today = Date()
return self.month == today.month && self.year == today.year
}
/// EZSE: Check date if it is within this week.
public var isThisWeek: Bool {
return self.minutesInBetweenDate(Date()) <= Double(Date.minutesInAWeek)
}
/// EZSE: Get the era from the date
public var era: Int {
return Calendar.current.component(Calendar.Component.era, from: self)
}
/// EZSE : Get the year from the date
public var year: Int {
return Calendar.current.component(Calendar.Component.year, from: self)
}
/// EZSE : Get the month from the date
public var month: Int {
return Calendar.current.component(Calendar.Component.month, from: self)
}
/// EZSE : Get the weekday from the date
public var weekday: String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEEE"
return dateFormatter.string(from: self)
}
// EZSE : Get the month from the date
public var monthAsString: String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMMM"
return dateFormatter.string(from: self)
}
// EZSE : Get the day from the date
public var day: Int {
return Calendar.current.component(.day, from: self)
}
/// EZSE: Get the hours from date
public var hour: Int {
return Calendar.current.component(.hour, from: self)
}
/// EZSE: Get the minute from date
public var minute: Int {
return Calendar.current.component(.minute, from: self)
}
/// EZSE: Get the second from the date
public var second: Int {
return Calendar.current.component(.second, from: self)
}
/// EZSE : Gets the nano second from the date
public var nanosecond: Int {
return Calendar.current.component(.nanosecond, from: self)
}
#if os(iOS) || os(tvOS)
/// EZSE : Gets the international standard(ISO8601) representation of date
@available(iOS 10.0, *)
@available(tvOS 10.0, *)
public var iso8601: String {
let formatter = ISO8601DateFormatter()
return formatter.string(from: self)
}
#endif
}
//
// String+Extension.swift
// CStoreEdu-iOS
//
// Created by 曹云霄 on 2017/3/21.
// Copyright © 2017年 上海勾芒信息科技有限公司. All rights reserved.
//
import UIKit
extension NSString {
// 计算字符串的宽度,高度
open func calculateStringSize(_ size: CGSize,font: UIFont) ->CGSize {
let attributes = [NSAttributedStringKey.font:font]
let option = NSStringDrawingOptions.usesLineFragmentOrigin
let rect:CGRect = self.boundingRect(with:CGSize(width: kWidth, height: kHeight) , options: option, attributes: attributes, context: nil)
return rect.size
}
// 去掉字符串前后空格
open func formatString() -> String {
let set = NSCharacterSet.whitespacesAndNewlines
return self.trimmingCharacters(in: set)
}
// MARK: - 富文本设置颜色
open func attributeString(_ colorString: String,_ color: UIColor) ->NSMutableAttributedString {
let range = self.range(of: colorString)
//富文本设置
let attributeString = NSMutableAttributedString(string:self as String)
//设置字体颜色
attributeString.addAttribute(NSAttributedStringKey.foregroundColor, value: color,range: range)
return attributeString
}
// MARK: - 带¥符号字符串
open func priceString() -> String {
return String(format: "¥%.2f", self.floatValue)
}
// MARK: - 获取路径文件大小
open func getFileSize() -> UInt64 {
var size: UInt64 = 0
let fileManager = FileManager.default
var isDir: ObjCBool = false
let isExists = fileManager.fileExists(atPath: self as String, isDirectory: &isDir)
// 判断文件存在
if isExists {
// 是否为文件夹
if isDir.boolValue {
// 迭代器 存放文件夹下的所有文件名
let enumerator = fileManager.enumerator(atPath: self as String)
for subPath in enumerator! {
// 获得全路径
let fullPath = self.appending("/\(subPath)")
do {
let attr = try fileManager.attributesOfItem(atPath: fullPath)
size += attr[FileAttributeKey.size] as! UInt64
} catch {
print("error :\(error)")
}
}
} else { // 单文件
do {
let attr = try fileManager.attributesOfItem(atPath: self as String)
size += attr[FileAttributeKey.size] as! UInt64
} catch {
print("error :\(error)")
}
}
}
return size
}
}
//
// UIDevice+Extension.swift
// Opple_iPhone_iOS
//
// Created by 曹云霄 on 2017/6/19.
// Copyright © 2017年 上海勾芒科技信息有限公司. All rights reserved.
//
import Foundation
import UIKit
//MARK: - UIDevice延展
public extension UIDevice {
/// 获取设备系统版本
var modelVersion: String {
return UIDevice.current.systemVersion
}
/// 获取设备名称
var modelName: String {
var systemInfo = utsname()
uname(&systemInfo)
let machineMirror = Mirror(reflecting: systemInfo.machine)
let identifier = machineMirror.children.reduce("") { identifier, element in
guard let value = element.value as? Int8, value != 0 else { return identifier }
return identifier + String(UnicodeScalar(UInt8(value)))
}
switch identifier {
case "iPod5,1": return "iPod Touch 5"
case "iPod7,1": return "iPod Touch 6"
case "iPhone3,1", "iPhone3,2", "iPhone3,3": return "iPhone 4"
case "iPhone4,1": return "iPhone 4s"
case "iPhone5,1", "iPhone5,2": return "iPhone 5"
case "iPhone5,3", "iPhone5,4": return "iPhone 5c"
case "iPhone6,1", "iPhone6,2": return "iPhone 5s"
case "iPhone7,2": return "iPhone 6"
case "iPhone7,1": return "iPhone 6 Plus"
case "iPhone8,1": return "iPhone 6s"
case "iPhone8,2": return "iPhone 6s Plus"
case "iPhone8,4": return "iPhone SE"
case "iPhone9,1": return "iPhone 7"
case "iPhone9,2": return "iPhone 7 Plus"
case "iPad2,1", "iPad2,2", "iPad2,3", "iPad2,4":return "iPad 2"
case "iPad3,1", "iPad3,2", "iPad3,3": return "iPad 3"
case "iPad3,4", "iPad3,5", "iPad3,6": return "iPad 4"
case "iPad4,1", "iPad4,2", "iPad4,3": return "iPad Air"
case "iPad5,3", "iPad5,4": return "iPad Air 2"
case "iPad2,5", "iPad2,6", "iPad2,7": return "iPad Mini"
case "iPad4,4", "iPad4,5", "iPad4,6": return "iPad Mini 2"
case "iPad4,7", "iPad4,8", "iPad4,9": return "iPad Mini 3"
case "iPad5,1", "iPad5,2": return "iPad Mini 4"
case "iPad6,7", "iPad6,8": return "iPad Pro"
case "AppleTV5,3": return "Apple TV"
case "i386", "x86_64": return "Simulator"
default: return identifier
}
}
}
//
// UIImage+Extension.swift
// GitHub
//
// Created by 曹云霄 on 2017/12/6.
// Copyright © 2017年 曹云霄. All rights reserved.
//
import Foundation
import UIKit
import Accelerate
//
// UIView+Extension.swift
// Tool_Swift
//
// Created by 曹云霄 on 2017/2/17.
// Copyright © 2017年 曹云霄. All rights reserved.
//
import UIKit
/// 对UIView的扩展
extension UIView {
/// X值
var X: CGFloat {
return self.frame.origin.x
}
/// Y值
var Y: CGFloat {
return self.frame.origin.y
}
/// 宽度
var width: CGFloat {
return self.frame.size.width
}
///高度
var height: CGFloat {
return self.frame.size.height
}
var size: CGSize {
return self.frame.size
}
var point: CGPoint {
return self.frame.origin
}
/// 添加圆角
func addAngle(_ cornerRadius:CGFloat) {
self.layer.masksToBounds = true
self.layer.cornerRadius = cornerRadius
}
/// 添加边框
func addBorder(_ border: CGFloat, _ color: UIColor) {
self.layer.borderWidth = border
self.layer.borderColor = color.cgColor
}
/// 添加阴影
func addShadow(_ color: UIColor) {
layer.shadowOpacity = Float(0.3)
layer.shadowColor = color.cgColor
layer.shadowOffset = CGSize(width: 0, height: 0)
layer.shadowRadius = 5
}
/// 设置X
func setx(x: CGFloat) {
self.frame = CGRect(x: x, y: self.Y, width: self.width, height: self.height)
}
/// 设置Y
func sety(y: CGFloat) {
self.frame = CGRect(x: self.X, y: y, width: self.width, height: self.height)
}
/// 设置W
func setw(w: CGFloat) {
self.frame = CGRect(x: self.X, y: self.Y, width: w, height: self.height)
}
/// 设置H
func seth(h: CGFloat) {
self.frame = CGRect(x: self.X, y: self.Y, width: self.width, height: h)
}
/// 返回UIView名字
class func name() ->String {
return "\(self)"
}
}
// MARK: - xib初始化
extension UIView {
public class func instantiateFromNib() -> UIView {
return Bundle.main.loadNibNamed(name(), owner: nil, options: nil)?.first as! UIView
}
}
/// 扩展storyboard
@IBDesignable
class CustomView: UIView {
//边框颜色
@IBInspectable var borderColor: UIColor = UIColor() {
didSet{
layer.borderColor = borderColor.cgColor
}
}
//边框距离
@IBInspectable var borderWindth: CGFloat = 0.0 {
didSet {
layer.borderWidth = borderWindth
}
}
//角度
@IBInspectable var cornerRadius: CGFloat = 0.0 {
didSet {
layer.masksToBounds = true
layer.cornerRadius = cornerRadius
}
}
//阴影颜色
@IBInspectable var shadowOpacity: CGFloat = 0.0 {
didSet {
layer.shadowOpacity = Float(shadowOpacity)
layer.shadowColor = UIColor.black.cgColor
layer.shadowOffset = CGSize(width: 0, height: 0)
}
}
//阴影大小
@IBInspectable var shadowRadius: CGFloat = 0.0 {
didSet {
layer.shadowRadius = shadowRadius
}
}
}
/// 扩展storyboard
@IBDesignable
class CustomButton: UIButton {
//边框颜色
@IBInspectable var borderColor: UIColor = UIColor() {
didSet{
layer.borderColor = borderColor.cgColor
}
}
//边框距离
@IBInspectable var borderWindth: CGFloat = 0.0 {
didSet {
layer.borderWidth = borderWindth
}
}
//角度
@IBInspectable var cornerRadius: CGFloat = 0.0 {
didSet {
layer.masksToBounds = true
layer.cornerRadius = cornerRadius
}
}
//阴影颜色
@IBInspectable var shadowOpacity: CGFloat = 0.0 {
didSet {
layer.shadowOpacity = Float(shadowOpacity)
layer.shadowColor = UIColor.black.cgColor
layer.shadowOffset = CGSize.init(width: 0, height: 0)
}
}
//阴影大小
@IBInspectable var shadowRadius: CGFloat = 0.0 {
didSet {
layer.shadowRadius = shadowRadius
}
}
override var isHighlighted: Bool {
set{
}
get {
return false
}
}
}
/// 扩展storyboard
@IBDesignable
class CustomImageView: UIImageView {
//边框颜色
@IBInspectable var borderColor: UIColor = UIColor() {
didSet{
layer.borderColor = borderColor.cgColor
}
}
//边框距离
@IBInspectable var borderWindth: CGFloat = 0.0 {
didSet {
layer.borderWidth = borderWindth
}
}
//角度
@IBInspectable var cornerRadius: CGFloat = 0.0 {
didSet {
layer.masksToBounds = true
layer.cornerRadius = cornerRadius
}
}
//阴影颜色
@IBInspectable var shadowOpacity: CGFloat = 0.0 {
didSet {
layer.shadowOpacity = Float(shadowOpacity)
layer.shadowColor = UIColor.black.cgColor
layer.shadowOffset = CGSize.init(width: 0, height: 0)
}
}
//阴影大小
@IBInspectable var shadowRadius: CGFloat = 0.0 {
didSet {
layer.shadowRadius = shadowRadius
}
}
}
/// 扩展storyboard
@IBDesignable
class CustomTextView: UITextView {
//边框颜色
@IBInspectable var borderColor: UIColor = UIColor() {
didSet{
layer.borderColor = borderColor.cgColor
}
}
//边框距离
@IBInspectable var borderWindth: CGFloat = 0.0 {
didSet {
layer.borderWidth = borderWindth
}
}
//角度
@IBInspectable var cornerRadius: CGFloat = 0.0 {
didSet {
layer.masksToBounds = true
layer.cornerRadius = cornerRadius
}
}
//阴影颜色
@IBInspectable var shadowOpacity: CGFloat = 0.0 {
didSet {
layer.shadowOpacity = Float(shadowOpacity)
layer.shadowColor = UIColor.black.cgColor
layer.shadowOffset = CGSize.init(width: 0, height: 0)
}
}
//阴影大小
@IBInspectable var shadowRadius: CGFloat = 0.0 {
didSet {
layer.shadowRadius = shadowRadius
}
}
}
class CustomLabel: UILabel {
//添加下划线
func addUnderline(_ text: String,color: UIColor) {
let string = NSMutableAttributedString(string: text)
let range1 = NSRange(location: 0, length: string.length)
let number = NSNumber(value:NSUnderlineStyle.styleSingle.rawValue)//此处需要转换为NSNumber 不然不对,rawValue转换为integer
string.addAttribute(NSAttributedStringKey.underlineStyle, value: number, range: range1)
string.addAttribute(NSAttributedStringKey.foregroundColor, value: color, range: range1)
self.attributedText = string
}
}
//
// UIViewController+Extension.swift
// CStoreEdu-iOS
//
// Created by 曹云霄 on 2017/3/10.
// Copyright © 2017年 上海勾芒信息科技有限公司. All rights reserved.
//
import Foundation
import UIKit
public enum StoryboardType: String {
case Main = "Main"
case Home = "Home"
case Function = "Function"
case Me = "Me"
}
extension UIViewController {
// MARK: -返回storyboard对象
class func instantiateViewController(_ storyBoardName: StoryboardType) -> UIViewController {
let storyBoard = UIStoryboard(name: storyBoardName.rawValue, bundle: nil)
return storyBoard.instantiateViewController(withIdentifier: "\(self)")
}
// MARK: -返回控制器名称
class func name() -> String {
return "\(self)"
}
}
//
// UIViewControllerExtensions.swift
// EZSwiftExtensions
//
// Created by Goktug Yilmaz on 15/07/15.
// Copyright (c) 2015 Goktug Yilmaz. All rights reserved.
#if os(iOS) || os(tvOS)
import UIKit
import SnapKit
extension UIViewController {
// MARK: - 添加搜索框到导航栏
open func addSearchBarToNav() ->UISearchBar {
let searchBar = UISearchBar()
searchBar.barStyle = .black
searchBar.placeholder = "请输入关键字"
navigationItem.titleView = searchBar
return searchBar
}
///EZSE: Pushes a view controller onto the receiver’s stack and updates the display.
open func pushVC(_ vc: UIViewController) {
navigationController?.pushViewController(vc, animated: true)
}
///EZSE: Pops the top view controller from the navigation stack and updates the display.
open func popVC() {
_ = navigationController?.popViewController(animated: true)
}
/// EZSE: Hide or show navigation bar
public var isNavBarHidden: Bool {
get {
return (navigationController?.isNavigationBarHidden)!
}
set {
navigationController?.isNavigationBarHidden = newValue
}
}
/// EZSE: Added extension for popToRootViewController
open func popToRootVC() {
_ = navigationController?.popToRootViewController(animated: true)
}
///EZSE: Presents a view controller modally.
open func presentVC(_ vc: UIViewController) {
present(vc, animated: true, completion: nil)
}
/// 显示加载中
open func startLoading() {
let titleView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 40))
navigationItem.titleView = titleView
let loadingLabel = UILabel()
loadingLabel.text = "加载中..."
loadingLabel.textColor = UIColor.white
loadingLabel.textAlignment = .center
loadingLabel.font = UIFont.boldSystemFont(ofSize: 16)
titleView.addSubview(loadingLabel)
loadingLabel.snp.makeConstraints({ (make) in
make.center.equalTo(titleView.snp.center)
})
let loadingView = UIActivityIndicatorView(activityIndicatorStyle: .white)
loadingView.startAnimating()
titleView.addSubview(loadingView)
loadingView.snp.makeConstraints({ (make) in
make.centerX.equalTo(titleView.snp.centerX).offset(-50)
make.centerY.equalTo(titleView.snp.centerY)
make.size.equalTo(CGSize(width: 30, height: 30))
})
}
// MARK: - 停止加载中
open func stopLoading() {
self.navigationItem.titleView = nil
}
}
#endif
//
// Network.swift
// GitHub
//
// Created by 曹云霄 on 2017/12/5.
// Copyright © 2017年 曹云霄. All rights reserved.
//
import Moya
import SwiftyJSON
import YXAlertController
struct Network {
// // 请求头
// static let publicParamEndpointClosure = { (target: Service) -> Endpoint<Service> in
// let url = target.baseURL.appendingPathComponent(target.path).absoluteString
// let endpoint = Endpoint<Service>(url: url, sampleResponseClosure: { .networkResponse(200, target.sampleData) }, method: target.method, task: target.task, httpHeaderFields: target.headers)
//// if let access_token = AppManager.shareInstance.user_Token {
//// return endpoint.adding(newHTTPHeaderFields: ["access_token" : access_token, "x-interface-version" : "1.0"])
//// }else {
// return endpoint
//// }
// }
//
// // 设置超时时间
// static let myRequestClosure = {(endpoint: Endpoint<Service>, closure: MoyaProvider<Service>.RequestResultClosure) -> Void in
// do {
// var urlRequest = try endpoint.urlRequest()
// urlRequest.timeoutInterval = 30
// closure(.success(urlRequest))
// } catch {
// closure(.failure(MoyaError.requestMapping(endpoint.url)))
// }
// }
//
// // 监听请求状态
// static let myNetworkActivityPlugin = NetworkActivityPlugin { (type,target) in
// switch type {
// case .began:
// ShowLoadingView(kWindow)
// UIApplication.shared.isNetworkActivityIndicatorVisible = true
// case .ended:
// HideLoadingView(kWindow)
// UIApplication.shared.isNetworkActivityIndicatorVisible = false
// }
// }
//
// // 公告请求对象
// static let provider = MoyaProvider<Service>(endpointClosure: publicParamEndpointClosure,requestClosure: myRequestClosure,plugins: [myNetworkActivityPlugin])
//
// // MARK: -取消所有请求
// static func cancelAllRequest() {
// provider.manager.session.invalidateAndCancel()
// }
//
// /// 公共请求方法
// ///
// /// - Parameters:
// /// - target: 请求方法
// /// - success: 请求成功
// /// - error: 请求失败
// static func request(target: Service, success: @escaping (JSON) -> Void, failure: @escaping (MoyaError) -> Void) {
// provider.request(target) { result in
// switch result {
// /// 请求成功后先通过json解析数据,如果解析失败使用jsonString重试一次
// case let .success(response):
// do {
// //请求失败
// guard response.statusCode != 404 else {
// failure(MoyaError.statusCode(response))
// return
// }
// //需要重新登录
// guard response.statusCode != 401 else {
// ShowAlertView("提示", "身份凭证已过期,需要重新登录!", ["我知道了"], .alert, { (index) in
//// AppManager.shareInstance.deleteToken();
//// AppManager.shareInstance.openLoginVc();
// })
// return
// }
// let json = try response.mapJSON()
// success(JSON(json))
// } catch {
// switch (error) {
// case MoyaError.jsonMapping(response):
// do {
// let jsonString = try response.mapString()
// success(JSON(jsonString))
// }catch {
// failure(error as! MoyaError)
// }
// default:
// failure(error as! MoyaError)
// break
// }
// }
// break
// case let .failure(error):
// failure(error)
// break
// }
// }
// }
}
//
// NetworkAPI.swift
// GitHub
//
// Created by 曹云霄 on 2017/11/30.
// Copyright © 2017年 曹云霄. All rights reserved.
//
import Foundation
public enum Service {
}
//
// EmptyTableViewCell.swift
// GitHub
//
// Created by 曹云霄 on 2017/12/11.
// Copyright © 2017年 曹云霄. All rights reserved.
//
import UIKit
class EmptyTableViewCell: UITableViewCell {
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13527"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" rowHeight="108" id="KGk-i7-Jjw" customClass="EmptyTableViewCell" customModule="GitHub" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="320" height="104"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
<rect key="frame" x="0.0" y="0.0" width="320" height="103.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="xd9-bc-yVS">
<rect key="frame" x="15" y="10" width="40" height="40"/>
<color key="backgroundColor" red="0.94117647058823528" green="0.94117647058823528" blue="0.94117647058823528" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="height" constant="40" id="prK-YL-gZp"/>
<constraint firstAttribute="width" constant="40" id="xwm-Er-nF8"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="nto-4N-3xi">
<rect key="frame" x="65" y="10" width="245" height="17"/>
<color key="backgroundColor" red="0.94117647059999998" green="0.94117647059999998" blue="0.94117647059999998" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="height" constant="17" id="tJR-tC-SKe"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Fw9-Dr-SCI">
<rect key="frame" x="65" y="32" width="205" height="17"/>
<color key="backgroundColor" red="0.94117647059999998" green="0.94117647059999998" blue="0.94117647059999998" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="height" constant="17" id="wMM-3K-Buf"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="1QC-km-eyU">
<rect key="frame" x="65" y="54" width="245" height="17"/>
<color key="backgroundColor" red="0.94117647059999998" green="0.94117647059999998" blue="0.94117647059999998" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="height" constant="17" id="tHZ-mV-Dr6"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="30l-ro-2VO">
<rect key="frame" x="65" y="76" width="50" height="17"/>
<color key="backgroundColor" red="0.94117647059999998" green="0.94117647059999998" blue="0.94117647059999998" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="height" constant="17" id="UWB-cn-HUN"/>
<constraint firstAttribute="width" constant="50" id="vip-MV-c4A"/>
</constraints>
</view>
</subviews>
<constraints>
<constraint firstItem="nto-4N-3xi" firstAttribute="top" secondItem="xd9-bc-yVS" secondAttribute="top" id="1ee-Uc-bDX"/>
<constraint firstItem="30l-ro-2VO" firstAttribute="leading" secondItem="1QC-km-eyU" secondAttribute="leading" id="89J-29-Jkv"/>
<constraint firstItem="Fw9-Dr-SCI" firstAttribute="leading" secondItem="nto-4N-3xi" secondAttribute="leading" id="B05-kb-iYv"/>
<constraint firstItem="Fw9-Dr-SCI" firstAttribute="top" secondItem="nto-4N-3xi" secondAttribute="bottom" constant="5" id="FHe-43-jpP"/>
<constraint firstAttribute="trailing" secondItem="Fw9-Dr-SCI" secondAttribute="trailing" constant="50" id="NLW-P7-hZR"/>
<constraint firstItem="nto-4N-3xi" firstAttribute="leading" secondItem="xd9-bc-yVS" secondAttribute="trailing" constant="10" id="Sew-xn-zTt"/>
<constraint firstAttribute="trailing" secondItem="nto-4N-3xi" secondAttribute="trailing" constant="10" id="aYX-je-JL8"/>
<constraint firstItem="1QC-km-eyU" firstAttribute="top" secondItem="Fw9-Dr-SCI" secondAttribute="bottom" constant="5" id="cML-u7-nQ7"/>
<constraint firstItem="xd9-bc-yVS" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="10" id="d35-q4-qVu"/>
<constraint firstItem="1QC-km-eyU" firstAttribute="leading" secondItem="Fw9-Dr-SCI" secondAttribute="leading" id="dSw-uA-pft"/>
<constraint firstItem="30l-ro-2VO" firstAttribute="top" secondItem="1QC-km-eyU" secondAttribute="bottom" constant="5" id="ffV-h0-XkJ"/>
<constraint firstAttribute="trailing" secondItem="1QC-km-eyU" secondAttribute="trailing" constant="10" id="mdU-bb-Eae"/>
<constraint firstItem="xd9-bc-yVS" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="15" id="teV-8o-nYX"/>
</constraints>
</tableViewCellContentView>
<viewLayoutGuide key="safeArea" id="njF-e1-oar"/>
<point key="canvasLocation" x="-119" y="-65"/>
</tableViewCell>
</objects>
</document>
//
// V2FPSLabel.swift
// V2ex-Swift
//
// Created by huangfeng on 1/15/16.
// Copyright © 2016 Fin. All rights reserved.
//
import UIKit
//重写自 YYFPSLabel
//https://github.com/ibireme/YYText/blob/master/Demo/YYTextDemo/YYFPSLabel.m
class V2FPSLabel: UILabel {
fileprivate var _link :CADisplayLink?
fileprivate var _count:Int = 0
fileprivate var _lastTime:TimeInterval = 0
fileprivate let _defaultSize = CGSize(width: 55, height: 20);
override init(frame: CGRect) {
var targetFrame = frame
if frame.size.width == 0 && frame.size.height == 0{
targetFrame.size = _defaultSize
}
super.init(frame: targetFrame)
self.layer.cornerRadius = 5
self.clipsToBounds = true
self.textAlignment = .center
self.isUserInteractionEnabled = false
self.textColor = UIColor.white
self.backgroundColor = UIColor(white: 0, alpha: 0.7)
self.font = UIFont(name: "Menlo", size: 14)
weak var weakSelf = self
_link = CADisplayLink(target: weakSelf!, selector:#selector(V2FPSLabel.tick(_:)) );
_link!.add(to: RunLoop.main, forMode:RunLoopMode.commonModes)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
@objc func tick(_ link:CADisplayLink) {
if _lastTime == 0 {
_lastTime = link.timestamp
return
}
_count += 1
let delta = link.timestamp - _lastTime
if delta < 1 {
return
}
_lastTime = link.timestamp
let fps = Double(_count) / delta
_count = 0
let progress = fps / 60.0;
self.textColor = UIColor(hue: CGFloat(0.27 * ( progress - 0.2 )) , saturation: 1, brightness: 0.9, alpha: 1)
self.text = "\(Int(fps+0.5))FPS"
}
}
//
// WebViewController.swift
// GitHub
//
// Created by 曹云霄 on 2017/12/1.
// Copyright © 2017年 曹云霄. All rights reserved.
//
import UIKit
import WebKit
import SnapKit
import RxSwift
/// 获取用户token使用
protocol LoginDelegate {
func getTokenByCode(code: String)
}
class WebViewController: BaseViewController {
var delegate: LoginDelegate?
// MARK: - WKWebView
fileprivate final lazy var webView: WKWebView = {
let webView = WKWebView()
webView.navigationDelegate = self
webView.uiDelegate = self
return webView
}()
fileprivate final var htmlResuest: URLRequest!
final let progress: String = "estimatedProgress"
// MARK: - 进度条
fileprivate final lazy var progressView: UIProgressView = {
let progressView = UIProgressView()
progressView.trackTintColor = UIColor.white
progressView.progressTintColor = kMainColor
progressView.frame = CGRect(x: 0, y: 44 - 2, width: kWidth, height: 2)
return progressView
}()
override func viewDidLoad() {
super.viewDidLoad()
setupProgressView()
setupWebView()
}
// MARK: - 自定义进度条
fileprivate func setupProgressView() {
self.navigationController?.navigationBar.addSubview(progressView)
webView.addObserver(self, forKeyPath: progress, options: .new, context: nil)
}
// MARK: - 监听网页加载进度回调
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if (keyPath == progress) {
progressView.alpha = 1.0
progressView.setProgress(Float(webView.estimatedProgress), animated: true)
if webView.estimatedProgress >= 1.0 {
UIView.animate(withDuration: 0.3, delay: 0.1, options: .curveEaseOut, animations: {
self.progressView.alpha = 0
}, completion: { (finish) in
self.progressView.setProgress(0.0, animated: false)
})
}
}
}
// MARK: - 自定义初始化方法
init(_ htmlString: String) {
super.init(nibName: nil, bundle: nil)
title = "WebView"
htmlResuest = URLRequest(url: URL(string: htmlString)!)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
fatalError("init(coder:) has not been implemented")
}
// MARK: - 初始化WKWebView
fileprivate func setupWebView() {
view.addSubview(webView)
webView.snp.makeConstraints { (make) in
make.edges.equalTo(view)
}
webView.load(htmlResuest)
}
deinit {
print("con is deinit")
webView.removeObserver(self, forKeyPath: progress)
webView.uiDelegate = nil
webView.navigationDelegate = nil
progressView.removeFromSuperview()
}
}
extension WebViewController: WKNavigationDelegate,WKUIDelegate {
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
print("开始加载")
startLoading()
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("加载完成")
title = webView.title
stopLoading()
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
print("加载失败")
stopLoading()
}
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
if !(navigationAction.targetFrame?.isMainFrame)! {
webView.load(navigationAction.request)
}
return nil
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
var urlString = navigationAction.request.url?.host
//拦截GitHub回调地址,获取用户code
//再通过code获取用户token
//本项目中所有接口均需要token才能正常访问
if (urlString?.contains("www.jianshu.com"))! {
urlString = navigationAction.request.url?.absoluteString
var array = urlString?.components(separatedBy: "code=")
if !(array?.isEmpty)! {
array = array?.last?.components(separatedBy: "&")
delegate?.getTokenByCode(code: (array?.first)!)
}
}
decisionHandler(.allow);
}
}
//
// AccountTableViewController.swift
// IFS
//
// Created by 曹云霄 on 2018/1/2.
// Copyright © 2018年 上海勾芒信息科技有限公司. All rights reserved.
//
import UIKit
import Kingfisher
class AccountTableViewController: UITableViewController {
/// 用户头像
@IBOutlet weak var userHeaderImg: UIImageView!
/// 用户名
@IBOutlet weak var userNameLab: UILabel!
/// 账户背景
@IBOutlet weak var accountBgView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
uiConfigAction()
dataAction()
}
// MARK: - 状态栏风格
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
// MARK: - UI
fileprivate func uiConfigAction() {
self.fd_prefersNavigationBarHidden = true
if #available(iOS 11.0, *) {
tableView.contentInsetAdjustmentBehavior = .never
} else {
automaticallyAdjustsScrollViewInsets = false
}
userHeaderImg.addAngle(kWidth * 0.15 * 0.5)
userHeaderImg.addBorder(1.0, UIColor.white)
accountBgView.seth(h: kWidth * 9 / 16)
}
// MARK: - 填充数据
fileprivate func dataAction() {
userNameLab.text = "曹云霄"
userHeaderImg.kf.setImage(with: URL(string: "https://upload.jianshu.io/users/upload_avatars/1603648/59f165f01901.jpg?imageMogr2/auto-orient/strip|imageView2/1/w/240/h/240"))
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 10
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
}
//
// FunctionViewController.swift
// IFS
//
// Created by 曹云霄 on 2018/1/2.
// Copyright © 2018年 上海勾芒信息科技有限公司. All rights reserved.
//
import UIKit
class FunctionViewController: BaseViewController {
/// 功能列表
@IBOutlet weak var functionCollectionView: UICollectionView!
@IBOutlet weak var functionFlowLayout: UICollectionViewFlowLayout!
/// FunctionViewModel
lazy final var functionViewModel: FunctionViewModel = {
var functionViewModel = FunctionViewModel()
return functionViewModel
}()
override func viewDidLoad() {
super.viewDidLoad()
setupCollectionView()
}
// MARK: - 设置UICollectionView
fileprivate func setupCollectionView() {
functionFlowLayout.itemSize = CGSize(width: kWidth / 4.0, height: kWidth / 4.0 - 20)
functionFlowLayout.minimumLineSpacing = 0
functionFlowLayout.minimumInteritemSpacing = 0
functionCollectionView.alwaysBounceVertical = true
}
}
extension FunctionViewController: UICollectionViewDelegate,UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
return functionViewModel.dequeueReusableCell(FunctionCollectionViewCell.name(), collectionView, indexPath)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return functionViewModel.itemArrays.count
}
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
let sectionView = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, withReuseIdentifier: FunctionCollectionReusableView.name(), for: indexPath)
return sectionView
}
}
//
// FunctionModel.swift
// IFS
//
// Created by 曹云霄 on 2018/1/2.
// Copyright © 2018年 上海勾芒信息科技有限公司. All rights reserved.
//
struct FunctionModel {
var item_name: String
var item_image: String
init(item_name: String,item_image: String) {
self.item_name = item_name
self.item_image = item_image
}
}
//
// FunctionCollectionReusableView.swift
// IFS
//
// Created by 曹云霄 on 2018/1/2.
// Copyright © 2018年 上海勾芒信息科技有限公司. All rights reserved.
//
import UIKit
class FunctionCollectionReusableView: UICollectionReusableView {
/// section 标题
@IBOutlet weak var sectionTitleLab: UILabel!
}
//
// FunctionCollectionViewCell.swift
// IFS
//
// Created by 曹云霄 on 2018/1/2.
// Copyright © 2018年 上海勾芒信息科技有限公司. All rights reserved.
//
import UIKit
class FunctionCollectionViewCell: UICollectionViewCell {
/// 菜单图片
@IBOutlet weak var itemImg: UIImageView!
/// 菜单名称
@IBOutlet weak var itemTitleLab: UILabel!
// MARK: - 更新菜单cell
func updateFunctionCell(_ model: FunctionModel) {
itemImg.image = UIImage(named: model.item_image)
itemTitleLab.text = model.item_name
}
}
//
// FunctionViewModel.swift
// IFS
//
// Created by 曹云霄 on 2018/1/2.
// Copyright © 2018年 上海勾芒信息科技有限公司. All rights reserved.
//
import UIKit
class FunctionViewModel: BaseViewModel {
// MARK: - 功能菜单图片
lazy final var itemArrays: Array<FunctionModel> = {
var itemImgArrays = Array<FunctionModel>()
let plistpath = Bundle.main.path(forResource: "function", ofType: "plist")
let tempArrays = NSArray(contentsOfFile: plistpath!)
for object in tempArrays! {
let dict = object as! Dictionary<String, String>
let model = FunctionModel(item_name: dict["item_name"]!, item_image: dict["item_image"]!)
itemImgArrays.append(model)
}
return itemImgArrays
}()
}
extension FunctionViewModel {
// MARK: - 创建功能cell
func dequeueReusableCell(_ identifier: String,_ collectionView: UICollectionView,_ indexPath: IndexPath) -> UICollectionViewCell {
let functionCell = collectionView.dequeueReusableCell(withReuseIdentifier: identifier, for: indexPath) as! FunctionCollectionViewCell
functionCell.updateFunctionCell(itemArrays[indexPath.item])
return functionCell
}
}
//
// HomeContentViewController.swift
// IFS
//
// Created by 曹云霄 on 2018/1/2.
// Copyright © 2018年 上海勾芒信息科技有限公司. All rights reserved.
//
import UIKit
class HomeContentViewController: BaseViewController {
/// 首页未开始、已领单
@IBOutlet weak var contentSegmented: UISegmentedControl!
/// 内容ScrollView
@IBOutlet weak var contentScrollView: UIScrollView!
/// 当前子视图
var currentVc: BaseTableViewPullController!
override func viewDidLoad() {
super.viewDidLoad()
addChildContentVc()
}
// MARK: - 添加子控制器到主控制器
fileprivate func addChildContentVc() {
for i in 0..<contentSegmented.numberOfSegments {
let homeTableVc = HomeTableViewController.instantiateViewController(.Home) as! BaseTableViewPullController
addChildViewController(homeTableVc)
if i == kZERO {
currentVc = homeTableVc
homeTableVc.view.setx(x: 0)
homeTableVc.view.seth(h: contentScrollView.height)
homeTableVc.view.setw(w: contentScrollView.width)
contentScrollView.addSubview(homeTableVc.view)
}
}
contentScrollView.contentSize = CGSize(width: contentSegmented.numberOfSegments * Int(kWidth), height: 0)
contentScrollView.isPagingEnabled = true
}
// MARK: - 滚动结束取出下标对应控制器
fileprivate func selectedCurrentVc(_ index: Int,_ scrollView: UIScrollView) {
let tableViewVc = childViewControllers[index]
currentVc = tableViewVc as! BaseTableViewPullController
tableViewVc.view.setx(x: scrollView.contentOffset.x)
tableViewVc.view.seth(h: contentScrollView.height)
tableViewVc.view.setw(w: contentScrollView.width)
contentScrollView.addSubview(tableViewVc.view)
}
// MARK: - UISegmentedControl切换事件
@IBAction func segmentedControlClickAction(_ sender: UISegmentedControl) {
let offset = sender.selectedSegmentIndex * Int(contentScrollView.width)
contentScrollView.setContentOffset(CGPoint(x: offset, y: 0), animated: true)
}
}
extension HomeContentViewController: UIScrollViewDelegate {
// MARK: - 滑动结束,获取当前下标(是人为拖拽scrollView导致滚动完毕,才会调用这个方法)
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
scrollViewDidEndScrollingAnimation(scrollView)
let offset = scrollView.contentOffset;
let index: Int = Int(offset.x / scrollView.width);
contentSegmented.selectedSegmentIndex = index
}
// MARK: - 滑动结束,获取当前下标(如果不是人为拖拽scrollView导致滚动完毕,才会调用这个方法)
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
let offset = scrollView.contentOffset;
let index: Int = Int(offset.x / scrollView.width);
selectedCurrentVc(index,scrollView)
}
}
//
// HomeTableViewController.swift
// IFS
//
// Created by 曹云霄 on 2018/1/2.
// Copyright © 2018年 上海勾芒信息科技有限公司. All rights reserved.
//
import UIKit
class HomeTableViewController: BaseTableViewPullController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func loadWebDataSource() {
endRefresh()
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let homeCell = tableView.dequeueReusableCell(withIdentifier: HomeTableViewCell.name(), for: indexPath)
return homeCell
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 50
}
}
//
// HomeViewController.swift
// IFS
//
// Created by 曹云霄 on 2018/1/2.
// Copyright © 2018年 上海勾芒信息科技有限公司. All rights reserved.
//
import UIKit
import SnapKit
class HomeViewController: BaseViewController {
/// 子视图背景View
@IBOutlet weak var contentBgView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
uiConfigAction()
addChildContentVc()
}
// MARK: - UI
fileprivate func uiConfigAction() {
contentBgView.addAngle(10.0)
contentBgView.addShadow(UIColor.black)
}
// MARK: - 添加子控制器到主控制器
fileprivate func addChildContentVc() {
let homeContentVc = HomeContentViewController.instantiateViewController(.Home)
addChildViewController(homeContentVc)
contentBgView.addSubview(homeContentVc.view)
homeContentVc.view.snp.makeConstraints { (make) in
make.edges.equalTo(contentBgView)
}
}
}
//
// HomeTableViewCell.swift
// IFS
//
// Created by 曹云霄 on 2018/1/2.
// Copyright © 2018年 上海勾芒信息科技有限公司. All rights reserved.
//
import UIKit
class HomeTableViewCell: UITableViewCell {
/// 部门(代码)
@IBOutlet weak var departmentLabel: UILabel!
/// 单据时间
@IBOutlet weak var orderTimeLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
}
This diff is collapsed.
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="oZa-IQ-b7k">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="lpN-PV-uRr">
<objects>
<viewController id="oZa-IQ-b7k" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Qv6-mi-Qhw">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="1470363197668_fact_1" translatesAutoresizingMaskIntoConstraints="NO" id="cwD-kG-8mE">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
</imageView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="cwD-kG-8mE" firstAttribute="bottom" secondItem="bJ4-nF-sq7" secondAttribute="bottom" id="QYE-4q-hD8"/>
<constraint firstItem="cwD-kG-8mE" firstAttribute="trailing" secondItem="bJ4-nF-sq7" secondAttribute="trailing" id="Tqs-Nb-0zs"/>
<constraint firstItem="cwD-kG-8mE" firstAttribute="leading" secondItem="bJ4-nF-sq7" secondAttribute="leading" id="gmz-Qv-m8g"/>
<constraint firstItem="cwD-kG-8mE" firstAttribute="top" secondItem="Qv6-mi-Qhw" secondAttribute="top" id="xoT-b5-H0h"/>
</constraints>
<viewLayoutGuide key="safeArea" id="bJ4-nF-sq7"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="JRl-d9-ZaP" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-180" y="-43.628185907046479"/>
</scene>
</scenes>
<resources>
<image name="1470363197668_fact_1" width="360" height="640"/>
</resources>
</document>
This diff is collapsed.
This diff is collapsed.
//
// AppManager.swift
// GitHub
//
// Created by 曹云霄 on 2017/12/1.
// Copyright © 2017年 曹云霄. All rights reserved.
//
import UIKit
import Hero
class AppManager: NSObject {
// /// 登录用户信息
// open var userModel: UserModel!
// /// 用户token
// open var user_Token: String! {
// didSet {
// //本地存储
// UserDefaults.standard.set(user_Token, forKey: kUserToken)
// UserDefaults.standard.synchronize()
// }
// }
//
/// 单例模式
static var shareInstance: AppManager = {
let instance = AppManager();
AppStyle.setupAppStyle()
return instance;
}();
//
// MARK: - 打开主页
func openMainVc() {
let tabBarVc: TabBarViewController = TabBarViewController()
kWindow.rootViewController = tabBarVc
}
//
// // MARK: - 广告页
// func openAdvertising() {
// let startPageVc: AdvertisingViewController = AdvertisingViewController()
// kWindow.rootViewController = startPageVc
// }
//
// // MARK: - 清除本地token,重新登录
// func deleteToken() {
// UserDefaults.standard.removeObject(forKey: kUserToken)
// }
// MARK: - 打开登录页
func openLoginVc() {
let loginVc = LoginViewController.instantiateViewController(.Main)
kWindow.rootViewController = loginVc
}
}
//
// AppStyle.swift
// GitHub
//
// Created by 曹云霄 on 2017/12/1.
// Copyright © 2017年 曹云霄. All rights reserved.
//
import Foundation
import UIKit
class AppStyle: NSObject {
// MARK: - App风格
open class func setupAppStyle() {
navigationStyle()
}
// MARK: - 设置导航栏风格
fileprivate class func navigationStyle() {
let bar = UINavigationBar.appearance()
bar.tintColor = UIColor.white
bar.barTintColor = kNavColor
bar.isTranslucent = false
bar.barStyle = .black
bar.titleTextAttributes = [NSAttributedStringKey.foregroundColor:UIColor.white,NSAttributedStringKey.font:UIFont.boldSystemFont(ofSize:20)]
}
}
//
// LoginViewController.swift
// GitHub
//
// Created by 曹云霄 on 2017/12/4.
// Copyright © 2017年 曹云霄. All rights reserved.
//
import UIKit
import RxCocoa
import RxSwift
class LoginViewController: UIViewController {
/// RxSwift自动释放
let disposeBag = DisposeBag()
/// 登录按钮
@IBOutlet weak var loginButton: UIButton!
/// 用户名
@IBOutlet weak var userNameTextField: UITextField!
@IBOutlet weak var userNameLineView: UIView!
/// 密码
@IBOutlet weak var passwordTextField: UITextField!
@IBOutlet weak var passwordLineView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
uiConfigAction()
addBtnClickAction()
bindingRxAction()
}
// MARK: - 隐藏状态栏
override var prefersStatusBarHidden: Bool {
return true
}
// MARK: - UI
fileprivate func uiConfigAction() {
loginButton.addAngle(25.0)
}
// MARK: - 登录
fileprivate func addBtnClickAction() {
loginButton.rx.controlEvent(.touchUpInside).subscribe(onNext: { (event) in
AppManager.shareInstance.openMainVc()
}).disposed(by: disposeBag)
}
// MARK: - UITextField绑定RxSwift事件
fileprivate func bindingRxAction() {
userNameTextField.rx.text.map { (text) -> Bool in
if (text?.isEmpty)! {
return false
}
return true
}.subscribe(onNext: {[weak self] (boolValue) in
self?.userNameLineView.backgroundColor = boolValue ? kBlueColor : kGaryColor
}).disposed(by: disposeBag)
passwordTextField.rx.text.map { (text) -> Bool in
if (text?.isEmpty)! {
return false
}
return true
}.subscribe(onNext: {[weak self] (boolValue) in
self?.passwordLineView.backgroundColor = boolValue ? kBlueColor : kGaryColor
}).disposed(by: disposeBag)
Observable.combineLatest(userNameTextField.rx.text.orEmpty,passwordTextField.rx.text.orEmpty).map { (arg) -> Bool in
let (userName, passowrd) = arg
return userName.count > 0 && passowrd.count > 0
}.subscribe(onNext: {[weak self] (bool) in
self?.loginButton.isEnabled = bool
self?.loginButton.alpha = bool ? 1 : 0.5
}).disposed(by: disposeBag)
}
}
//
// TabBarViewController.swift
// GitHub
//
// Created by 曹云霄 on 2017/11/29.
// Copyright © 2017年 曹云霄. All rights reserved.
//
import UIKit
class TabBarViewController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
addChildViewControllers()
}
// MARK: - 添加TabBar控制器
fileprivate func addChildViewControllers() {
setTabBarItem(HomeViewController.instantiateViewController(.Home), navTitle: "首页", tabBarTitle: "首页", imageName: "home_icon")
setTabBarItem(FunctionViewController.instantiateViewController(.Function), navTitle: "功能", tabBarTitle: "功能", imageName: "function_icon")
setTabBarItem(AccountTableViewController.instantiateViewController(.Me), navTitle: "我的", tabBarTitle: "我的", imageName: "me_icon")
}
/// 创建TabBarItem
///
/// - Parameters:
/// - vc: 控制器
/// - navTitle: 导航栏标题
/// - tabBarTitle: item标题
/// - imageName: 图标名字
/// - imageName_selected: 选中图标名字
fileprivate func setTabBarItem(_ vc: UIViewController, navTitle: String?, tabBarTitle: String?, imageName: String?) {
let image: UIImage? = UIImage(named: imageName!)?.withRenderingMode(.alwaysOriginal)
let image_selected: UIImage? = UIImage(named: imageName! + "_selected")?.withRenderingMode(.alwaysOriginal)
let tabBarItem: UITabBarItem = UITabBarItem(title: tabBarTitle, image: image, selectedImage: image_selected)
let nav: BaseNavigationController = BaseNavigationController(rootViewController: vc)
vc.tabBarItem = tabBarItem
vc.navigationItem.title = navTitle
addChildViewController(nav);
// 设置默认的选中文字颜色
UITabBarItem.appearance().setTitleTextAttributes(NSDictionary(object:UIColor.darkGray, forKey:NSAttributedStringKey.foregroundColor as NSCopying) as? [NSAttributedStringKey : AnyObject], for:UIControlState.normal);
UITabBarItem.appearance().setTitleTextAttributes(NSDictionary(object:kNavColor, forKey:NSAttributedStringKey.foregroundColor as NSCopying) as? [NSAttributedStringKey : AnyObject], for:UIControlState.selected)
// 设置字体大小
UITabBarItem.appearance().setTitleTextAttributes([NSAttributedStringKey.font : UIFont(name: "Helvetica", size: 11)!], for: UIControlState.normal)
}
}
//
// UserModel.swift
//
// Create by 云霄 曹 on 7/12/2017
// Copyright © 2017. All rights reserved.
import Foundation
class UserModel: BaseModel {
var location: String! = "---"
var hireable: String!
var public_gists: Int = 0
var url: String!
var following_url: String!
var events_url: String!
var received_events_url: String!
var company: String! = "---"
var updated_at: String!
var bio: String!
var avatar_url: String!
var name: String!
var type: String!
var subscriptions_url: String!
var gists_url: String!
var id: Int = 0
var starred_url: String!
var organizations_url: String!
var repos_url: String!
var site_admin: Bool = false
var email: String! = "---"
var login: String!
var blog: String! = "---"
var public_repos: Int = 0
var followers: Int = 0
var following: Int = 0
var created_at: String!
var gravatar_id: String!
var followers_url: String!
var html_url: String!
}
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "order_icon@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "order_icon@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "todo_icon@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "todo_icon@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "feather@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "feather@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "function_icon@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "function_icon@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "function_icon_selected@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "function_icon_selected@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "home_icon@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "home_icon@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "home_icon_selected@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "home_icon_selected@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "logo_bg@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "me_icon@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "me_icon@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "me_icon_selected@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "me_icon_selected@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "password_icon@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "password_icon@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "username_icon@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "username_icon@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "about_us@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "about_us@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "change_passowrd@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "change_passowrd@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "update_version@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "update_version@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment