日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[Swift]添加暂无数据和暂无网络缺省页

發(fā)布時間:2023/12/14 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Swift]添加暂无数据和暂无网络缺省页 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Demo
GitHub
每個項目都會對暫無數(shù)據(jù)和暫無網(wǎng)絡(luò)進行處理, 提前將這些功能提取出來, 便于以后使用方便.
先pods導(dǎo)入第三方框架,然后拓展控制器的基類.

pod 'EmptyDataSet-Swift', '5.0.0'# 網(wǎng)絡(luò)監(jiān)測pod 'ReachabilitySwift'

最后使用時用一句代碼解決:

setupEmptyData(scrollView: tableView, reload: true, image: UIImage(named: "icon_qs_data.png"))

示意圖:

[代碼備份]
下面是模擬的一個列表:

import Foundation import UIKit import MJRefreshclass GAHomeVC: BaseVC {@IBOutlet weak var tableView: UITableView!var listArr: [[String: String]] = []var page: Int = 1override func viewDidLoad() {super.viewDidLoad()setupUI()anewReloadData()}func setupUI() {tableView.separatorStyle = .noneadjustsScrollViewInsetNever(scrollView: tableView)setupScrollReload()}override func anewReloadData() {super.anewReloadData()page = 1requestListData()}func setupScrollReload() {let mjheader = MJRefreshNormalHeader { [weak self] inself?.anewReloadData()}mjheader.stateLabel?.textColor = .blackmjheader.lastUpdatedTimeLabel?.isHidden = truetableView.mj_header = mjheaderanewReloadData()let footer = MJRefreshAutoNormalFooter { [weak self] inself?.page += 1self?.requestListData()}footer.isHidden = truefooter.setTitle("暫無更多數(shù)據(jù)", for: .noMoreData)footer.stateLabel?.textColor = #colorLiteral(red: 0.6, green: 0.6, blue: 0.6, alpha: 0.5)tableView.mj_footer = footer}@IBAction func tapEmptyAction(_ sender: Any) {tableView.mj_footer?.isHidden = truelistArr.removeAll()page = -1requestListData()}}extension GAHomeVC {func requestListData() {if page == 1 {listArr.removeAll()}let data = moniData()listArr += dataendRefreshing()if data.count < 20 {tableView.mj_footer?.endRefreshingWithNoMoreData()} else {tableView.mj_footer?.resetNoMoreData()}if listArr.count < 20 {tableView.mj_footer?.isHidden = true} else {tableView.mj_footer?.isHidden = false}tableView.reloadData()setupEmptyData(scrollView: tableView, reload: true, image: UIImage(named: "icon_qs_data.png"), space: -70)}func endRefreshing() {if let header = tableView.mj_header , header.isRefreshing {header.endRefreshing()}if let footer = tableView.mj_footer , footer.isRefreshing {footer.endRefreshing()}}func moniData() -> [[String: String]] {if !NetstatManager.shared.isNetworkConnect() {return []}var listCount = 0if page == 1 {listCount = 20} else if page == 2 {listCount = 10} else {return []}var tempArr: [[String: String]] = []for index in ((page-1)*20)..<((page-1)*20+listCount) {let obj = ["title": "title\(index)", "id": "\(index)"]tempArr.append(obj)}return tempArr}}extension GAHomeVC: UITableViewDelegate, UITableViewDataSource {func numberOfSections(in tableView: UITableView) -> Int {return 1}func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {return listArr.count}func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {let cell = UITableViewCell(style: .default, reuseIdentifier: "UITableViewCell")cell.selectionStyle = .noneif listArr.count > indexPath.row {let obj = listArr[indexPath.row]cell.textLabel?.text = obj["title"]}return cell}func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {}}

對BaseVC進行功能擴展:

import UIKit import EmptyDataSet_Swift import SnapKitclass BaseVC: UIViewController {// 暫無數(shù)據(jù) 自定義視圖var emptyDataCustomView: EmptyDataCustomView?// 暫無網(wǎng)絡(luò) 自定義視圖lazy var netAlert: NetstatAlertVC = {let alert = NetstatAlertVC()alert.modalPresentationStyle = .overCurrentContextalert.modalTransitionStyle = .coverVerticalalert.tranferReloadBlock { [weak self] result inself?.anewReloadData()}return alert}()deinit {NotificationCenter.default.removeObserver(self, name: Notification.Name("NetworkStatusChange"), object: nil)}override func viewDidLoad() {super.viewDidLoad()view.backgroundColor = .systemGray5if #available(iOS 13.0, *) {overrideUserInterfaceStyle = .light} else {// Fallback on earlier versions}}override func viewWillAppear(_ animated: Bool) {super.viewWillAppear(animated)}// MARK: iOS11設(shè)置 使用安全區(qū)域func adjustsScrollViewInsetNever(scrollView:UIScrollView) {if #available(iOS 11.0, *){scrollView.contentInsetAdjustmentBehavior = .never}else{self.automaticallyAdjustsScrollViewInsets = false}}// MARK: 重新加載刷新數(shù)據(jù)@objc func anewReloadData() {}}// MARK: 暫無數(shù)據(jù)/暫無網(wǎng)絡(luò) extension BaseVC {/**@abstract 處理暫無數(shù)據(jù)@param scrollView: 容器@param reload: 是否有刷新按鈕@param alert: 提示文字@param image: 提示圖片@param space: 文字頂部距離圖片底部的相對偏移@param mark: 0表示Size15 #333333, 1表示Size13 #999999@param onlyNet: 方法中只處理暫無網(wǎng)絡(luò)的提示*/func setupEmptyData(scrollView: UIScrollView?,reload: Bool = false,alert: String = "暫無數(shù)據(jù)",image: UIImage? = nil,space: CGFloat = 0,mark: Int = 0,onlyNet: Bool = false) {if !NetstatManager.shared.isNetworkConnect() {noNetstatAction(scrollView)return}if onlyNet {return}guard let scr = scrollView else {return}scr.emptyDataSetView { [weak self] view inif self?.emptyDataCustomView == nil {let customView = Bundle.main.loadNibNamed("EmptyDataCustomView", owner: nil, options: nil)![0] as! EmptyDataCustomViewcustomView.setupAlertData(image: image, msg: alert, space: space, mark: mark)if reload {customView.tranferParameterClosure { [weak self] result inself?.anewReloadData()}}self?.emptyDataCustomView = customView}view.customView(self?.emptyDataCustomView).verticalOffset(-50)}}/**@abstract 處理暫無網(wǎng)絡(luò)@param haveData: 是否有數(shù)據(jù)@param reload: 是否有刷新按鈕*/private func noNetstatAction(_ scrollView: UIScrollView?) {var haveData = falseif let tv = scrollView as? UITableView {let cells = tv.visibleCellsif cells.count > 0 {haveData = true}} else if let co = scrollView as? UICollectionView {let cells = co.visibleCellsif cells.count > 0 {haveData = true}}if !NetstatManager.shared.isNetworkConnect() && haveData == false {NotificationCenter.default.addObserver(self, selector: #selector(networkStatusChange(_:)), name: Notification.Name("NetworkStatusChange"), object: nil)self.view.addSubview(netAlert.view)self.view.bringSubviewToFront(netAlert.view)let top: CGFloat = UIApplication.shared.statusBarFrame.height + 44netAlert.view.snp.remakeConstraints { make inmake.bottom.left.right.equalToSuperview()make.top.equalToSuperview().offset(top)}} else {netAlert.view.removeFromSuperview()}}/// 網(wǎng)絡(luò)狀態(tài)從無網(wǎng)絡(luò)切換到有網(wǎng)絡(luò)時,通知刷新@objc func networkStatusChange(_ sender: Notification) {noNetstatAction(nil)if let topVC = ScreenUIManager.topViewController() {if topVC.theClassName == self.theClassName {anewReloadData()}}NotificationCenter.default.removeObserver(self, name: Notification.Name("NetworkStatusChange"), object: nil)}}extension NSObject {// 獲取對象的類名var theClassName: String {return NSStringFromClass(type(of: self))} }

暫無數(shù)據(jù)時的提示視圖:

import Foundation import UIKitclass EmptyDataCustomView: UIView {@IBOutlet weak var alertIV: UIImageView!@IBOutlet weak var ivHConstraint: NSLayoutConstraint!@IBOutlet weak var alertLab: UILabel!@IBOutlet weak var reloadBut: UIButton!@IBOutlet weak var devConstraint: NSLayoutConstraint!private var reloadBlock:((String) -> Void)?override func layoutSubviews() {super.layoutSubviews()}override func awakeFromNib() {super.awakeFromNib()}@IBAction func tapRloadAction(_ sender: Any) {if self.reloadBlock != nil {self.reloadBlock!("刷新了")}}public func tranferParameterClosure(callbackEnclosure:@escaping ((String) -> Void)) {self.reloadBlock = callbackEnclosurereloadBut.isHidden = false}func setupAlertData(image:UIImage?, msg:String, space:CGFloat, mark:Int) {alertIV.image = imagealertLab.text = msgdevConstraint.constant = spaceif mark == 1 {alertLab.textColor = .darkGrayalertLab.font = UIFont.systemFont(ofSize: 13)} else {alertLab.textColor = .blackalertLab.font = UIFont.boldSystemFont(ofSize: 15)}var viewHeight: CGFloat = 100if let ig = image {let igSize = ig.size // 默認都是傳的二倍圖let newIgSize = CGSize(width: igSize.width/2.0, height: igSize.height/2.0)ivHConstraint.constant = newIgSize.heightviewHeight = viewHeight+newIgSize.height} else {ivHConstraint.constant = 0.0}self.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width - 40, height: viewHeight)}}

網(wǎng)絡(luò)管理:

import Foundation import Reachabilityclass NetstatManager: UIViewController {/// 單例static let shared = NetstatManager()/// Reachability必須一直存在,所以需要設(shè)置為全局變量let reachability = try! Reachability()lazy var netAlert: NetstatAlertVC = {let alert = NetstatAlertVC()alert.modalPresentationStyle = .overCurrentContextalert.modalTransitionStyle = .coverVerticalreturn alert}()deinit {// 關(guān)閉網(wǎng)絡(luò)狀態(tài)消息監(jiān)聽reachability.stopNotifier()// 移除網(wǎng)絡(luò)狀態(tài)消息通知NotificationCenter.default.removeObserver(self, name: Notification.Name.reachabilityChanged, object: reachability)}override func viewDidLoad() {super.viewDidLoad()}/// 判斷是否聯(lián)網(wǎng)func isNetworkConnect() -> Bool {return reachability.isReachable}}extension NetstatManager {/// 網(wǎng)絡(luò)狀態(tài)監(jiān)聽func NetworkStatusListener() {// 1、設(shè)置網(wǎng)絡(luò)狀態(tài)消息監(jiān)聽 2、獲得網(wǎng)絡(luò)Reachability對象NotificationCenter.default.addObserver(self, selector: #selector(self.reachabilityChanged),name: Notification.Name.reachabilityChanged,object: reachability)do {// 3、開啟網(wǎng)絡(luò)狀態(tài)消息監(jiān)聽try reachability.startNotifier()} catch {print("could not start reachability notifier")}}/// 主動監(jiān)測網(wǎng)絡(luò)狀態(tài)@objc func reachabilityChanged(note: NSNotification) {let reachability = note.object as! Reachabilityif reachability.isReachable {if reachability.isReachableViaWiFi {print("連接類型:WiFi")} else {print("連接類型:移動網(wǎng)絡(luò)")}self.netAlert.dismiss(animated: false, completion: nil)// 由無網(wǎng)絡(luò)到有網(wǎng)絡(luò)時才發(fā)出通知NotificationCenter.default.post(name: NSNotification.Name("NetworkStatusChange"), object: nil)} else {print("連接類型:暫無網(wǎng)絡(luò)")self.alert_noNetwrok()}}/// 警告框,提示沒有連接網(wǎng)絡(luò)func alert_noNetwrok() -> Void {if let topVC = ScreenUIManager.topViewController() {if let _ = topVC as? NetstatAlertVC {return}}// UIApplication.shared.keyWindow?.rootViewController?.present(self.netAlert, animated: false, completion: nil)}}

總結(jié)

以上是生活随笔為你收集整理的[Swift]添加暂无数据和暂无网络缺省页的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 久久黄色影视 | 一级大片儿 | 亚洲精品污一区二区三区 | 麻豆蜜桃wwww精品无码 | 伊人网综合网 | 日本少妇xxxxxx | 在线免费观看欧美大片 | 欧美亚洲综合网 | 国产午夜伦鲁鲁 | 国产伦精品一区二区三区网站 | 国产精品ww| 精品久久人妻av中文字幕 | 日韩jizz | 欧美一级视频 | 色婷婷久久综合中文久久蜜桃av | 日本色呦呦 | 岛国色图 | 91精品国产91久久久久久黑人 | 亚洲福利在线观看 | 亚洲天堂视频一区 | 91精品人妻一区二区三区 | 香蕉视频黄色 | 中文自拍 | av色欲无码人妻中文字幕 | 亚洲视屏 | 四虎国产成人精品免费一女五男 | 成年人的视频网站 | 2019中文字幕在线观看 | 国产精品视频免费网站 | zzjizzji亚洲日本少妇 | 欧美日韩亚洲在线 | 一区二区三区黄色录像 | 波多野吉衣久久 | 巨胸挤奶视频www网站 | 日韩在线1 | 亚洲男人天堂av | 欧美一区二区黄片 | 中国xxxx性xxxx产国 | 午夜视频福利网站 | 最新日韩精品 | 黄色a一片 | 欧美寡妇性猛交ⅹxxx | 国模私拍在线观看 | 国产免费播放 | 久草久草 | 亚洲精品视频在线看 | 久久中文字幕高清 | 欧美日韩激情视频在线观看 | a√国产 | 香蕉视频在线免费看 | 久久欧| 午夜爽视频 | 免费的黄色的视频 | 欧美午夜寂寞影院 | 国产黄片一区二区三区 | ,国产精品国产三级国产 | 精品无码一区二区三区蜜臀 | 偷拍夫妻性生活 | 麻豆久久久久久久 | 蜜桃av成人 | 亚洲 激情 | 香蕉在线网站 | 欧美日韩a | 日韩高清免费av | 日韩精品乱码久久久久久 | 性欧美4khd高清极品 | 伊人中文网 | 日一日射一射 | 国产情侣av在线 | 一本久久综合亚洲鲁鲁五月天 | 精品成人久久久 | 亚洲免费大全 | 在线激情小视频 | 午夜美女网站 | 亚洲无人禁区 | 少女逼逼 | 蜜桃av噜噜一区二区三区麻豆 | 日韩一级免费 | 国产一级做a爱片久久毛片a | 欧美三级黄色大片 | 成人免费看高清电影在线观看 | 国产高中女学生第一次 | 日女人网站 | 色婷婷色| 黄片毛片一级 | 人妻无码一区二区三区久久99 | 男女av免费 | 国产绿帽刺激高潮对白 | av大帝在线 | 老牛av一区二区 | 99在线无码精品入口 | 亚洲色图在线观看 | 手机免费av片 | 久久久久国色av免费观看性色 | 91黄色免费网站 | 亚洲欧美视频二区 | 18无套直看片红桃 | 色一区二区三区四区 | 97免费超碰 |