//
// BannerViewController.swift
// iosTest
//
//
import UIKit
import SwiftyJSON
import Alamofire
import MJRefresh
//实现SliderGalleryControllerDelegate接口
class BannerViewController: UIViewController,SliderGalleryControllerDelegate,UITableViewDelegate,UITableViewDataSource {
//顶部下拉刷新
//let top_header = MJRefreshNormalHeader()//这个是原声的样式,不能自定一图片轮播
let top_header_style = MJRefreshGifHeader()//这个可以设置下拉刷新的图片动画效果
//底部上拉加载
let bottom_footer = MJRefreshAutoNormalFooter()
//TableView列表控件
@IBOutlet var my_tableview: UITableView!
//获取屏幕的宽度
let screenWidth = UIScreen.main.bounds.size.width
//获取屏幕的高度
let screenHeight = UIScreen.main.bounds.size.height
//自定义的图片轮播的组件
var sliderGallery : SliderGalleryController!
//图片轮播的数据源(String类型的数组)
var imgageData = [String]()
//tableViewData列表数据源(JSON数组)
var tableViewData = Array<JSON>()
override func viewDidLoad() {
super.viewDidLoad()
//请求服务获取轮播图片
getImageData()
getTableViewData("up")
initMJRefresh()
}
//图片轮播组件接口获取数据源的方法
func galleryDataSource() -> [String] {
return imgageData
}
//图片轮播组件接口的方法,获取内部scrollView的尺寸
func galleryScrollerViewSize() -> CGSize {
return CGSize(width: screenWidth-20, height: (screenWidth-20)/4*3)
}
//点击事件响应
@objc func handleTapAction(_ tap:UITapGestureRecognizer) -> Void {
//获取图片的索引值
let index = sliderGallery.currentIndex
print("宝宝你点击了\(index)张图片")
}
//tableView的分区(分区是啥可以看这篇文章 https://blog.csdn.net/lwjok2007/article/details/49246613)
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
//TableView需要展示的行数
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.tableViewData.count
}
//设置每行的单元格的高度
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
//设置每一行的内容
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// 这里 withIdentifier 的参数就是在做 tableview初始化时创建的单元格设置的 forCellReuseIdentifier 值
let cell:MyTableViewCell = my_tableview.dequeueReusableCell(withIdentifier: "myCell") as! MyTableViewCell
//设置cell的值
cell.text_money.text = self.tableViewData[indexPath.row]["***"].stringValue
cell.text3.text = self.tableViewData[indexPath.row]["***"].stringValue
cell.text2.text = self.tableViewData[indexPath.row]["***"].stringValue
cell.text1.text = self.tableViewData[indexPath.row]["***"].stringValue
return cell
}
//顶部下拉刷新时执行的函数
@objc func headerRefresh(){
print("下拉刷新了")
//服务器请求数据的函数
self.getTableViewData()
//重新加载tableView数据
//self.my_tableview.reloadData()
//结束下拉刷新
self.my_tableview.mj_header.endRefreshing()
}
//上拉加载执行的函数
@objc func buttomFooterLoad(){
print("上拉加载")
//服务器请求数据的函数
self.getTableViewData()
//结束刷新
self.my_tableview.mj_footer.endRefreshing()
}
//初始化下拉刷新/上拉加载
func initMJRefresh(){
//下拉刷新相关设置
top_header_style.setRefreshingTarget(self, refreshingAction: #selector(BannerViewController.headerRefresh))
// Set the ordinary state of animated images
var idleImages = [UIImage]()
//添加动画图片
for i in 1...3 {
idleImages.append(UIImage(named:"b\(i)")!)
}
top_header_style.setImages(idleImages, for: .idle)
top_header_style.setImages(idleImages, for: .pulling)
top_header_style.setImages(idleImages, for: .refreshing)
//将下拉刷新控件与 tableView控件绑定起来
self.my_tableview.mj_header = top_header_style
//初始化上拉加载
init_bottomFooter()
}
//上拉加载初始化设置
func init_bottomFooter(){
//上刷新相关设置
bottom_footer.setRefreshingTarget(self, refreshingAction: #selector(BannerViewController.buttomFooterLoad))
//self.bottom_footer.stateLabel.isHidden = true // 隐藏文字
//是否自动加载(默认为true,即表格滑到底部就自动加载,这个我建议关掉,要不然效果会不好)
bottom_footer.isAutomaticallyRefresh = false
bottom_footer.isAutomaticallyChangeAlpha = true //自动更改透明度
//修改文字
bottom_footer.setTitle("上拉上拉上拉", for: .idle)//普通闲置的状态
bottom_footer.setTitle("加载加载加载", for: .refreshing)//正在刷新的状态
bottom_footer.setTitle("没有没有更多数据了", for: .noMoreData)//数据加载完毕的状态
//将上拉加载的控件与 tableView控件绑定起来
self.my_tableview.mj_footer = bottom_footer
}
//数据请求成功后初始化TableView
func initTableView(){
//加载数据
self.my_tableview.reloadData()
//设置tableView控件的位置
self.my_tableview.frame = CGRect(x: 10, y: 200, width: screenWidth, height: screenHeight - 160)
//设置delegate的事件监听
self.my_tableview.delegate = self
//设置dataSource的事件监听
self.my_tableview.dataSource = self
//去除单元格分割线
self.my_tableview.separatorStyle = .none
//创建一个重用的单元格(第一个参数为创建单元格的样式文件的名字,这里就是MyTableViewCell.xib文件,最好把它的'Restoration ID'也设置为跟文件名一样的;第二个参数为创建单元格的标识名)
self.my_tableview.register(UINib(nibName: "MyTableViewCell", bundle: nil), forCellReuseIdentifier: "myCell")
}
//初始化轮播组件
func initSliderGallery(){
//初始化图片轮播组件
sliderGallery = SliderGalleryController()
//设置 SliderGalleryControllerDelegate 接口的监听事件
sliderGallery.delegate = self
//设置轮播组件的位置(这里 height设置170,SliderGalleryController同时也要设置成170)
sliderGallery.view.frame = CGRect(x: 10, y: 30, width: screenWidth-20, height: 170)
//将图片轮播组件添加到当前视图
self.addChildViewController(sliderGallery)
self.view.addSubview(sliderGallery.view)
//添加组件的点击事件
let tap = UITapGestureRecognizer(target: self, action: #selector(BannerViewController.handleTapAction(_:)))
sliderGallery.view.addGestureRecognizer(tap)
}
//请求服务器获取轮播图片的数据
func getImageData(){
//获取当前时间
let now = Date()
//当前时间的时间戳
let timeInterval:TimeInterval = now.timeIntervalSince1970
let timeStamp = String(timeInterval)
let url = URL(string: "http://47.92.107.28:8000/****/****.f?_=\(timeStamp)")!
Alamofire.request(url,method: .get,parameters: nil,encoding: URLEncoding.default,headers:nil).responseJSON { response
in
switch response.result.isSuccess {
case true:
if let value = response.result.value{
self.imgageData = []
//获取返回的值,转为json对象
let img_json = JSON(value)
//json转字符串
let json_str = img_json.rawString()
let zhu_url = "http://47.92.107.28:8000"
//遍历json数据
for(key,item) in img_json["imgs"] {
//print("src的值:\(item["src"])")
//如果取得的 src 的值为 String类型的话就添加到数组中
if let img_url = item["src"].string{
//将图片路径添加到数组中
self.imgageData.append(zhu_url+img_url)
}
}
let str = self.imgageData.joined()
//print("请求到返回的数据\(json_str)")
//初始化轮播组件
self.initSliderGallery()
}
case false:
print(response.result.error)
UIAlertController.showAlert(message: "网络连接失败")
}
}
}
var firset_order:String? = nil//下拉刷新时第一条数据的标识(当前记录的是时间)
var last_order:String? = nil //上拉刷新时最后一条数据的标识(当前记录的是时间)
//获取tableview的数据源(第二步)
func getTableViewData(_ upordown:String) -> Void {
var parameters_json = Dictionary<String,String>()
parameters_json["a"] = upordown //用于标识时上拉还是下拉
parameters_json["l"] = "10" //返回的数据个数
//下拉
if upordown == "up"{
if firset_order != nil {
parameters_json["b"] = firset_order
}else{
parameters_json["b"] = nil
}
}
//上拉
if upordown == "down"{
if last_order != nil {
parameters_json["b"] = last_order
}else{
parameters_json["b"] = nil
}
}
Alamofire.request("http://*****",method: .post,parameters:parameters_json).responseJSON{(response) in
switch response.result.isSuccess{
case true:
if let value = response.result.value{
//将返回的值转为json对象
let data_json = JSON(value)
//获取的新的数据,将其转为json数组
var tmp_order = data_json["*****"].arrayValue
// let json_str = data_json["*****"].rawString()
print("获取首页数据:\(tmp_order.count)")
let len = tmp_order.count
if upordown == "down"{
//重置上拉加载
self.my_tableview.mj_footer.resetNoMoreData()
}
if len > 0 {
//下拉
if upordown == "up"{
if self.last_order == nil {
//下拉的时候,当记录最后一条数据的标识为空时,为它赋值
self.last_order = tmp_order[len - 1]["***"].stringValue
}
//记录每次最新数据第一条数据的时间(因为下拉要的永远是最新数据的第一条)
self.firset_order = tmp_order[0]["***"].stringValue
}
//上拉
if upordown == "down"{
if self.firset_order == nil {
//下拉的时候,当记录第一条数据的标识为空时,为它赋值
self.firset_order = tmp_order[0]["***"].stringValue
}
//记录每次最新数据最后一条数据的时间(因为上拉要的永远是最新数据的最后一条)
self.last_order = tmp_order[len - 1]["***"].stringValue
}
}else{
//如果为上拉的话
if upordown == "down"{
self.my_tableview.mj_footer.endRefreshingWithNoMoreData() //没有数据结束下拉刷新
}
}
//去掉重复的数据,并根据上拉或下拉来处理数据
self.quchong(tmp_order,upordown)
//tableview加载数据
self.initTableView()
}
case false:
print("异常\(response.result.error)")
UIAlertController.showAlert(message: "网络连接失败2")
}
}
}
//去掉重复的数据
func quchong(_ tmp_order: Array<JSON>,_ upordown: String){
//总的数据源长度
let len = self.tableViewData.count
if len > 0{
//先循环新的数据(因为是要去除掉老数据中的重复数据,所以先循环新的数据,再循环老的数据,根据新的数据跟每一个老的数据对比,相同的删除掉)
for (key,item) in tmp_order.enumerated(){
//循环总的数据
for (key2,item2) in self.tableViewData.enumerated(){
if item != nil && item2 != nil{
if item["id"].stringValue == item2[key2]["id"].stringValue{
//如果老数据里有相同的新数据,就将老数据删除
self.tableViewData.remove(at: key2)
}
}
}
}
}
if upordown == "up"{
//如果是下拉刷新,将老的数据添加到新的数据后面
self.tableViewData = tmp_order + self.tableViewData
}else if upordown == "down"{
//如果是上拉加载,就将新的数据添加到老的数据后面
self.tableViewData = self.tableViewData + tmp_order
//移除掉最后一条数据(因为上拉加载更多时,最后一条后有重复,在上面去重的时候最后一条会处理不到)
self.tableViewData.removeLast()
}
print("去重后订单的个数:\(self.tableViewData.count)")
}
//第一个参数为要排序的数组,第二个为根据排序的字段,第三个为是否是时间排序
func jsonSort(_ jsonArray:Array<JSON>,_ field:String,_ isData:Bool) -> Array<JSON>{
var jary = jsonArray
//如果数组长度小于2就步排序了
if jary.count < 2{
return jary
}
//如果是时间排序
if isData{
jary.sort { (x, y) -> Bool in
let formatter = DateFormatter()
formatter.dateFormat = "yyyyMMddHHmmss"
let date_str1 = x[field].rawString()
let date_str2 = y[field].rawString()
let d1 = formatter.date(from: date_str1!)
let d2 = formatter.date(from: date_str2!)
return d1?.compare(d2!) == .orderedDescending //降序排列的 date1 > date2 降序排列 “orderedAscending”代表升序date1 < date2
}
}else{
jary.sort { (x, y) -> Bool in
//字母排序,数字排序
return y[field] < x[field]
}
}
return jary
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
图片轮播缺少的类可以参考我的这篇文章
MJRefresh具体用法可以参考这篇文章
使用MJRefresh时候遇到的问题
1.在给上拉刷新和下拉加载配置图片动画效果的时候,图片一定要小,太大的话刷新会失效(这个问题就因为我当时懒得搞图片,触发的,害得我爬了大半天的坑)