<file_sep>//
//  LazyObject.swift
//  SwiftTestbed
//
//  Created by firefly on 2020/11/13.
//

import Foundation

struct Object {
    var x = 1
    var y = 2
    var z = 3
}

struct LazyObject {
    lazy var x = 1
    lazy var y = 2
    lazy var z = 3
}

enum Week {
    case sunday
    case monday
    case tuesday(Int)
    case wednesday
    case thursday
    case friday
    case saturday
}
<file_sep>//
//  DimPresentationVC.swift
//  SwiftTestbed
//
//  Created by firefly on 2021/1/16.
//

import Foundation
import UIKit

class DimPresentationVC: UIPresentationController {
    
    var dimmingView: UIView = {
        let view = UIView(frame: CGRect(origin: CGPoint.zero, size: UIScreen.main.bounds.size))
        view.backgroundColor = UIColor.black.withAlphaComponent(0.3)
        return view
    }()
    
    public override var frameOfPresentedViewInContainerView: CGRect {
        
        let width = UIScreen.main.bounds.width - 2 * 24
        let height = width / 327 * 287

        let y = UIScreen.main.bounds.height * 0.4 - height / 2
        let frame = CGRect(x: 24, y: y, width: width, height: height)
        
        return frame
    }
    
    override func presentationTransitionWillBegin() {
        print("\(type(of: self)).\(#function)")
        self.containerView?.addSubview(dimmingView)
        dimmingView.addSubview(self.presentedViewController.view)
        
        let transitionCoordinator = self.presentingViewController.transitionCoordinator
        dimmingView.alpha = 0
        transitionCoordinator?.animate(alongsideTransition: { (content) in
            self.dimmingView.alpha = 1
        }, completion: { (context) in
            print("dimmingView alpha = 1")
        })
    }
    override func presentationTransitionDidEnd(_ completed: Bool) {
        print("\(type(of: self)).\(#function)")
    }
    
    override func dismissalTransitionWillBegin() {
        print("\(type(of: self)).\(#function)")
        let transitionCoordinator = self.presentingViewController.transitionCoordinator
        dimmingView.alpha = 1
        transitionCoordinator?.animate(alongsideTransition: { (content) in
            self.dimmingView.alpha = 0
        }, completion: { (context) in
            print("dimmingView alpha = 0")
        })
    }
    override func dismissalTransitionDidEnd(_ completed: Bool) {
        print("\(type(of: self)).\(#function)")
        if !completed {
            dimmingView.removeFromSuperview()
        }
    }
    
    deinit {
        print("\(type(of: self)).\(#function)")
    }
}
<file_sep>//
//  PopoverVC.swift
//  SwiftTestbed
//
//  Created by firefly on 2020/12/8.
//

import Foundation
import UIKit

class PopoverVC: BaseViewController {
    
    lazy var addItem: UIBarButtonItem = {
        let item = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(add))
        return item
    }()
    
    var btn: UIButton!
    var items: IteamsVC!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        addBarButtonItems()
        
        addButton()
        
    }
    
    func addBarButtonItems() {
        navigationItem.rightBarButtonItem = addItem
    }
    
    func addPopover() {
        let items = IteamsVC()
        items.preferredContentSize = CGSize(width: 80, height: 160)
        items.modalPresentationStyle = .popover
        
        let pop = items.popoverPresentationController
        pop?.delegate = self
        pop?.barButtonItem = addItem
        
        self.present(items, animated: true, completion: nil)
        
    }
    
    @objc func add() {
        print("\(type(of: self)).\(#function)")
        
        addPopover()
    }
    
    func addButton() {
        btn = UIButton(frame: CGRect(x: 60, y: 100, width: 100, height: 60))
        btn.addTarget(self, action: #selector(popButton), for: UIControl.Event.touchUpInside)
        btn.backgroundColor = UIColor.green
        view.addSubview(btn)
        
        // 创建vc
        items = IteamsVC()
        // 设置弹出框的大小
        items.preferredContentSize = CGSize(width: 80, height: 160)
        // 设置显示的样式为弹出框
        items.modalPresentationStyle = .popover
    }
    
    @objc func popButton() {
        print("\(type(of: self)).\(#function)")
        
        // 获取vc的展示vc 并 设置该展示vc
        let pop = items.popoverPresentationController
        pop?.delegate = self
        pop?.sourceView = btn
        pop?.sourceRect = CGRect(x: 90, y: 50, width: 10, height: 10)
        pop?.backgroundColor = UIColor.orange
        print(pop?.popoverLayoutMargins as Any)
        // 显示vc
        self.present(items, animated: true, completion: nil)
    }
    
    
}

// 提供该方法，则不能呈现弹出框样式
extension PopoverVC: UIPopoverPresentationControllerDelegate {
    func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
        return .none
    }
}


<file_sep>//
//  PayPasswordVC.swift
//  SwiftTestbed
//
//  Created by firefly on 2021/1/16.
//

import Foundation
import UIKit


class PayPasswordVC: BaseViewController {
    
    var label: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        print("\(type(of: self)).\(#function)")
        creatUI()
        configUI()
        addUI()
        constraintUI()
    }
    
    func creatUI() {
        label = UILabel()
        
    }
    func configUI() {
        view.backgroundColor = .green
        view.layer.cornerRadius = 10
        view.layer.masksToBounds = true
    }
    func addUI() {
        
    }
    func constraintUI() {
        
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.dismiss(animated: true, completion: nil)
    }
}

extension PayPasswordVC: UIViewControllerTransitioningDelegate {
    func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
        print("\(type(of: self)).\(#function)")
        let presentationVC = DimPresentationVC(presentedViewController: presented, presenting: presenting)
        return presentationVC
    }
}
<file_sep>//
//  LazyLoadingVC.swift
//  SwiftTestbed
//
//  Created by firefly on 2020/11/13.
//

import Foundation

import UIKit

class LazyLoadingVC: BaseViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        var lazyObject = LazyObject()
        var object = Object()
        
        title = "懒加载"
        if #available(iOS 11, *) {
            navigationItem.backButtonTitle = ""
        }
        
        print("object内存结构")
        print(MemoryLayout.size(ofValue: object))
        print(MemoryLayout.alignment(ofValue: object))
        print(MemoryLayout.stride(ofValue: object))
        print("lazyObject内存结构")
        print(MemoryLayout.size(ofValue: lazyObject))
        print(MemoryLayout.alignment(ofValue: lazyObject))
        print(MemoryLayout.stride(ofValue: lazyObject))
    
        print("lazyObject:", lazyObject)
        print("x:", lazyObject.x)
        print("y:", lazyObject.y)
        print("z:", lazyObject.z)
        
        print("lazyObject.z type:", type(of: lazyObject.z))
        print("lazyObject内存结构")
        print(MemoryLayout.size(ofValue: lazyObject))
        print(MemoryLayout.alignment(ofValue: lazyObject))
        print(MemoryLayout.stride(ofValue: lazyObject))
        
        print("end")
    }
    
}
<file_sep>//
//  Table.swift
//  SwiftTestbed
//
//  Created by firefly on 2020/12/8.
//

import Foundation

class Table<T> {
    var dataArray = [T]()
}
<file_sep>//
//  Team.swift
//  SwiftTestbed
//
//  Created by firefly on 2020/11/16.
//

import Foundation

struct Person: Codable {
    var id: Int
    var name: String
    var age: Int
    var isMale: Bool
}

struct Team: Codable {
    var master: Person
    var members: [Person]
}


<file_sep>//
//  File.swift
//  SwiftTestbed
//
//  Created by itang on 2021/5/15.
//

import Foundation
import UIKit

/*
 目标：
 1、感知 ViewController 已经dismiss了
 2、感知 ViewController 的返回按钮被点击了，然后决定是否要pop
 
 显示：
 1、在viewDidDisappear(_ animated:)中实现
 2、
 */
class BackActionVC: BaseViewController {
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        navigationController?.pushViewController(UIViewController(), animated: true)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let popBarBtn = UIBarButtonItem(title: "pop", style: .plain, target: self, action: #selector(pop))
        let presentBarBtn = UIBarButtonItem(title: "present", style: .plain, target: self, action: #selector(presentVC))

        navigationItem.rightBarButtonItems = [popBarBtn, presentBarBtn]

        
        // 自定义左侧按钮后，视图控制器的返回手势就失效了
//        navigationItem.leftBarButtonItem = UIBarButtonItem(title: "back", style: .plain, target: self, action: #selector(pop))

    }
    
    @objc func pop() {
        /*
         pop vc时，不会触发navigationBar(_:shouldPop:)
         右滑返回视图控制器时，不会触发navigationBar(_:shouldPop:)
         */
        navigationController?.popViewController(animated: true)
    }
    @objc func presentVC() {
        /*
         pop vc时，不会触发navigationBar(_:shouldPop:)
         右滑返回视图控制器时，不会触发navigationBar(_:shouldPop:)
         */
        let vc = PVC()
        vc.modalPresentationStyle = .fullScreen
        self.present(vc, animated: true)
    }
}
<file_sep>//
//  SearchResultVC.swift
//  SwiftTestbed
//
//  Created by itang on 2020/12/6.
//

import Foundation
import UIKit

class SearchResultVC: BaseViewController, UISearchResultsUpdating {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = UIColor.orange
//        用UIPresentationController来写一个简洁漂亮的底部弹出控件
//        UIPopoverPresentationController
//        UIPresentationController
    }
    
    func updateSearchResults(for searchController: UISearchController) {
        print("\(type(of: self)).\(#function)")
        let frame = searchController.view.frame
        let newFrame = CGRect(x: 0, y: 100, width: frame.width, height: frame.height - 100)
        view.frame = newFrame
        view.isHidden = false
    }
    
    deinit {
        print("\(type(of: self)).\(#function)")
    }
}
<file_sep>//
//  PVC.swift
//  SwiftTestbed
//
//  Created by itang on 2021/5/16.
//

import Foundation
import UIKit

class PVC: BaseViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        title = "被弹出的控制器A"
        view.backgroundColor = .orange
        
        let btn = UIButton(frame: CGRect(origin: .zero, size: CGSize(width: 100, height: 60)))
        btn.addTarget(self, action: #selector(presentVC), for: .touchUpInside)
        btn.setTitle("present VC", for: .normal)
        btn.center = view.center
        btn.backgroundColor = .gray
        view.addSubview(btn)
    }
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.dismiss(animated: true) {
            print("PVC did dismiss")
        }
    }
    
    @objc func presentVC() {
        let vc = BaseViewController()
        vc.modalPresentationStyle = .fullScreen
        present(vc, animated: true)
    }
}
<file_sep>//
//  HUD.swift
//  SwiftTestbed
//
//  Created by firefly on 2021/1/28.
//

import Foundation
import UIKit
import MBProgressHUD

/// 状态指示器
/// 可显示在window上，可显示在指定的view上
/// 对于显示结果的hud，文字不宜过长，否则很丑。(待优化)
/// 要在主线中操作：显示、切换、隐藏
class HUD {
    
    // 文本类的hud在父视图上的位置
    enum Position {
        case top // 在顶部
        case middle // 在中间
        case bottom // 在底部
    }
        
    //MARK: - 显示指示器
    @discardableResult
    static func showIndicator(message: String = "")  -> MBProgressHUD {
        let window = UIApplication.shared.windows.last
        let hud = showIndicator(message: message, in: window!)
        
        return hud
    }
    
    @discardableResult
    static func showIndicator(message: String = "", in view: UIView) -> MBProgressHUD {
        let hud = MBProgressHUD.showAdded(to: view, animated: true)
        hud.mode = .customView
        
        hud.label.text = message
        hud.isSquare = true
        
        // dim
        hud.backgroundView.style = .solidColor
        hud.backgroundView.color = UIColor(white: 0, alpha: 0.1)
        
        // 隐藏时从父视图上移除
        hud.removeFromSuperViewOnHide = true;
        
        let indefinateView = SVIndefiniteAnimatedView(frame: CGRect(x: 0, y: 0, width: 80, height: 80))

        indefinateView.strokeColor = .white;
        indefinateView.strokeThickness = 2
        indefinateView.radius = 20
                
        hud.customView = indefinateView
        
        // 文本颜色
        hud.contentColor = .white
        // 背景色
        hud.bezelView.style = .solidColor
        hud.bezelView.backgroundColor = .black
        
        return hud
    }
    
    //MARK: - 让指示器消失
    static func hideIndicator(parentViewOrHud: UIView, animated: Bool = true) {
        var optionalHud: MBProgressHUD?
        if parentViewOrHud is MBProgressHUD {
            optionalHud = parentViewOrHud as? MBProgressHUD
        } else {
            optionalHud = MBProgressHUD.forView(parentViewOrHud)
        }
        
        guard let hud = optionalHud else {
            return
        }
        
        hud.hide(animated: animated)
    }
    
    // MARK: - 显示结果： 成功、失败、警告
    
    
    // MARK: 转换到结果视图
    static func switchToSuccess(text: String, for view: UIView, duration: TimeInterval = 3) {
        switchToResult(.success, text: text, for: view)
    }
    static func switchToFailure(text: String, for view: UIView, duration: TimeInterval = 3) {
        switchToResult(.failure, text: text, for: view)
    }
    static func switchToWaring(text: String, for view: UIView, duration: TimeInterval = 3) {
        switchToResult(.warning, text: text, for: view)
    }
    
    /// 从状态指示器切换到结果
    /// - parameter resultType: 结果类型：成功、失败、警告
    /// - parameter text: 提示信息
    /// - parameter for: 要切换的视图，可能是状态指示器的父视图，可可能是状态指示器本身
    /// - parameter duration: 切换后，结果视图显示的时间(单位为秒)，默认为3s

    static func switchToResult(_ resultType: ResultType, text: String, for view: UIView, duration: TimeInterval = 3) {
        
        var optionalHud: MBProgressHUD?
        if view is MBProgressHUD {
            optionalHud = view as? MBProgressHUD
        } else {
            optionalHud = MBProgressHUD.forView(view)
        }
        
        guard let hud = optionalHud else {
            return
        }
        // 切换模式
        hud.mode = .customView
        // 切换消息
        hud.label.text = text
        // 切换到指定的结果
        let image = HUD.resultImage(resultType)
        hud.customView = UIImageView(image: image)
        
        hud.hide(animated: true, afterDelay: duration)
    }
    
    // MARK: 显示在window上
    static func showSuccess(text: String, duration: TimeInterval = 3) {
        showResult(.success, text: text, duration: duration)
    }
    static func showFailure(text: String, duration: TimeInterval = 3) {
        showResult(.failure, text: text, duration: duration)
    }
    static func showWarning(text: String, duration: TimeInterval = 3) {
        showResult(.warning, text: text, duration: duration)
    }
    
    static func showResult(_ resultType: ResultType, text: String, duration: TimeInterval = 3) {
        guard let window = UIApplication.shared.windows.last else {
            return
        }
        showResult(resultType, text: text, in: window, duration: duration)
    }
    
    // MARK: 显示指定视图上
    static func showSuccess(text: String, in view: UIView, duration: TimeInterval = 3) {
        showResult(.success, text: text, in: view, duration: duration)
    }
    static func showFailure(text: String, in view: UIView, duration: TimeInterval = 3) {
        showResult(.failure, text: text, in: view, duration: duration)
    }
    static func showWarning(text: String, in view: UIView, duration: TimeInterval = 3) {
        showResult(.warning, text: text, in: view, duration: duration)
    }
    /*
     在指定视图上显示指定时间的指定文字和结果
     */
    enum ResultType {
        case success
        case failure
        case warning
    }
    static func showResult(_ resultType: ResultType, text: String, in view: UIView, duration: TimeInterval = 3) {
        let hud = MBProgressHUD.showAdded(to: view, animated: true)
        hud.mode = .customView
        hud.label.text = text
        
        // 自定义视图
        let image = resultImage(resultType)
        hud.customView = UIImageView(image: image)
        
        // 保持正方形
//        hud.isSquare = true

        // 文本颜色
        hud.contentColor = .white
        // 背景色
        hud.bezelView.style = .solidColor
        hud.bezelView.backgroundColor = .black
        
        hud.hide(animated: true, afterDelay: duration)
    }
    
    static func resultImage(_ resultType: ResultType) -> UIImage? {
        let image: UIImage?
        
        switch resultType {
        case .success:
            image = UIImage(named: "Checkmark")
        case .failure:
            image = UIImage(named: "error")
        case .warning:
            image = UIImage(named: "info")
        }
        
        return image?.withRenderingMode(.alwaysTemplate)
    }
    
    // MARK: - 显示提示文字
    // 在window指定的位置显示指定的时间
    static func showText(_ text: String, at position: Position = .bottom, duration: TimeInterval = 3) {
        guard let window = UIApplication.shared.windows.last else {
            return
        }
        showText(text, at: position, in: window, duration: duration)
    }
        
    static func showText(_ text: String, at position: Position = .bottom, in parentView: UIView, duration: TimeInterval = 3) {
        let hud = MBProgressHUD.showAdded(to: parentView, animated: true)
        hud.mode = .text
        hud.label.text = text
        
        // 显示位置
        let viewHeight = parentView.bounds.height
        let delta = viewHeight / 2 * 0.7
        
        let offsetY: CGFloat
        switch position {
        case .top:
            offsetY = -delta
        case .middle:
            offsetY = 0
        case .bottom:
            offsetY = delta
        }
        
        hud.offset = CGPoint(x: 0, y: offsetY)

        // 文本颜色
        hud.contentColor = .white
        // 背景色
        hud.bezelView.style = .solidColor
        hud.bezelView.backgroundColor = .black
        
        hud.margin = 10 // 调整提hud的高度
        
        hud.hide(animated: true, afterDelay: duration)
    }
}
<file_sep>//
//  AppDelegate.swift
//  SwiftTestbed
//
//  Created by firefly on 2020/11/12.
//

import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        self.window = UIWindow(frame: UIScreen.main.bounds)
        self.window?.backgroundColor = UIColor.white
        
        let tvc = TableViewController()
        let nvc = NavigationController(rootViewController: tvc)
        self.window?.rootViewController = nvc
        self.window?.makeKeyAndVisible()
        
        printItems()
        
        return true
    }
    
    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        
        // file:///private/var/mobile/Containers/Data/Application/63B17B7E-1C80-4B65-B3A2-459579FD6D7D/Documents/Inbox/test-1.txt
        // path: /var/mobile/Containers/Data/Application/D0E5544D-DD36-46D0-9C92-5C051870A95E/Documents/user
        
        print("in file:", url.absoluteString)
        
        return true
    }
    
    func printItems() {
        let homePath = NSHomeDirectory()
        let docPath = homePath + "/Documents"
        let path = docPath + "/Inbox/test"
        
        let enumerator = FileManager.default.enumerator(atPath: path)
        while let item = enumerator?.nextObject() as? String {
            print(item)
        }
    }
    
    static let path: String = {
        let homePath = NSHomeDirectory()
        let docPath = homePath + "/Documents"
        let userPath = docPath + "/user"
        
        return userPath
    }()
}

<file_sep>//
//  TableViewController.swift
//  SwiftTestbed
//
//  Created by firefly on 2020/11/12.
//

import Foundation

import UIKit

class TableViewController: UITableViewController {
    
    fileprivate let cellReuseID = "cell"
    
    lazy var dataArray = [TestItem]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        configUI()
        
        setupData()
        
        tableView.reloadData()
    }
    
    func configUI() {
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellReuseID)
        tableView.tableFooterView = UIView()
    }
    
    func setupData() {
        dataArray = [
            TestItem(title: "元类型", type: MetatypeVC.self),
            TestItem(title: "懒加载", type: LazyLoadingVC.self),
            TestItem(title: "编码、解码、归档", type: CodableDemoVC.self),
            TestItem(title: "分页滑动", type: PageDemoVC.self),
            TestItem(title: "CollectionView", type: CollectionViewVC.self),
            TestItem(title: "泛型父类和具体子类", type: GenericsVC.self),
            TestItem(title: "搜索", type: ContainSearchBarVC.self),
            TestItem(title: "弹出框", type: PopoverVC.self),
            TestItem(title: "图文混排", type: ImageTextVC.self),
            TestItem(title: "WebviewVC", type: WebviewVC.self),
            TestItem(title: "过渡动画", type: PresetationDemoVC.self),
            TestItem(title: "无限转动动画", type: HUDVC.self),
            TestItem(title: "控制器返回事件", type: BackActionVC.self),
            
        ]
    }
}

extension TableViewController {
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        
        let testItem = dataArray[indexPath.row]
        
        let vc = testItem.type.init()
        self.navigationController?.pushViewController(vc, animated: true)
        
    }
}

extension TableViewController {
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataArray.count
    }
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let testItem = dataArray[indexPath.row]
        let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseID, for: indexPath)
        cell.textLabel?.text = testItem.title
        return cell
    }
}
<file_sep>//
//  Smiley.swift
//  SwiftTestbed
//
//  Created by firefly on 2020/11/13.
//

import Foundation

class Smiley {
    class var text: String {
        return ":)"
    }
}

class EmojiSmiley: Smiley {
    override class var text: String {
        return "😊"
    }
}
<file_sep>//
//  CollectionViewVC.swift
//  SwiftTestbed
//
//  Created by firefly on 2020/11/23.
//

import Foundation

import UIKit

class CollectionViewVC: BaseViewController {
    
    // 三个button、一个collectionView
    
    var twoLevelCollectionView: UICollectionView!
    var collectionViewLayout: UICollectionViewLayout!
    
    let tableViewReuseID = "UITableViewCell"
    let collectionViewReuseID = "UICollectionViewCell"
    let headerReuseID = "headerReuseID"

    override func viewDidLoad() {
        super.viewDidLoad()
        
        creatUI()
        configUI()
        addUI()
        constraintUI()
        
    }
    
    // MARK: - UI 初步
    func creatUI() {
        collectionViewLayout = UICollectionViewFlowLayout()
//        collectionViewLayout.
        twoLevelCollectionView = UICollectionView(frame: view.bounds, collectionViewLayout: collectionViewLayout)
    }
    func configUI() {
        configCollectionView()
    }
    func addUI() {
        view.addSubview(twoLevelCollectionView)
    }
    func constraintUI() {
        
    }
    
    // MARK: 细化
    func configCollectionView() {
//        twoLevelCollectionView.backgroundColor = UIColor.lightGray
        twoLevelCollectionView.delegate = self
        twoLevelCollectionView.dataSource = self
        twoLevelCollectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: collectionViewReuseID)
        
        twoLevelCollectionView.register(UICollectionReusableView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "headerReuseID")
    }
}

// MARK: - collection view delegate
extension CollectionViewVC: UICollectionViewDelegate, UICollectionViewDataSource {
    
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        1
    }
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        10
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: collectionViewReuseID, for: indexPath)
        cell.contentView.backgroundColor = UIColor.gray
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: headerReuseID, for: indexPath)
        header.backgroundColor = UIColor.red
        return header
    }
}
//extension CollectionViewVC: UICollectionViewDelegateFlowLayout {
//    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
//        return CGSize(width: 60, height: 40)
//    }
//}
<file_sep>//
//  ImageTextVC.swift
//  SwiftTestbed
//
//  Created by firefly on 2020/12/28.
//

import Foundation
import UIKit

class ImageTextVC: BaseViewController {
    
    var textVieW = UITextView(frame: CGRect(x: 30, y: 40, width: 340, height: 600))
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        creatUI()
        configUI()
        addUI()
        constraintUI()
    }
    
    func creatUI() {
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "test", style: .plain, target: self, action: #selector(parse))
    }
    func configUI() {
        view.backgroundColor = UIColor.groupTableViewBackground
        textVieW.backgroundColor = UIColor.white
        
//        textVieW.text = "asdfasdf asd fasdf j;ljas asdfja;ls j;lk asdf asfasdf jasdfasd;jfkas;djkf asd fsdffsadf asdf  as dfj;lasdj as;ldjf;lkjl;j;k;kddd a "
        
        
        //图片表情
//        //1. 生成一个图片的附件, Attachment:附件
//        let attachMent = NSTextAttachment()
//
//        //2. 使用NSTextAttachment将想要插入的图片作为一个字符处理，转换成NSAttributedString
//        attachMent.image = UIImage(named: "shop_bg")
//
//        //3. 因为图片的大小是按照原图的尺寸, 所以要设置图片的bounds, 也就是大小
//        attachMent.bounds = CGRect(x: 0, y: 100, width: 300, height: 200)
//
//        //4. 将图片添加到富文本上
//        let attachString = NSAttributedString(attachment: attachMent)
//
//        //5. 把图片富文本转换成可变的富文本
//        let mutiAttachString = NSMutableAttributedString(attributedString: attachString)
//
//        //6. 调用富文本的对象方法 addAttributes(_ attrs: [String : Any] = [:], range: NSRange)
//        //来修改对应range范围中 attribute属性的 value值
//        //这里是修改富文本所有文本的字体大小为textView里的文本大小
//        mutiAttachString.addAttributes([NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16)], range: NSMakeRange(0, attachString.length))
//
//        textVieW.attributedText = mutiAttachString
        
    }
    func addUI() {
        view.addSubview(textVieW)
    }
    func constraintUI() {
        
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//        insetText()
        insetImage()
    }
    
    //插入文字
    func insetText() {
       
        //创建属性字符串
        let attrStr = NSAttributedString(string: "美女", attributes: [NSAttributedString.Key.foregroundColor:UIColor.red])
         
        let font = textVieW.font!
         
        //创建可变属性字符串
        let attrMutableStr = NSMutableAttributedString(attributedString: textVieW.attributedText)
         
        //将图片属性字符串替换到可变属性字符串的某一个位置
        //获取光标所在位置
        let range = textVieW.selectedRange
         
        //替换属性字符串
        attrMutableStr.replaceCharacters(in: range, with: attrStr)
         
        //显示属性字符串
        textVieW.attributedText = attrMutableStr
         
        //将文字大小重置
        textVieW.font = font
         
        //将光标设置回原来的位置
        textVieW.selectedRange = NSRange(location: range.location + 2, length : 0)

    }

         //插入图片
    func insetImage() {
        
        //创建图片属性字符串
        let attachment = NSTextAttachment()
        attachment.image = UIImage(named: "shop_bg")
        let font = textVieW.font!
        attachment.bounds = CGRect(x: 0, y: 0, width: 300, height: 200)
        let attrImageStr = NSAttributedString(attachment: attachment)
        
        //创建可变属性字符串
        let attrMutableStr = NSMutableAttributedString(attributedString: textVieW.attributedText)
        
        //将图片属性字符串替换到可变属性字符串的某一个位置
        //获取光标所在位置
        let range = textVieW.selectedRange
        
        //替换属性字符串
        attrMutableStr.replaceCharacters(in: range, with: attrImageStr)
        
        //显示属性字符串
        textVieW.attributedText = attrMutableStr
        
        //将文字大小重置
        textVieW.font = font
        
        //将光标设置回原来的位置
        textVieW.selectedRange = NSRange(location: range.location + 1, length : 0)
    }
    
    
    @objc func parse() {
        print("\(type(of: self)).\(#function)")
        
        textVieW.attributedText.enumerateAttributes(in: NSRange(location: 0, length: textVieW.attributedText.length), options: NSAttributedString.EnumerationOptions(rawValue: 0)) { (info, range, stop) in
            
            if let attachment = info[NSAttributedString.Key.attachment] as? NSTextAttachment{
                print(attachment.image!)
                print(range)
                
                
            }
            print("\n")

        }
        
        print("text:", textVieW.text)
        
    }
}
<file_sep>//
//  ContainSearchBarVC.swift
//  SwiftTestbed
//
//  Created by itang on 2020/12/6.
//

import Foundation
import UIKit

class ContainSearchBarVC: BaseViewController {
    
    var svc: UISearchController = {
        let rvc = SearchResultVC()
        let vc = UISearchController(searchResultsController: rvc)
        
        vc.hidesNavigationBarDuringPresentation = false
        vc.obscuresBackgroundDuringPresentation = false
        
        vc.searchResultsUpdater = rvc
        
        return vc
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.lightGray
        addBarButtonItems()
        
        addSearchBar()
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        svc.dismiss(animated: true, completion: nil)
    }
    
    func addBarButtonItems() {
        let item = UIBarButtonItem(title: "发布", style: .plain, target: self, action: #selector(publish(sender:)))
        navigationItem.rightBarButtonItem = item
    }
    
    func addSearchBar() {
        
        
        
        let searchBar = svc.searchBar
        searchBar.delegate = self
        navigationItem.titleView = searchBar
    }
    
    @objc func publish(sender: UIBarButtonItem) {
        print("\(type(of: self)).\(#function)")

    }
    
    deinit {
        print("\(type(of: self)).\(#function)")
    }
}

extension ContainSearchBarVC: UISearchBarDelegate {
    
    func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool {
        print("\(type(of: self)).\(#function)")
        navigationItem.rightBarButtonItem = nil
        return true
    }

    func searchBarTextDidBeginEditing(_ searchBar: UISearchBar){
        print("\(type(of: self)).\(#function)")
    }

    func searchBarShouldEndEditing(_ searchBar: UISearchBar) -> Bool {
        print("\(type(of: self)).\(#function)")
        return true

    }

    func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
        print("\(type(of: self)).\(#function)")
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
            self.addBarButtonItems()
        }
    }
    
    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        print("\(type(of: self)).\(#function)")
        svc.dismiss(animated: true, completion: nil)
    }
    
    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
        print("\(type(of: self)).\(#function)")
    }
    
    
}
<file_sep>//
//  User.swift
//  SwiftTestbed
//
//  Created by firefly on 2020/11/16.
//

import Foundation


// 归档 必须继承NSObject
struct User: Codable {
    var id = 1001
    var isMale = true
    var name: String
    var age: Int
    var money: Double
    var des = ""
}

extension User {
    enum CodingKeys: String, CodingKey {
        case id
        case isMale = "is_male"
        case name
        case age
        case money
    }
}
<file_sep>//
//  PageDemoVC.swift
//  SwiftTestbed
//
//  Created by firefly on 2020/11/17.
//

import Foundation


import UIKit

class PageDemoVC: BaseViewController {
    var dataArray: [PageVC] = {
        let p1 = PageVC()
        p1.view.backgroundColor = UIColor.green
        let p2 = PageVC()
        p2.view.backgroundColor = UIColor.orange
        let p3 = PageVC()
        p3.view.backgroundColor = UIColor.blue
        
        return [p1, p2, p3]
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        
        let pagesVC = UIPageViewController.init(transitionStyle: UIPageViewController.TransitionStyle.scroll, navigationOrientation: UIPageViewController.NavigationOrientation.horizontal)
        pagesVC.delegate = self
        pagesVC.dataSource = self
        
        pagesVC.setViewControllers([dataArray[0]], direction: UIPageViewController.NavigationDirection.reverse, animated: false, completion: nil)
        
        pagesVC.view.frame = self.view.bounds
        
        self.addChild(pagesVC)
        self.view.addSubview(pagesVC.view)
    }
}

extension PageDemoVC: UIPageViewControllerDelegate {
    
}

extension PageDemoVC: UIPageViewControllerDataSource {
    
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        
        let index = dataArray.firstIndex(of: viewController as! PageVC)
        if index == 0 {
            return nil
        }
        
        return dataArray[index! - 1]
    }
    
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        let index = dataArray.firstIndex(of: viewController as! PageVC)
        if index == dataArray.count - 1 {
            return nil
        }
        
        return dataArray[index! + 1]
    }
    
}
<file_sep>//
//  WebviewVC.swift
//  SwiftTestbed
//
//  Created by firefly on 2020/12/31.
//

import Foundation
import WebKit


class WebviewVC: BaseViewController {
    var webView = WKWebView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        creatUI()
        configUI()
        addUI()
        constraintUI()
        
        let url = URL(string: "https://www.baidu.com")
        let baidu = URLRequest(url: url!)
        webView.load(baidu)
    }
    
    func creatUI() {
        
    }
    func configUI() {
        webView.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height)
    }
    func addUI() {
        view.addSubview(webView)
    }
    func constraintUI() {
        
    }
    
    
}
<file_sep>//
//  CodableDemoVC.swift
//  SwiftTestbed
//
//  Created by firefly on 2020/11/16.
//

import Foundation

import UIKit

class CodableDemoVC: BaseViewController {
    
    lazy var archivedPath: String = {
        let homePath = NSHomeDirectory()
        let docPath = homePath + "/Documents"
        let teamPath = docPath + "/team"
        
        return teamPath
    }()
    
    lazy var userPath: String = {
        let homePath = NSHomeDirectory()
        let docPath = homePath + "/Documents"
        let userPath = docPath + "/user"
        
        return userPath
    }()
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
//        let archiveItem = UIBarButtonItem(title: "归档", style: UIBarButtonItem.Style.plain, target: self, action: #selector(archivie))
//        let unachiveItem = UIBarButtonItem(title: "解档", style: UIBarButtonItem.Style.plain, target: self, action: #selector(unarchivie))
        let archiveItem = UIBarButtonItem(title: "归档", style: UIBarButtonItem.Style.plain, target: self, action: #selector(archiveUser))
        let unachiveItem = UIBarButtonItem(title: "解档", style: UIBarButtonItem.Style.plain, target: self, action: #selector(unarchiveUser))
        
        self.navigationItem.rightBarButtonItems = [archiveItem, unachiveItem]
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        
        removeArchivedFile()
        
//        demoJson()
//        demoPlist()
//        decodeTeam()

//        archive()
//        unarchive()
//        archiveUser()
        
    }
    
    @objc func archivie () {
        print("\(type(of: self)).\(#function)")
        
        let p1 = Person(id: 1, name: "tom", age: 10, isMale: true)
        let p2 = Person(id: 2, name: "jim", age: 12, isMale: false)
        let p3 = Person(id: 3, name: "tim", age: 14, isMale: true)
        let p4 = Person(id: 4, name: "sam", age: 16, isMale: true)
        
        let members = [p1, p2, p3]
        let team = Team(master: p4, members: members)
        
        guard let plistData = try? PropertyListEncoder().encode(team) else {
            print("编码为plist失败")
            return
        }
        
        let dataPath = self.archivedPath + ".plist"
        
        do {
            try plistData.write(to: URL(fileURLWithPath: dataPath))
            print("plist data存储成功")
        } catch {
            print("plist data存储失败:", error)
        }
        
        let result = NSKeyedArchiver.archiveRootObject(plistData, toFile: self.archivedPath)
        print("archive plist data:", result)
        
        // josn
        do {
            let data = try JSONEncoder().encode(team)
            let jsonData = self.archivedPath + "_jsondata"
            do {
                try data.write(to: URL(fileURLWithPath: jsonData))
                print("json data --> file 成功")
            } catch {
                print("json data --> file 失败:", error)
            }
            
        } catch {
            print("team --> json data 失败")
        }
        
    }
    @objc func unarchivie () {
        print("\(type(of: self)).\(#function)")
        guard let data = NSKeyedUnarchiver.unarchiveObject(withFile: self.archivedPath) as? Data else {
            print("archived --> data 失败")
            return
        }
        do {
            let team = try PropertyListDecoder().decode(Team.self, from: data)
            print("解档成功")
            print("team:", team)
        } catch {
            print("data --> team 失败")
        }
    }
    
    func removeArchivedFile() {
        print("\(type(of: self)).\(#function)")
        
        
        if FileManager.default.fileExists(atPath: self.archivedPath) {
            // 存在
            
            do {
                try FileManager.default.removeItem(at: URL(fileURLWithPath: self.archivedPath))
                print("删除文件成功:", self.archivedPath)
            }
            catch {
                print("删除失败:", error)
            }
        } else {
            print("文件不存在:", self.archivedPath)
        }
    }
    
    func demoJson() {
        let p1 = Person(id: 1, name: "tom", age: 10, isMale: true)
        let p2 = Person(id: 2, name: "jim", age: 12, isMale: false)
        let p3 = Person(id: 3, name: "tim", age: 14, isMale: true)
        let p4 = Person(id: 4, name: "sam", age: 16, isMale: true)
        
        let members = [p1, p2, p3]
        let team = Team(master: p4, members: members)
        
        let jsonData = try? JSONEncoder().encode(team)
        if let data = jsonData {
            let jsonText = String(data: data, encoding: String.Encoding.utf8)
            print(jsonText ?? "")
            
            print("解码")
            let t = try? JSONDecoder().decode(Team.self, from: data)
            if let tm = t {
                print("master:", tm.master)
                for person in tm.members {
                    print("member:", person)
                }
            }
        }
    }
    
    @objc func archiveUser() {
        var user = User(name: "jim", age: 22, money: 36000.56)
        user.isMale = true
        let homePath = NSHomeDirectory()
        let docPath = homePath + "/Documents"
        let userPath = docPath + "/user"
        
        
        do {
            let data = try PropertyListEncoder().encode(user)
            let result = NSKeyedArchiver.archiveRootObject(data, toFile: userPath)
            print("archive result:", result)
        } catch {
            print("archived 失败:", error)
        }
    }
    
    @objc func unarchiveUser() {
        
        let info: [String : Any] = ["id" : 1002,
                    "is_male" : false,
                    "name" : "jobs",
                    "age" : 18,
                    "money" : 266.68,
        ]
        
        do {
            let data = try JSONSerialization.data(withJSONObject: info, options: JSONSerialization.WritingOptions.prettyPrinted)
            do {
                let user = try JSONDecoder().decode(User.self, from: data)
                print("user:", user)
            } catch {
                print("json data --> user 失败:", error)
            }
        } catch {
            print("dic --> json data 失败:", error)
        }
        
        
//        guard let user = NSKeyedUnarchiver.unarchiveObject(withFile: self.archivedPath) as? User else {
//            return
//        }
//
//        print("archived user:", user)
    }
}
<file_sep>//
//  SearchBarVC.swift
//  SwiftTestbed
//
//  Created by firefly on 2020/12/7.
//

import Foundation
import UIKit

class SearchBarVC: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.white
    }
}
<file_sep>//
//  SearchResultVC1.swift
//  SwiftTestbed
//
//  Created by firefly on 2020/12/7.
//

import Foundation
<file_sep>//
//  SubTable.swift
//  SwiftTestbed
//
//  Created by firefly on 2020/12/8.
//

import Foundation

struct Model {
    var name = ""
    var age = 0
}

class SubTable: Table<Model> {
    func displayData() {
        for item in dataArray {
            print(item.age, item.name)
        }
    }
}
<file_sep>//
//  MetatypeVC.swift
//  SwiftTestbed
//
//  Created by firefly on 2020/11/13.
//

import UIKit

class MetatypeVC: BaseViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        test()
    }
    
    func test() {
        print(type(of: self))
        print(type(of: MetatypeVC.self))
        
        let smiley = EmojiSmiley()
        printSmileyInfo(smiley)
        
        let intMetaType: Int.Type = Int.self
        let protocolMetaType: SomeProtocol.Protocol = SomeProtocol.self
        print("类型的元类型:", intMetaType) // Int
        print("协议的元类型:", protocolMetaType) // SomeProtocol
        
        print("可以使用元类型的实例来调用类型的静态方法")
        print(intMetaType.init(10)) // 10

        
        print("打印为协议类型")
        let s: SomeProtocol = "hello"
        printGenericInfo(s) // meta type: SomeProtocol
        
        print("打印为真实类型")
        betterPrintGenericInfo(s) // meta type: String
        
        String.someFunc()
        String.self.someFunc()
        type(of: "hello").someFunc()
    }
    
    func printSmileyInfo(_ value: Smiley) {
        let smileyType = type(of: value) // 通过类的对象获取类的元类型的实例
        print("print type:", smileyType)
        print("value type:", smileyType.text)
        print("value type:", Smiley.self.text) // 通过类名获取类的元类型的实例
        
        
    }
    
    func printGenericInfo<T>(_ value: T) {
        let metaType = type(of:value)
        print("meta type:", metaType)
    }
    func betterPrintGenericInfo<T>(_ value: T) {
        let metaType = type(of:value as Any)
        print("meta type:", metaType)
    }
    
}

protocol SomeProtocol {
    static func someFunc()
}
extension String: SomeProtocol {
    static func someFunc () {
        print("some func")
    }
}
<file_sep>//
//  GenericsVC.swift
//  SwiftTestbed
//
//  Created by firefly on 2020/12/8.
//

import Foundation

class GenericsVC: BaseViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let subTable = SubTable()
        for i in 1...5 {
            subTable.dataArray.append(Model(name: "jobs", age: i))
        }
        subTable.displayData()
    }
}
<file_sep>//
//  TestItem.swift
//  SwiftTestbed
//
//  Created by firefly on 2020/11/12.
//

import UIKit

struct TestItem {
    var title: String
    var type: UIViewController.Type
}
<file_sep>//
//  PageVC.swift
//  SwiftTestbed
//
//  Created by firefly on 2020/11/17.
//

import Foundation

import UIKit

class PageVC: BaseViewController {
    
    deinit {
        print("\(type(of: self)).\(#function)")
    }
}
<file_sep>//
//  NavigationController.swift
//  CloudBusiness
//
//  Created by firefly on 2020/10/26.
//

import UIKit

class NavigationController: UINavigationController {
    
    var mt: NavigationController.Type = NavigationController.self
    
    override func pushViewController(_ viewController: UIViewController, animated: Bool) {
        viewController.hidesBottomBarWhenPushed = self.viewControllers.count > 0
        super.pushViewController(viewController, animated: animated)
        
    }
}

extension NavigationController: UINavigationBarDelegate {
    func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
        print("\(type(of: self)).\(#function):", item)
        
        
        
        return true //!(self.topViewController is LazyLoadingVC)
    }
    func navigationBar(_ navigationBar: UINavigationBar, didPop item: UINavigationItem) {
        print("\(type(of: self)).\(#function):", item)
    }
}

<file_sep>//
//  IteamsVC.swift
//  SwiftTestbed
//
//  Created by firefly on 2020/12/8.
//

import Foundation
import UIKit

class IteamsVC: BaseViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.blue
    }
}
<file_sep>//
//  HUDVC.swift
//  SwiftTestbed
//
//  Created by firefly on 2021/1/28.
//

import Foundation
import MBProgressHUD

class HUDVC: BaseViewController {
    
    
    // MARK: - viewDidLoad
    override func viewDidLoad() {
        super.viewDidLoad()
        
        creatUI()
        configUI()
        addUI()
        constraintUI()
    }
    deinit {
        print("\(type(of: self)).\(#function)")
    }
    
    // MARK: - UI
    func creatUI() {
        
        let backItem = UIBarButtonItem(title: "back", style: .plain, target: self, action: #selector(back))
        let showItem = UIBarButtonItem(title: "shw", style: .plain, target: self, action: #selector(showIndicator))
        let dismissItem = UIBarButtonItem(title: "dis", style: .plain, target: self, action: #selector(dismissIndicator))
        
        navigationItem.leftBarButtonItems = [backItem, showItem, dismissItem]
        
        let doneItem = UIBarButtonItem(title: "done", style: .plain, target: self, action: #selector(showDone))
        let progressItem = UIBarButtonItem(title: "poges", style: .plain, target: self, action: #selector(showProgress))
        let failureItem = UIBarButtonItem(title: "fail", style: .plain, target: self, action: #selector(showFailure))
        let warningItem = UIBarButtonItem(title: "warn", style: .plain, target: self, action: #selector(showWarning))
        let switchItem = UIBarButtonItem(title: "swtich", style: .plain, target: self, action: #selector(swithToResult))

        
        navigationItem.rightBarButtonItems = [doneItem, progressItem, failureItem, warningItem, switchItem]

        let btn = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 40))
        btn.setTitle("test", for: .normal)
        btn.addTarget(self, action: #selector(btnTapped), for: .touchUpInside)
        
        view.addSubview(btn)
        
        btn.backgroundColor = .gray
        
    }
    
    func configUI() {
        
    }
    func addUI() {
        
    }
    func constraintUI() {
        
    }
    
    // MARK: - action
    @objc func btnTapped() {
        print("\(type(of: self)).\(#function)")
    }
    
    @objc func back() {
        navigationController?.popViewController(animated: true)
    }
    @objc func showIndicator() {
        HUD.showIndicator(message: "正在登录", in: view)
    }
    @objc func dismissIndicator() {
        
        HUD.hideIndicator(parentViewOrHud: view)
        
    }
    @objc func showDone() {
        if let hud = MBProgressHUD.forView(view) {
            hud.mode = .customView
            hud.customView = UIImageView()
            
            let image = UIImage(named: "Checkmark")?.withRenderingMode(.alwaysTemplate)
            let imageView = UIImageView(image: image)
            hud.customView = imageView
            hud.label.text = "完成"
            
            hud.hide(animated: true, afterDelay: 3)
        } else {
            HUD.showSuccess(text: "修改成功")
        }
    }
    @objc func showProgress() {
    }
    @objc func showFailure() {
        HUD.showFailure(text: "服务器繁忙20")
    }
    @objc func showWarning() {
        HUD.showWarning(text: "密码不正确")
    }
    @objc func swithToResult() {
        HUD.switchToSuccess(text: "登录成功", for: view)
    }
     
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        
        
//        HUD.showText("hello")
//        HUD.showText("hello", in:view)
        
//        let indefinateView = SVIndefiniteAnimatedView(frame: CGRect(x: 200, y: 150, width: 80, height: 80))
//        indefinateView.center = view.center
//        indefinateView.backgroundColor = UIColor.black
//
//        indefinateView.layer.cornerRadius = 6
//        indefinateView.layer.masksToBounds = true
//        indefinateView.strokeColor = .white;
//        indefinateView.strokeThickness = 3
//        indefinateView.radius = 30
//        view.addSubview(indefinateView)
    }
}

<file_sep>//
//  BaseVC.swift
//  CloudBusiness
//
//  Created by firefly on 2020/10/27.
//

import UIKit

class BaseViewController: UIViewController {
    override func viewDidLoad() {
        self.view.backgroundColor = UIColor.white
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        
        print("\(type(of: self)).\(#function)")
        if navigationController == nil && presentingViewController == nil {
            viewControllerDidDismiss()
        } else {
            print("ViewController does not dismiss")
        }
    }
    
    func viewControllerDidDismiss() {
        print("\(type(of: self)).\(#function)")
    }
    
}
<file_sep>//
//  PresetationDemoVC.swift
//  SwiftTestbed
//
//  Created by firefly on 2021/1/16.
//

import Foundation
import UIKit

class PresetationDemoVC: BaseViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        creatUI()
        configUI()
        addUI()
        constraintUI()
    }
    
    func creatUI() {
        
    }
    func configUI() {
        
    }
    func addUI() {
        
    }
    func constraintUI() {
        
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        let vc = PayPasswordVC()
        vc.modalTransitionStyle = .crossDissolve
        vc.modalPresentationStyle = .custom
        vc.transitioningDelegate = vc
        self.present(vc, animated: true, completion: nil)
    }
}
