123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- //
- // UIScrollView+Empty.swift
- // HDEmptyViewDemo
- //
- // Created by liuyi on 2018/5/18.
- // Copyright © 2018年 liuyi. All rights reserved.
- //
- import UIKit
- import Foundation
- extension UIScrollView {
- struct RuntimeKey {
- static let kEmptyViewKey = UnsafeRawPointer.init(bitPattern: "kEmptyViewKey".hashValue)
- }
-
- public var ly_emptyView: HDEmptyView? {
- set {
- objc_setAssociatedObject(self, RuntimeKey.kEmptyViewKey!, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
- for view in self.subviews {
- if view.isKind(of: HDEmptyView.classForCoder()) {
- view.removeFromSuperview()
- }
- }
- self.addSubview(ly_emptyView!)
- self.ly_emptyView?.isHidden = true
- }
- get {
- return objc_getAssociatedObject(self, RuntimeKey.kEmptyViewKey!) as? HDEmptyView
- }
- }
-
- //MAKR: --- 根据 DataSource 判断是否自动显示 emptyView
- public func ly_startLoading() {
- self.ly_emptyView?.isHidden = true
- }
-
- public func ly_endLoading() {
- getDataAndSet()
- }
-
- //手动控制显隐方法,不受DataSource的影响,需要把 autoShowEmptyView = false
- public func ly_showEmptyView() {
- self.ly_emptyView?.superview?.layoutSubviews()
- self.ly_emptyView?.isHidden = false
- //始终保持显示在最上层
- if self.ly_emptyView != nil {
- self.bringSubviewToFront(self.ly_emptyView!)
- }
- }
-
- public func ly_hideEmptyView() {
- self.ly_emptyView?.isHidden = true
- }
-
- //MARK: - Private Method
- fileprivate func totalDataCount() -> NSInteger {
- var totalCount: NSInteger = 0
- if self.isKind(of: UITableView.classForCoder()) {
- let tableView = self as? UITableView
- if (tableView?.numberOfSections)! >= 1 {
- for section in 0...(tableView?.numberOfSections)!-1 {
- totalCount += (tableView?.numberOfRows(inSection: section))!
- }
- }
- }
- else if self.isKind(of: UICollectionView.classForCoder()) {
- let collectionView = self as? UICollectionView
- if (collectionView?.numberOfSections)! >= 1 {
- for section in 0...(collectionView?.numberOfSections)!-1 {
- totalCount += (collectionView?.numberOfItems(inSection: section))!
- }
- }
- }
- return totalCount
- }
-
- fileprivate func getDataAndSet() {
- if self.totalDataCount() == 0 {
- show()
- } else {
- hide()
- }
- }
-
- fileprivate func show() {
- if self.ly_emptyView?.autoShowEmptyView == false {
- self.ly_emptyView?.isHidden = true
- return
- }
- ly_showEmptyView()
- }
- fileprivate func hide() {
- if self.ly_emptyView?.autoShowEmptyView == false {
- self.ly_emptyView?.isHidden = true
- return
- }
- ly_hideEmptyView()
- }
- }
- //MARK: ------ UITableView ------
- extension UITableView:SelfAware {
- static func awake() {
- UITableView.classInit()
- }
-
- static func classInit() {
- swizzleMethod
- }
- private static let swizzleMethod: Void = {
- //insertSections
- let originalSelector = #selector(insertSections(_:with:))
- let swizzledSelector = #selector(ly_insertSections(_:with:))
- HDRunTime.exchangeMethod(selector: originalSelector, replace: swizzledSelector, class: UITableView.self)
-
- //deleteSections
- let originalSelector1 = #selector(deleteSections(_:with:))
- let swizzledSelector1 = #selector(ly_deleteSections(_:with:))
- HDRunTime.exchangeMethod(selector: originalSelector1, replace: swizzledSelector1, class: UITableView.self)
-
- //insertRows
- let originalSelector2 = #selector(insertRows(at:with:))
- let swizzledSelector2 = #selector(ly_insertRowsAtIndexPaths(at:with:))
- HDRunTime.exchangeMethod(selector: originalSelector2, replace: swizzledSelector2, class: UITableView.self)
-
- //deleteRows
- let originalSelector3 = #selector(deleteRows(at:with:))
- let swizzledSelector3 = #selector(ly_deleteRowsAtIndexPaths(at:with:))
- HDRunTime.exchangeMethod(selector: originalSelector3, replace: swizzledSelector3, class: UITableView.self)
-
- //reload
- let originalSelector4 = #selector(UITableView.reloadData as (UITableView) -> () -> Void)
- let swizzledSelector4 = #selector(ly_reloadData)
- HDRunTime.exchangeMethod(selector: originalSelector4, replace: swizzledSelector4, class: UITableView.self)
-
- }()
-
- //section
- @objc func ly_insertSections(_ sections: NSIndexSet, with animation: UITableView.RowAnimation) {
- ly_insertSections(sections, with: animation)
- getDataAndSet()
- }
-
- @objc func ly_deleteSections(_ sections: NSIndexSet, with animation: UITableView.RowAnimation) {
- ly_deleteSections(sections, with: animation)
- getDataAndSet()
- }
-
- //row
- @objc func ly_insertRowsAtIndexPaths(at indexPaths: [IndexPath], with animation: UITableView.RowAnimation){
- ly_insertRowsAtIndexPaths(at: indexPaths, with: animation)
- getDataAndSet()
- }
-
- @objc func ly_deleteRowsAtIndexPaths(at indexPaths: [IndexPath], with animation: UITableView.RowAnimation){
- ly_deleteRowsAtIndexPaths(at: indexPaths, with: animation)
- getDataAndSet()
- }
-
- //reloadData
- @objc func ly_reloadData() {
- self.ly_reloadData()
- self.getDataAndSet()
- }
-
- }
- //MARK: ------ UICollectionView ------
- extension UICollectionView:SelfAware {
- static func awake() {
- UICollectionView.classInit()
- }
-
- static func classInit() {
- swizzleMethod
- }
-
- private static let swizzleMethod: Void = {
- //insertSections
- let originalSelector = #selector(insertSections(_:))
- let swizzledSelector = #selector(ly_insertSections(_:))
- HDRunTime.exchangeMethod(selector: originalSelector, replace: swizzledSelector, class: UICollectionView.self)
-
- //deleteSections
- let originalSelector1 = #selector(deleteSections(_:))
- let swizzledSelector1 = #selector(ly_deleteSections(_:))
- HDRunTime.exchangeMethod(selector: originalSelector1, replace: swizzledSelector1, class: UICollectionView.self)
-
- //insertRows
- let originalSelector2 = #selector(insertItems(at:))
- let swizzledSelector2 = #selector(ly_insertItemsAtIndexPaths(at:))
- HDRunTime.exchangeMethod(selector: originalSelector2, replace: swizzledSelector2, class: UICollectionView.self)
-
- //deleteRows
- let originalSelector3 = #selector(deleteItems(at:))
- let swizzledSelector3 = #selector(ly_deleteItemsAtIndexPaths(at:))
- HDRunTime.exchangeMethod(selector: originalSelector3, replace: swizzledSelector3, class: UICollectionView.self)
-
- //reload
- let originalSelector4 = #selector(UICollectionView.reloadData as (UICollectionView) -> () -> Void)
- let swizzledSelector4 = #selector(ly_reloadData)
- HDRunTime.exchangeMethod(selector: originalSelector4, replace: swizzledSelector4, class: UICollectionView.self)
-
- }()
-
- //section
- @objc func ly_insertSections(_ sections: NSIndexSet) {
- ly_insertSections(sections)
- getDataAndSet()
- }
-
- @objc func ly_deleteSections(_ sections: NSIndexSet) {
- ly_deleteSections(sections)
- getDataAndSet()
- }
-
- //item
- @objc func ly_insertItemsAtIndexPaths(at indexPaths: [IndexPath]){
- ly_insertItemsAtIndexPaths(at: indexPaths)
- getDataAndSet()
- }
-
- @objc func ly_deleteItemsAtIndexPaths(at indexPaths: [IndexPath]){
- ly_deleteItemsAtIndexPaths(at: indexPaths)
- getDataAndSet()
- }
-
- //reloadData
- @objc func ly_reloadData() {
- self.ly_reloadData()
- self.getDataAndSet()
- }
- }
- // MARK:- SelfAware 定义协议,使得程序在初始化的时候,将遵循该协议的类做了方法交换
- protocol SelfAware: class {
- static func awake()
- }
- class NothingToSeeHere {
- static func harmlessFunction() {
- let typeCount = Int(objc_getClassList(nil, 0))
- let types = UnsafeMutablePointer<AnyClass>.allocate(capacity: typeCount)
- let autoreleasingTypes = AutoreleasingUnsafeMutablePointer<AnyClass>(types)
- objc_getClassList(autoreleasingTypes, Int32(typeCount))
- for index in 0 ..< typeCount {
- (types[index] as? SelfAware.Type)?.awake()
- }
- //types.deallocate(capacity: typeCount)
- types.deallocate()
- }
- }
- extension UIApplication {
- private static let runOnce: Void = {
- NothingToSeeHere.harmlessFunction()
- }()
-
- override open var next: UIResponder? {
- // Called before applicationDidFinishLaunching
- UIApplication.runOnce
- return super.next
- }
- }
|