Commit 8613f641 ilCode

刷新加载等基础框架搭建

1 个父辈 4b21ff31
/*
Localizable.strings
AoleiSports
Created by ilCode on 2024/6/19.
*/
"Loading more" = "Loading more";
"No more data" = "No more data";
"Loading..." = "Loading...";
/*
Localizable.strings
AoleiSports
Created by ilCode on 2024/6/19.
*/
"Loading more" = "加载更多";
"No more data" = "没有更多数据";
"Loading..." = "加载中...";
{
"images" : [
{
"filename" : "refresh_icon.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "refresh_icon@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "refresh_icon@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
......@@ -11,6 +11,7 @@ import UIKit
enum EmptyType {
case netErr // 网络问题
case noData // 无数据
case other // 其他错误
}
// 缺省页
......@@ -22,21 +23,13 @@ class AsEmptyView: UIView {
return iv
}()
private lazy var netLab: UILabel = {
private lazy var messageLab: UILabel = {
let lab = UILabel()
lab.text = "请检查您的网络设置或刷新重试"
lab.textColor = kSubTitleColor
lab.textAlignment = .center
lab.font = kFontSize(14)
return lab
}()
private lazy var noDataLab: UILabel = {
let lab = UILabel()
lab.text = "暂无数据"
lab.text = ""
lab.textColor = kSubTitleColor
lab.textAlignment = .center
lab.font = kFontSize(14)
lab.numberOfLines = 0
return lab
}()
......@@ -51,26 +44,8 @@ class AsEmptyView: UIView {
return btn
}()
private lazy var netStackView: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [netLab, refreshBtn])
stackView.axis = .vertical
stackView.alignment = .center
stackView.distribution = .equalSpacing
stackView.spacing = 15
return stackView
}()
private lazy var noDataStackView: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [noDataLab])
stackView.axis = .vertical
stackView.alignment = .center
stackView.distribution = .equalSpacing
stackView.spacing = 20
return stackView
}()
private lazy var containerStackView: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [placeHolder, netStackView, noDataStackView])
let stackView = UIStackView(arrangedSubviews: [placeHolder, messageLab, refreshBtn])
stackView.axis = .vertical
stackView.alignment = .center
stackView.distribution = .equalSpacing
......@@ -87,6 +62,8 @@ class AsEmptyView: UIView {
containerStackView.snp.makeConstraints { make in
make.center.equalToSuperview()
make.left.equalToSuperview().offset(10)
make.right.equalToSuperview().offset(-10)
}
refreshBtn.snp.makeConstraints { make in
......@@ -105,14 +82,15 @@ extension AsEmptyView {
if type == .netErr {
placeHolder.image = R.image.net_err()
netStackView.isHidden = false
noDataStackView.isHidden = true
netLab.text = message ?? "请检查您的网络设置或刷新重试"
messageLab.text = message ?? "请检查您的网络设置或刷新重试"
}
else if type == .noData {
placeHolder.image = R.image.no_data()
netStackView.isHidden = true
noDataStackView.isHidden = false
messageLab.text = "暂无数据,请刷新重试"
}
else if type == .other {
placeHolder.image = R.image.no_data()
messageLab.text = message ?? ""
}
}
......@@ -124,3 +102,40 @@ extension AsEmptyView {
refreshAction?()
}
}
////MARK: - UIView+EmptyView
//extension UITableView {
// private enum AssociatedKeys {
// static var emptyViewKey: Void?
// }
//
// private var emptyView: AsEmptyView? {
// get {
// return objc_getAssociatedObject(self, &AssociatedKeys.emptyViewKey) as? AsEmptyView
// }
// set {
// objc_setAssociatedObject(self, &AssociatedKeys.emptyViewKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
// }
// }
//
// // 显示空视图
// func showEmptyView(type: EmptyType, message: String? = nil, refreshAction: (() -> Void)? = nil) {
// if emptyView == nil {
// let ev = AsEmptyView(frame: .zero)
// addSubview(ev)
// ev.snp.makeConstraints { make in
// make.center.equalToSuperview()
// }
// emptyView = ev
// }
// emptyView?.refreshAction = refreshAction
// emptyView?.show(type: type, message: message)
// }
//
// // 隐藏空视图
// func hideEmptyView() {
// emptyView?.dismiss()
// emptyView?.removeFromSuperview()
// emptyView = nil
// }
//}
......@@ -31,6 +31,7 @@ class BaseController: UIViewController {
}
}
//MARK: - Empty处理
extension BaseController {
func showEmpty(type: EmptyType, message: String? = nil) {
emptyView.show(type: type, message: message)
......@@ -41,6 +42,6 @@ extension BaseController {
}
@objc func handleRefresh() {
dismissEmpty()
}
}
......@@ -16,3 +16,14 @@ extension UIImage {
return resizedImage
}
}
extension UIImage {
convenience init(color: UIColor, size: CGSize) {
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
color.setFill()
UIRectFill(CGRect(origin: .zero, size: size))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
self.init(cgImage: image!.cgImage!)
}
}
......@@ -21,8 +21,8 @@ extension UIView {
}
// 分割线
static func divider(color: UIColor = kDividerColor) -> UIView {
let line = UIView()
static func divider(frame: CGRect = .zero, color: UIColor = kDividerColor) -> UIView {
let line = UIView(frame: frame)
line.backgroundColor = color
return line
}
......
......@@ -9,6 +9,8 @@ import UIKit
// 赛事情报页面
class InfoController: BaseController {
private let MatchInfoCellId = "MatchInfoCell"
var provider: InfoProvider<InfoTarget>?
private lazy var infoListView: UITableView = {
......@@ -17,7 +19,10 @@ class InfoController: BaseController {
tv.dataSource = self
tv.rowHeight = 100
tv.backgroundColor = kMainBgColor
tv.register(MatchInfoCell.self, forCellReuseIdentifier: "MatchInfoCell")
tv.register(MatchInfoCell.self, forCellReuseIdentifier: MatchInfoCellId)
tv.es.addPullToRefresh(animator: RefreshHeaderAnimator(frame: .zero)) { [weak self] in
self?.handleRefresh()
}
return tv
}()
......@@ -25,49 +30,65 @@ class InfoController: BaseController {
super.viewDidLoad()
gk_navTitle = "赛事情报"
provider = InfoProvider(vc: self, showErr: false)
view.addSubview(infoListView)
initProvider()
handleRefresh()
}
deinit {
infoListView.es.removeRefreshHeader()
}
private func initProvider() {
provider = InfoProvider(vc: self, showErr: false)
provider?.infoDataList
.asObservable()
.subscribe(onNext: { infoModels in
print("InfoDataList changed: \(infoModels)")
self.infoListView.reloadData()
if infoModels.isEmpty {
self.infoListView.isHidden = true
self.showEmpty(type: .noData)
} else {
// 数据不为空后面刷新操作换成下拉刷新
self.dismissEmpty()
self.provider?.initLoading = false
self.infoListView.isHidden = false
}
})
.disposed(by: disposeBag)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
handleRefresh()
}
override func handleRefresh() {
super.handleRefresh()
dismissEmpty()
provider?.liveScoreRequest(completion: { logicResult in
if self.provider!.initLoading == false {
self.infoListView.es.stopPullToRefresh()
}
if case .failure(let err) = logicResult {
if case AsError.netErr(let message) = err {
if self.provider!.infoDataList.value.isEmpty && self.provider!.initLoading == true {
self.infoListView.isHidden = true
self.showEmpty(type: .netErr, message: message)
if case AsError.netErr(let message) = err {
self.showEmpty(type: .netErr, message: message)
} else {
self.showEmpty(type: .other, message: err.localizedDescription)
}
} else {
self.view.makeToast(err.localizedDescription, position: .center)
}
return
}
})
}
}
//MARK: UITableViewDelegate, UITableViewDataSource
extension InfoController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return provider?.infoDataList.value.count ?? 0
......@@ -75,51 +96,15 @@ extension InfoController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let model = provider?.infoDataList.value[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "MatchInfoCell", for: indexPath) as! MatchInfoCell
model?.isLast = indexPath.row == (provider?.infoDataList.value.count ?? 0) - 1
let cell = tableView.dequeueReusableCell(withIdentifier: MatchInfoCellId, for: indexPath) as! MatchInfoCell
cell.model = model
return cell
}
}
class MatchInfoCell: BaseTableViewCell {
private lazy var cornerBgView: UIView = {
let view = UIView()
view.backgroundColor = kWhite
view.corners(radius: 10)
return view
}()
private lazy var teamLab: UILabel = {
let lab = UILabel()
lab.textColor = kMainTitleColor
lab.font = kFontSize(16)
return lab
}()
var model: InfoModel? {
didSet {
teamLab.text = (model?.hostName ?? "") + "VS" + (model?.guestName ?? "")
}
}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.addSubview(cornerBgView)
cornerBgView.addSubview(teamLab)
cornerBgView.snp.makeConstraints { make in
make.left.top.equalToSuperview().offset(5)
make.right.equalToSuperview().offset(-5)
make.bottom.equalToSuperview()
}
teamLab.snp.makeConstraints { make in
make.left.top.equalToSuperview().offset(5)
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let infoDetail = InfoDetailController()
infoDetail.model = provider?.infoDataList.value[indexPath.row]
navigationController?.pushViewController(infoDetail, animated: true)
}
}
......@@ -9,15 +9,11 @@ import UIKit
// 情报详情页面
class InfoDetailController: BaseController {
var model: InfoModel? {
didSet {
gk_navTitle = (model?.hostName ?? "") + "VS" + (model?.guestName ?? "")
}
}
var model: InfoModel?
override func viewDidLoad() {
super.viewDidLoad()
gk_navTitle = (model?.hostName ?? "") + "VS" + (model?.guestName ?? "")
}
}
......@@ -27,6 +27,8 @@ class InfoModel: Mappable {
var sportsInfoCount: Int?
var jcInfo: String?
var isLast: Bool?
required init?(map: ObjectMapper.Map) {
}
......
......@@ -58,18 +58,18 @@ enum InfoTarget: TargetType {
class InfoProvider<Target: TargetType>: BaseMoyaProvider<Target> {
var infoDataList = BehaviorRelay<[InfoModel]>(value: [])
func liveScoreRequest(completion: @escaping (Result<Bool, AsError>) -> Void) {
moyaPost(api: APIs.kLiveScore, target: InfoTarget.info) { midResult in
DDLogInfo("赛事情报接口数据:\(midResult)")
// DDLogInfo("赛事情报接口数据:\(midResult)")
switch midResult {
case let .success(midSuccessResult):
guard let matchs = midSuccessResult["matchs"] as? [[String : Any]] else {
guard let matchs = midSuccessResult["matchs"] as? [[String : Any]], !matchs.isEmpty else {
self.infoDataList.accept([])
return
}
// 过滤出 JcInfo 非空的项
// 过滤出JcInfo非空的项
let filteredMatchs = matchs.filter { match in
guard let jcInfo = match["JcInfo"] as? String, !jcInfo.isEmpty else {
return false
......@@ -78,7 +78,6 @@ class InfoProvider<Target: TargetType>: BaseMoyaProvider<Target> {
}
let infoModels = Mapper<InfoModel>().mapArray(JSONArray: filteredMatchs)
self.infoDataList.accept(infoModels)
completion(.success(true))
case .failure(let err):
completion(.failure(err))
......
//
// MatchInfoCell.swift
// AoleiSports
//
// Created by ilCode on 2024/6/18.
//
import UIKit
class MatchInfoCell: BaseTableViewCell {
private lazy var cornerBgView: UIView = {
let view = UIView()
view.backgroundColor = kWhite
view.corners(radius: 5)
return view
}()
private lazy var teamLab: UILabel = {
let lab = UILabel()
lab.textColor = kMainTitleColor
lab.font = kFontSize(16)
return lab
}()
var model: InfoModel? {
didSet {
teamLab.text = (model?.hostName ?? "") + "VS" + (model?.guestName ?? "")
cornerBgView.snp.remakeConstraints { make in
make.left.top.equalToSuperview().offset(8)
make.right.equalToSuperview().offset(-8)
make.bottom.equalToSuperview().offset((model?.isLast ?? false) ? -8 : 0)
}
}
}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.backgroundColor = kMainBgColor
contentView.addSubview(cornerBgView)
cornerBgView.addSubview(teamLab)
cornerBgView.snp.makeConstraints { make in
make.left.top.equalToSuperview().offset(8)
make.right.equalToSuperview().offset(-8)
make.bottom.equalToSuperview()
}
teamLab.snp.makeConstraints { make in
make.left.top.equalToSuperview().offset(5)
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
......@@ -23,6 +23,9 @@ class RootController: UITabBarController {
// 设置tabbar选中及未选中的文字颜色
tabBar.tintColor = kMasterColor
tabBar.unselectedItemTintColor = kSubTitleColor
// 自定义分割线
tabBar.addSubview(UIView.divider(frame: CGRect(x: 0, y: 0, width: kScreenW, height: 1)))
addController(rootVC: HomeController(), title: "赛事比分", image: R.image.home(), selectedImage: R.image.home_selected())
addController(rootVC: InfoController(), title: "赛事情报", image: R.image.ssqb(), selectedImage: R.image.ssqb_selected())
......
......@@ -15,3 +15,4 @@
@_exported import SwiftyJSON
@_exported import RxGesture
@_exported import ObjectMapper
@_exported import ESPullToRefresh
......@@ -73,13 +73,15 @@ extension TargetType {
final class BaseMoyaPlugin: PluginType {
var vc: UIViewController?
private var spinner: NVActivityIndicatorView!
var initLoading: Bool = true
var showErr: Bool = true
init(vc: UIViewController?, showLoading: Bool = true, showErr: Bool = true) {
init(vc: UIViewController?, initLoading: Bool = true, showErr: Bool = true) {
self.vc = vc
self.initLoading = initLoading
self.showErr = showErr
if let tmpVC = self.vc, showLoading {
if let tmpVC = self.vc, initLoading {
spinner = NVActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 60, height: 55), type: .ballSpinFadeLoader, color: kMasterColor)
spinner.center = tmpVC.view.center
}
......@@ -96,7 +98,7 @@ final class BaseMoyaPlugin: PluginType {
}
func willSend(_ request: any RequestType, target: any TargetType) {
if let tmpVC = self.vc, let spinner = spinner {
if let tmpVC = self.vc, initLoading, let spinner = spinner {
DispatchQueue.main.async {
tmpVC.view.addSubview(spinner)
spinner.startAnimating()
......@@ -106,7 +108,7 @@ final class BaseMoyaPlugin: PluginType {
func didReceive(_ result: Result<Response, MoyaError>, target: any TargetType) {
// 移除界面中央的活动状态指示器
if let spinner = spinner {
if let spinner = spinner, initLoading {
DispatchQueue.main.async {
spinner.removeFromSuperview()
spinner.stopAnimating()
......@@ -132,10 +134,16 @@ final class BaseMoyaPlugin: PluginType {
class BaseMoyaProvider<Target: TargetType>: MoyaProvider<Target> {
let disposeBag = DisposeBag()
var basePlugin: BaseMoyaPlugin
var initLoading: Bool = true {
didSet {
basePlugin.initLoading = initLoading
}
}
init(vc: UIViewController? = nil, showLoading: Bool = true, showErr: Bool = true) {
self.basePlugin = BaseMoyaPlugin(vc: vc, showLoading: showLoading, showErr: showErr)
init(vc: UIViewController? = nil, initLoading: Bool = true, showErr: Bool = true) {
self.basePlugin = BaseMoyaPlugin(vc: vc, initLoading: initLoading, showErr: showErr)
super.init(plugins: [self.basePlugin])
self.initLoading = initLoading
}
/// Moya Post
......
//
// RefreshFooterAnimator.swift
// AoleiSports
//
// Created by ilCode on 2024/6/19.
//
import UIKit
//MARK: - 自定义刷新尾
public class RefreshFooterAnimator: UIView, ESRefreshProtocol, ESRefreshAnimatorProtocol {
public let loadingMoreDescription: String = "Loading more"
public let noMoreDataDescription: String = "No more data"
public let loadingDescription: String = "Loading..."
public var view: UIView {
return self
}
public var insets: UIEdgeInsets = UIEdgeInsets.zero
public var trigger: CGFloat = 48.0
public var executeIncremental: CGFloat = 48.0
public var state: ESRefreshViewState = .pullToRefresh
private let topLine: UIView = {
let topLine = UIView.init(frame: CGRect.zero)
topLine.backgroundColor = UIColor.init(red: 214/255.0, green: 211/255.0, blue: 206/255.0, alpha: 1.0)
return topLine
}()
private let bottomLine: UIView = {
let bottomLine = UIView.init(frame: CGRect.zero)
bottomLine.backgroundColor = UIColor.init(red: 214/255.0, green: 211/255.0, blue: 206/255.0, alpha: 1.0)
return bottomLine
}()
private let titleLabel: UILabel = {
let label = UILabel.init(frame: CGRect.zero)
label.font = UIFont.systemFont(ofSize: 14.0)
label.textColor = UIColor.init(white: 160.0 / 255.0, alpha: 1.0)
label.textAlignment = .center
return label
}()
private let indicatorView: UIActivityIndicatorView = {
let indicatorView = UIActivityIndicatorView.init(style: .medium)
indicatorView.isHidden = true
return indicatorView
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.white
titleLabel.text = loadingMoreDescription
addSubview(titleLabel)
addSubview(indicatorView)
addSubview(topLine)
addSubview(bottomLine)
}
public required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public func refreshAnimationBegin(view: ESRefreshComponent) {
indicatorView.startAnimating()
indicatorView.isHidden = false
}
public func refreshAnimationEnd(view: ESRefreshComponent) {
indicatorView.stopAnimating()
indicatorView.isHidden = true
}
public func refresh(view: ESRefreshComponent, progressDidChange progress: CGFloat) {
// do nothing
}
public func refresh(view: ESRefreshComponent, stateDidChange state: ESRefreshViewState) {
switch state {
case .refreshing :
titleLabel.text = loadingDescription
break
case .autoRefreshing :
titleLabel.text = loadingDescription
break
case .noMoreData:
titleLabel.text = noMoreDataDescription
break
default:
titleLabel.text = loadingMoreDescription
break
}
}
public override func layoutSubviews() {
super.layoutSubviews()
let s = self.bounds.size
let w = s.width
let h = s.height
titleLabel.frame = self.bounds
indicatorView.center = CGPoint.init(x: 32.0, y: h / 2.0)
topLine.frame = CGRect.init(x: 0.0, y: 0.0, width: w, height: 0.5)
bottomLine.frame = CGRect.init(x: 0.0, y: h - 1.0, width: w, height: 1.0)
}
}
//
// RefreshHeaderAnimator.swift
// LittleDreamSleep
//
// Created by peter on 2022/8/24.
//
import UIKit
//MARK: - 自定义刷新头
class RefreshHeaderAnimator: UIView, ESRefreshAnimatorProtocol {
public var view: UIView { return self }
public var insets: UIEdgeInsets = UIEdgeInsets.zero
public var trigger: CGFloat = 60.0
public var executeIncremental: CGFloat = 60.0
public var state: ESRefreshViewState = .pullToRefresh
let aniImageView = UIImageView(image: R.image.refresh_icon())
override init(frame: CGRect) {
super.init(frame: frame)
aniImageView.frame = CGRect(x: (kScreenW - 30)/2.0, y: (60 - 30)/2.0, width: 30, height: 30)
addSubview(aniImageView)
}
public required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
//MARK: - ESRefreshProtocol
extension RefreshHeaderAnimator: ESRefreshProtocol {
public func refreshAnimationBegin(view: ESRefreshComponent) {
aniImageView.frame = CGRect(x: (self.bounds.size.width - 30)/2.0, y: (self.bounds.size.height - 30)/2.0, width: 30, height: 30)
startAnimation()
}
public func refreshAnimationEnd(view: ESRefreshComponent) {
stopAnimation()
}
public func refresh(view: ESRefreshComponent, progressDidChange progress: CGFloat) { }
public func refresh(view: ESRefreshComponent, stateDidChange state: ESRefreshViewState) {
guard self.state != state else {
return
}
self.state = state
switch state {
case .pullToRefresh:
break
case .releaseToRefresh:
break
default:
break
}
}
}
extension RefreshHeaderAnimator {
@objc func startAnimation() {
let animation = CABasicAnimation(keyPath: "transform.rotation.z")
animation.toValue = NSNumber(value: Double.pi * 2)
animation.duration = 2.0
animation.repeatCount = Float.infinity
aniImageView.layer.add(animation, forKey: "rotationAnimation")
}
@objc func stopAnimation() {
aniImageView.layer.removeAnimation(forKey: "rotationAnimation")
}
}
//MARK: - 3D动画
extension RefreshHeaderAnimator {
// import SceneKit
// var sceneView: SCNView!
// 创建旋转动画
// let animation = CABasicAnimation(keyPath: "transform.rotation.z")
// animation.toValue = NSNumber(value: Double.pi * 2)
// animation.duration = 3.0
// animation.repeatCount = Float.infinity
// aniImageView.layer.add(animation, forKey: nil)
// 创建 SceneKit 视图
// sceneView = SCNView(frame: CGRect(x: (kScreenW - w)/2.0, y: 0, width: 60, height: 60))
// addSubview(sceneView)
// sceneView.border()
// 创建场景
// let scene = SCNScene()
// sceneView.scene = scene
// sceneView.allowsCameraControl = true
// sceneView.autoenablesDefaultLighting = true
// 创建球体几何体
// let sphere = SCNSphere(radius: 1.5)
//
// // 添加球体材质
// let material = SCNMaterial()
// material.diffuse.contents = UIImage(named: "football_texture.jpg")
// sphere.firstMaterial = material
//
// // 创建球体节点
// let sphereNode = SCNNode(geometry: sphere)
// sphereNode.position = SCNVector3(0, 0, 0)
// scene.rootNode.addChildNode(sphereNode)
//
// // 创建绕球体旋转的动画
// let rotateAction = SCNAction.rotateBy(x: 0, y: CGFloat(2 * Double.pi), z: 0, duration: 3)
// let repeatAction = SCNAction.repeatForever(rotateAction)
// sphereNode.runAction(repeatAction)
//
// // 添加相机
// let cameraNode = SCNNode()
// cameraNode.camera = SCNCamera()
// cameraNode.position = SCNVector3(0, 0, 5)
// scene.rootNode.addChildNode(cameraNode)
}
......@@ -15,6 +15,7 @@ target 'AoleiSports' do
pod 'Toast-Swift', '~> 5.1.1'
pod 'ObjectMapper', '~> 4.4.2'
pod 'RxGesture', '~> 4.0.4'
pod 'ESPullToRefresh', '~> 2.9.3'
end
......
......@@ -3,6 +3,7 @@ PODS:
- CocoaLumberjack/Core (3.8.5)
- CocoaLumberjack/Swift (3.8.5):
- CocoaLumberjack/Core
- ESPullToRefresh (2.9.3)
- Moya/Core (15.0.0):
- Alamofire (~> 5.0)
- Moya/RxSwift (15.0.0):
......@@ -29,6 +30,7 @@ PODS:
DEPENDENCIES:
- Alamofire (~> 5.9.1)
- CocoaLumberjack/Swift
- ESPullToRefresh (~> 2.9.3)
- Moya/RxSwift (~> 15.0)
- NVActivityIndicatorView (~> 5.2.0)
- ObjectMapper (~> 4.4.2)
......@@ -44,6 +46,7 @@ SPEC REPOS:
trunk:
- Alamofire
- CocoaLumberjack
- ESPullToRefresh
- Moya
- NVActivityIndicatorView
- ObjectMapper
......@@ -59,6 +62,7 @@ SPEC REPOS:
SPEC CHECKSUMS:
Alamofire: f36a35757af4587d8e4f4bfa223ad10be2422b8c
CocoaLumberjack: 6a459bc897d6d80bd1b8c78482ec7ad05dffc3f0
ESPullToRefresh: 0d68daa602b343c81753a1b95e09fd0bfcddfd40
Moya: 138f0573e53411fb3dc17016add0b748dfbd78ee
NVActivityIndicatorView: fe52a6a68664c2df8991d7d9e3d86d8d19453c53
ObjectMapper: e6e4d91ff7f2861df7aecc536c92d8363f4c9677
......@@ -71,6 +75,6 @@ SPEC CHECKSUMS:
SwiftyJSON: f5b1bf1cd8dd53cd25887ac0eabcfd92301c6a5a
Toast-Swift: 7a03a532afe3a560d4044bc7c237e2864d295173
PODFILE CHECKSUM: 0ed9736004dd278591ebfa22937383fb27c4e17f
PODFILE CHECKSUM: aaab2dc38f3bdf57b45edf6252d34b03cda60517
COCOAPODS: 1.15.2
......@@ -44,25 +44,55 @@ struct _R {
}
struct project {
let developmentRegion = "en"
let developmentRegion = "zh-Hans"
}
/// This `_R.string` struct is generated, and contains static references to 1 localization tables.
/// This `_R.string` struct is generated, and contains static references to 2 localization tables.
struct string {
let bundle: Foundation.Bundle
let preferredLanguages: [String]?
let locale: Locale?
var launchScreen: launchScreen { .init(source: .init(bundle: bundle, tableName: "LaunchScreen", preferredLanguages: preferredLanguages, locale: locale)) }
var localizable: localizable { .init(source: .init(bundle: bundle, tableName: "Localizable", preferredLanguages: preferredLanguages, locale: locale)) }
func launchScreen(preferredLanguages: [String]) -> launchScreen {
.init(source: .init(bundle: bundle, tableName: "LaunchScreen", preferredLanguages: preferredLanguages, locale: locale))
}
func localizable(preferredLanguages: [String]) -> localizable {
.init(source: .init(bundle: bundle, tableName: "Localizable", preferredLanguages: preferredLanguages, locale: locale))
}
/// This `_R.string.launchScreen` struct is generated, and contains static references to 0 localization keys.
struct launchScreen {
let source: RswiftResources.StringResource.Source
}
/// This `_R.string.localizable` struct is generated, and contains static references to 3 localization keys.
struct localizable {
let source: RswiftResources.StringResource.Source
/// zh-Hans translation: 加载更多
///
/// Key: Loading more
///
/// Locales: en, zh-Hans
var loadingMore: RswiftResources.StringResource { .init(key: "Loading more", tableName: "Localizable", source: source, developmentValue: "加载更多", comment: nil) }
/// zh-Hans translation: 加载中...
///
/// Key: Loading...
///
/// Locales: en, zh-Hans
var loading: RswiftResources.StringResource { .init(key: "Loading...", tableName: "Localizable", source: source, developmentValue: "加载中...", comment: nil) }
/// zh-Hans translation: 没有更多数据
///
/// Key: No more data
///
/// Locales: en, zh-Hans
var noMoreData: RswiftResources.StringResource { .init(key: "No more data", tableName: "Localizable", source: source, developmentValue: "没有更多数据", comment: nil) }
}
}
/// This `_R.color` struct is generated, and contains static references to 1 colors.
......@@ -73,7 +103,7 @@ struct _R {
var accentColor: RswiftResources.ColorResource { .init(name: "AccentColor", path: [], bundle: bundle) }
}
/// This `_R.image` struct is generated, and contains static references to 22 images.
/// This `_R.image` struct is generated, and contains static references to 23 images.
struct image {
let bundle: Foundation.Bundle
......@@ -134,6 +164,9 @@ struct _R {
/// Image `profile_selected`.
var profile_selected: RswiftResources.ImageResource { .init(name: "profile_selected", path: [], bundle: bundle, locale: nil, onDemandResourceTags: nil) }
/// Image `refresh_icon`.
var refresh_icon: RswiftResources.ImageResource { .init(name: "refresh_icon", path: [], bundle: bundle, locale: nil, onDemandResourceTags: nil) }
/// Image `right_arrow_icon`.
var right_arrow_icon: RswiftResources.ImageResource { .init(name: "right_arrow_icon", path: [], bundle: bundle, locale: nil, onDemandResourceTags: nil) }
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!