<repo_name>Kxyaaad/CloudKit_Demo<file_sep>/CloudKit_Demo/Tools/ActivityIndicator.swift
//
//  ActivityIndicator.swift
//  CloudKit_Demo
//
//  Created by Mac on 2020/4/20.
//  Copyright © 2020 Mac. All rights reserved.
//

import Foundation
import UIKit

class  ActivityIndicator {
    
    lazy var loading = UIActivityIndicatorView()
    
    lazy var loadingBGV = UIView()
    
    static var shared:ActivityIndicator = {
        let instance = ActivityIndicator()
        return instance
    }()
    
   
    func start(viewController:UIViewController, complition:@escaping ()->()) {
        
        self.loadingBGV = UIView.init(frame: viewController.view.frame)
        self.loadingBGV.backgroundColor = UIColor.init(white: 0.3, alpha: 0.3)
        self.loadingBGV.alpha = 0
        viewController.view.addSubview(self.loadingBGV)
        
        UIView.animate(withDuration: 0.3, animations: {
            self.loadingBGV.alpha = 1
        }) { (_) in
            self.loading.frame = CGRect(origin: viewController.view.center, size: CGSize(width: 60, height: 60))
            self.loading.center = viewController.view.center
            self.loading.backgroundColor = .white
            self.loading.layer.cornerRadius = 10
            
            viewController.view.addSubview(self.loading)
            
            self.loading.startAnimating()
            
            //最后执行
            complition()
        }
    }
    
    func dismiss(viewController:UIViewController, compolition:@escaping ()->()) {
        DispatchQueue.main.async {
            self.loading.stopAnimating()
            self.loading.removeFromSuperview()
            UIView.animate(withDuration: 0.3, animations: {
                self.loadingBGV.alpha = 0
            }) { (_) in
                self.loadingBGV.removeFromSuperview()
                compolition()
            }
        }
        
    }
 
}
<file_sep>/CloudKit_Demo/Views/BaseViewController.swift
//
//  BaseViewController.swift
//  CloudKit_Demo
//
//  Created by Mac on 2020/4/21.
//  Copyright © 2020 Mac. All rights reserved.
//

import UIKit

class BaseViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default.addObserver(self, selector: #selector(loginSuccess(Noti:)), name: NSNotification.Name(rawValue: UserLoginSuccessedNotification), object: nil)
    }
    
    deinit {
           ///注销通知
           NotificationCenter.default.removeObserver(self)
       }
    
    @objc private func loginSuccess(Noti: Notification) {
           print("收到登录成功通知")
        ///强制刷新界面
           view = nil
       }
}
<file_sep>/Podfile
# Uncomment the next line to define a global platform for your project
platform :ios, '9.0'
target 'CloudKit_Demo' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!
  pod 'SnapKit', '~> 5.0.0'
  pod 'Kingfisher'
  pod "SDWebImage"
  # Pods for CloudKit_Demo

end
<file_sep>/CloudKit_Demo/Views/MineViews/SettingViewController.swift
//
//  SettingViewController.swift
//  CloudKit_Demo
//
//  Created by Mac on 2020/4/21.
//  Copyright © 2020 Mac. All rights reserved.
//

import UIKit

class SettingViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        self.title = "设置"
        DispatchQueue.main.async {
            self.setUI()
        }
        
    }
    
    
    private func setUI() {
        let quitIMG = UIImageView(image: UIImage(named: "tuichu"))
        quitIMG.frame = CGRect(origin: .zero, size: CGSize(width: 30, height: 30))
        quitIMG.center = CGPoint(x: 35, y: self.navigationController!.navigationBar.frame.height + UIApplication.shared.statusBarFrame.height + 50)
        
        view.addSubview(quitIMG)
        
        let quitBtn = UIButton(frame: CGRect(origin: CGPoint(x: 60, y: self.navigationController!.navigationBar.frame.height + UIApplication.shared.statusBarFrame.height + 35), size: CGSize(width: 50, height: 30)))
        quitBtn.setTitle("退出", for: [])
        quitBtn.setTitleColor(UIColor.dynamicColor(lightColor: .black, darkColor: .white), for: [])
        quitBtn.addTarget(self, action: #selector(quitAccount), for: .touchUpInside)
        view.addSubview(quitBtn)
        
        let lineView = UIView(frame: CGRect(origin: CGPoint(x: 60, y: self.navigationController!.navigationBar.frame.height + UIApplication.shared.statusBarFrame.height + 70), size: CGSize(width: self.view.frame.width - 80, height: 1)))
        lineView.backgroundColor = UIColor.dynamicColor(lightColor: .systemGray3, darkColor: .white)
        view.addSubview(lineView)
    }
    
    @objc func quitAccount() {
        let userDefault = UserDefaults.standard
        userDefault.set(nil, forKey: "userName")
        let vc = LoginViewController()
        vc.modalPresentationStyle = .fullScreen
        self.present(vc, animated: true) {
            self.navigationController?.popViewController(animated: true)
        }
    }

}
<file_sep>/CloudKit_Demo/Views/RegisterViewController.swift
//
//  RegisterViewController.swift
//  CloudKit_Demo
//
//  Created by Mac on 2020/4/20.
//  Copyright © 2020 Mac. All rights reserved.
//

import UIKit
import CloudKit

class RegisterViewController: BaseViewController {
    
    let userName = UITextField()
    
    let passWord = UITextField()
    
    let comfirmPW = UITextField()
    
    let register = UIButton()
    
    let login = UIButton()
    
    let loading = UIActivityIndicatorView.init(style: .medium)
    
    let loadingBGV = UIView()
    
    var isisRegisteSuccessed : isRegisteSuccessedDelegate?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.setUI()
    }
    
    private func setUI() {
        view.backgroundColor = .systemBlue
        view.addSubview(self.userName)
        view.addSubview(self.passWord)
        view.addSubview(self.comfirmPW)
        view.addSubview(self.register)
        
        self.userName.frame.size = CGSize(width: ScreenWidth / 2, height: 40)
        self.userName.backgroundColor = .white
        self.userName.center = CGPoint(x: ScreenWidth/2, y: ScreenHeight/2-100)
        self.userName.layer.cornerRadius = 10
        self.userName.textColor = .black
        self.userName.placeholder = "请输入用户名"
        
        self.passWord.frame.size = CGSize(width: ScreenWidth / 2, height: 40)
        self.passWord.backgroundColor = .white
        self.passWord.center = CGPoint(x: ScreenWidth/2, y: ScreenHeight/2 - 40)
        self.passWord.layer.cornerRadius = 10
        self.passWord.placeholder = "请输入密码"
        self.passWord.textColor = .black
        self.passWord.isSecureTextEntry = true
        
        self.comfirmPW.frame.size = CGSize(width: ScreenWidth / 2, height: 40)
        self.comfirmPW.backgroundColor = .white
        self.comfirmPW.center = CGPoint(x: ScreenWidth/2, y: ScreenHeight/2 + 20)
        self.comfirmPW.layer.cornerRadius = 10
        self.comfirmPW.textColor = .black
        self.comfirmPW.placeholder = "请确认密码"
        self.comfirmPW.isSecureTextEntry = true
        
        self.register.frame.size = CGSize(width: 100, height: 50)
        self.register.center = CGPoint(x: ScreenWidth/2, y: ScreenHeight/2+100)
        self.register.setTitle("注册", for: [])
        self.register.setTitleColor(.white, for: .normal)
        self.register.addTarget(self, action: #selector(RegisterAccount), for: .touchUpInside)
        
    }
    
    @objc func RegisterAccount() {
        
        if self.userName.text == "" {
            let alert = UIAlertController(title: "请输入您想注册的用户名", message: nil, preferredStyle: .alert)
            
            let ac1 = UIAlertAction(title: "确认", style: .default) { (_) in
                
            }
            alert.addAction(ac1)
            self.present(alert, animated: true, completion: nil)
            return
        }else if self.userName.text!.allSatisfy({ (char) -> Bool in
            return char.isWhitespace
        }) {
            let alert = UIAlertController(title: "用户名不得为空", message: nil, preferredStyle: .alert)
            
            let ac1 = UIAlertAction(title: "确认", style: .default) { (_) in
                
            }
            alert.addAction(ac1)
            self.present(alert, animated: true, completion: nil)
            
            return
        }
        
        if self.passWord.text != self.comfirmPW.text {
            let alert = UIAlertController(title: "两次输入密码不一致", message: nil, preferredStyle: .alert)
            
            let ac1 = UIAlertAction(title: "确认", style: .default) { (_) in
                
            }
            alert.addAction(ac1)
            self.present(alert, animated: true, completion: nil)
            
            return
        }
        
        ///开始提交注册
        
        ActivityIndicator.shared.start(viewController: self) {
            self.registerID()
        }
        
    }
    
    //提交注册
    private func registerID() {
        let registerRecordID = CKRecord.ID(recordName: self.userName.text!)
        let registerRecord = CKRecord(recordType: "UserAccouts", recordID: registerRecordID)
        
        registerRecord["PassWord"] = self.passWord.text!
        
        let myContainer = CKContainer.default()
        let pbData = myContainer.publicCloudDatabase
        
        pbData.save(registerRecord) { (record, erroe) in
            if let error = erroe {
                DispatchQueue.main.async {
                    let alert = UIAlertController(title: "错误", message: error.localizedDescription, preferredStyle: .alert)
                    
                    let ac1 = UIAlertAction(title: "确认", style: .default) { (_) in
                        
                    }
                    alert.addAction(ac1)
                    self.present(alert, animated: true, completion: {
                        ActivityIndicator.shared.dismiss(viewController: self) {
                            
                        }
                    })
                }
                
                
                return
            }
            print("注册结果",record as Any)
            
            DispatchQueue.main.async {
                let userDefault = UserDefaults.standard
                userDefault.set(self.userName.text!, forKey: "userName")
                
                ///发送登录成功通知
                NotificationCenter.default.post(Notification(name: Notification.Name(rawValue: UserLoginSuccessedNotification)))
            }
            
           
            ActivityIndicator.shared.dismiss(viewController: self) {
                self.dismiss(animated: true) {
                    self.isisRegisteSuccessed?.isisRegisteSuccessed(isisRegisteSuccessed: true)
                }
            }
        }
    }
}

protocol isRegisteSuccessedDelegate  {
    func isisRegisteSuccessed(isisRegisteSuccessed:Bool)
}
<file_sep>/CloudKit_Demo/Views/addNewController.swift
//
//  addNewController.swift
//  CloudKit_Demo
//
//  Created by Mac on 2020/4/8.
//  Copyright © 2020 Mac. All rights reserved.
//

import UIKit
import SnapKit
import CloudKit
import Photos

class addNewController: BaseViewController {
    
    var textInput : UITextView?
    
    var imgCollection : UICollectionView?
    
    var imgsData : Array<UIImage> = []
    
    var imgsURL : Array<URL> = []
    ///发布按钮
    var postBtn = UIButton()
    
    //用于删除image的view
    lazy var delateView = UIView()
    
    lazy var delateLabel = UILabel()
    //拖拽图片的index
    lazy var indexPath = IndexPath()
    
    lazy var DragedImg = UIImageView()
    
    lazy var cellPoint = CGPoint()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setUpUI()
        // Do any additional setup after loading the view.
    }
    
    private func setUpUI() {
        view.backgroundColor = UIColor.dynamicColor(lightColor: UIColor.init(white: 0.8, alpha: 1), darkColor: UIColor.init(white: 0.2, alpha: 1))
        
        self.postBtn.setTitle("发布", for: [])
        self.postBtn.setTitleColor(UIColor.dynamicColor(lightColor: .systemBlue, darkColor: .systemGreen), for: [])
        self.postBtn.addTarget(self, action: #selector(upLoad), for: .touchUpInside)
        view.addSubview(self.postBtn)
        self.postBtn.snp.makeConstraints { (make) in
            make.rightMargin.equalTo(20)
            make.topMargin.equalTo(20)
            make.width.equalTo(100)
            make.height.equalTo(50)
        }
        
        //输入框
        self.textInput = UITextView()
        self.textInput?.font = .systemFont(ofSize: 15)
        self.textInput?.layer.cornerRadius = 10
        self.textInput?.delegate = self
        self.textInput?.backgroundColor = UIColor.dynamicColor(lightColor: UIColor.init(white: 1, alpha: 1), darkColor: UIColor.init(white: 0, alpha: 1))
        view.addSubview(self.textInput!)
        self.textInput?.becomeFirstResponder()
        
        self.textInput?.frame = CGRect(origin: CGPoint(x: 20, y: 70), size: CGSize(width: self.view.frame.width-40, height: 200))
        
        
        
        //选择图片
        let layout = UICollectionViewFlowLayout()
        layout.itemSize = CGSize(width: 80, height: 80)
        layout.minimumLineSpacing = 5
        layout.minimumInteritemSpacing = 5
        layout.scrollDirection = .vertical
        layout.sectionInset = UIEdgeInsets.init(top: 10, left: 10, bottom: 10, right: 10)
        
        self.imgCollection = UICollectionView(frame: CGRect(origin: CGPoint(x: 20, y: 290), size: CGSize(width: self.view.frame.width - 40, height: 400)), collectionViewLayout: layout)
        self.imgCollection?.delegate = self
        self.imgCollection?.dataSource = self
        self.imgCollection?.register(pickImageCell.self, forCellWithReuseIdentifier: "PICKIMAGE")
        self.imgCollection?.backgroundColor = UIColor.dynamicColor(lightColor: UIColor.init(white: 0.8, alpha: 1), darkColor: UIColor.init(white: 0.2, alpha: 1))
        
        
        self.imgCollection?.setCollectionViewLayout(layout, animated: true)
        
        view.addSubview(self.imgCollection!)
        
    }
    
    
    @objc
    private func upLoad() {
        ActivityIndicator.shared.start(viewController: self) {
            
        }
        //新建
        let artworkRecordID = CKRecord.ID()
        let artworkRecord = CKRecord(recordType: "BlogData", recordID: artworkRecordID)
        artworkRecord["des"] = self.textInput!.text
        artworkRecord["Artist"] = UserDefaults.standard.string(forKey: "userName")!
        //添加图片
        var imgAssets : Array<CKAsset> = []
        for i in 0..<self.imgsURL.count {
            let photoAsset = CKAsset(fileURL: self.imgsURL[i])
            imgAssets.append(photoAsset)
        }
        
        artworkRecord["images"] = imgAssets

        
        //to save
        //公共数据库
        let myContainer = CKContainer.default()
        let publicDB = myContainer.publicCloudDatabase
        
        publicDB.save(artworkRecord) { (record, error) in
            if let error = error {
                print("错误",error)
                return
            }
            print("保存完毕")
            ActivityIndicator.shared.dismiss(viewController: self) {
                self.dismiss(animated: true) {
                    NotificationCenter.default.post(Notification(name: Notification.Name(rawValue: UpdataBlogNotification)))
                }
            }
        }
        
    }
    
    
}


extension addNewController:UITextViewDelegate {
    func textViewDidEndEditing(_ textView: UITextView) {
        print("完成")
    }
    
    
}

extension addNewController:UICollectionViewDelegate,UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return self.imgsData.count + 1
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PICKIMAGE", for: indexPath) as! pickImageCell
        if indexPath.row  == self.imgsData.count {
            cell.imgView?.image = UIImage.init(named: "tianjiatupian")
        }else if indexPath == self.indexPath {
            cell.imgView?.image = nil
        } else {
            cell.imgView?.image = self.imgsData[indexPath.row]
            cell.longPress.addTarget(self, action: #selector(longPress(longPress:)))
        }
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        if indexPath.row == self.imgsData.count{
            self.getAlbumList()
        }
    }
    
    //长按功能
    @objc
    func longPress(longPress: UILongPressGestureRecognizer) {
        switch longPress.state {
        case .began:
            self.delateViewShowOn()
            self.dragBegan(point: longPress.location(in: self.imgCollection!), cellPoint: longPress.location(in: longPress.view))
        case .changed:
            self.dragChanged(point: longPress.location(in: self.view))
        case .ended:
            self.dragEnd(point: longPress.location(in: self.view))
        default:
            print("default")
        }
        
        
        
    }
    
    private func dragBegan(point:CGPoint, cellPoint:CGPoint) {
        
        self.indexPath = self.imgCollection!.indexPathForItem(at: point)!
        self.cellPoint = cellPoint
        print(self.indexPath, cellPoint)
        
    }
    
    private func dragChanged(point: CGPoint) {
        self.imgCollection?.reloadData()
        self.view.insertSubview(self.DragedImg, belowSubview: self.delateView)
        self.DragedImg.frame = CGRect(origin: CGPoint(x: point.x - self.cellPoint.x, y: point.y  - cellPoint.y), size: CGSize(width: 80, height: 80))
        
        self.DragedImg.image = self.imgsData[indexPath.row]
        
        if point.y > self.view.frame.height - 100 - self.additionalSafeAreaInsets.bottom {
            self.delateLabel.text = "松开以删除"
            self.delateView.alpha = 0.9
        }else {
            self.delateLabel.text = "拖至此处以删除"
            self.delateView.alpha = 0.7
        }
        
    }
    
    private func dragEnd(point: CGPoint) {
        //
        if point.y > self.view.frame.height - 100 - self.additionalSafeAreaInsets.bottom {
            self.imgsData.remove(at: self.indexPath.row)
            self.imgsURL.remove(at: self.indexPath.row)
            self.indexPath = IndexPath()
            self.imgCollection?.reloadData()
            self.DragedImg.image = UIImage()
            self.DragedImg.removeFromSuperview()
            self.delateViewShowOff()
        }else {
            self.indexPath = IndexPath()
            self.imgCollection?.reloadData()
            self.DragedImg.image = UIImage()
            self.DragedImg.removeFromSuperview()
            self.delateViewShowOff()
        }
        
        
    }
    
    func collectionView(_ collectionView: UICollectionView, canMoveItemAt indexPath: IndexPath) -> Bool {
        return true
    }
    
    
    ///用于删除的View
    private func delateViewShowOn() {
        
        self.delateView.frame = CGRect(x: 0, y: self.view.frame.height, width: self.view.frame.width, height: 300 + self.additionalSafeAreaInsets.bottom)
        self.delateView.backgroundColor = UIColor.dynamicColor(lightColor: .red, darkColor: .red)
        self.delateView.alpha = 0.7
        view.addSubview(self.delateView)
        
        self.delateView.addSubview(self.delateLabel)
        
        self.delateLabel.font = .boldSystemFont(ofSize: 20)
        self.delateLabel.adjustsFontSizeToFitWidth = true
        self.delateLabel.textAlignment = .center
        self.delateLabel.text = "拖至此处以删除"
        self.delateLabel.textColor = .white
        self.delateLabel.snp.makeConstraints { (make) in
            make.centerX.equalToSuperview()
            make.width.equalToSuperview()
            make.topMargin.equalTo(30)
        }
        
        UIView.animate(withDuration: 0.25) {
            self.delateView.frame = CGRect(x: 0, y: self.view.frame.height - 100 - self.additionalSafeAreaInsets.bottom, width: self.view.frame.width, height: 300 + self.additionalSafeAreaInsets.bottom)
        }
    }
    
    private func delateViewShowOff() {
        UIView.animate(withDuration: 0.25, animations: {
            self.delateView.frame = CGRect(x: 0, y: self.view.frame.height, width: self.view.frame.width, height: 300 + self.additionalSafeAreaInsets.bottom)
        }) { (_) in
            self.delateView.removeFromSuperview()
        }
    }
    
}


extension addNewController:UIImagePickerControllerDelegate,UINavigationControllerDelegate {
    @objc private func getAlbumList() {
        let Alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
        let albumAction = UIAlertAction(title: "相册", style: .default) { (_) in
            self.album()
        }
        
        let tokePhotoAction = UIAlertAction(title: "照相", style: .default) { (_) in
            self.takePhoto()
        }
        
        let cancelAction = UIAlertAction(title: "取消", style: .cancel, handler: nil)
        
        Alert.addAction(albumAction)
        Alert.addAction(tokePhotoAction)
        Alert.addAction(cancelAction)
        self.present(Alert, animated: true, completion: nil)
    }
    
    private func album() {
        let albumPicker = UIImagePickerController()
        albumPicker.sourceType = .photoLibrary
        albumPicker.delegate = self
        albumPicker.allowsEditing = true
        self.present(albumPicker, animated: true, completion: nil)
    }
    
    private func takePhoto() {
        if UIImagePickerController.isSourceTypeAvailable(.camera) {
            let cameraPicker = UIImagePickerController()
            cameraPicker.delegate = self
            cameraPicker.allowsEditing = true
            cameraPicker.sourceType = .camera
            self.present(cameraPicker, animated: true, completion: nil)
        }else{
            let alter = UIAlertController(title: "暂不支持拍照", message: "", preferredStyle: .alert)
            let action = UIAlertAction(title: "确定", style: .cancel, handler: nil)
            alter.addAction(action)
            self.present(alter, animated: true, completion: nil)
        }
    }
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        print("完成获取照片")
        let tokedPhoto = info[.editedImage] as! UIImage
        self.imgsData.insert(tokedPhoto, at: 0)
    
        if picker.sourceType == .camera {
//            //初始化一个标识符
            var localId: String!
            PHPhotoLibrary.shared().performChanges({
                let result = PHAssetChangeRequest.creationRequestForAsset(from: tokedPhoto)
                let assetPlaceHolder = result.placeholderForCreatedAsset
                //保存标志符
                localId = assetPlaceHolder?.localIdentifier
            }) { (isSuccessed, error) in
                if isSuccessed {
                    //获取保存图片的路径
                    print("保存拍照图片")

                    let assetResult = PHAsset.fetchAssets(withLocalIdentifiers: [localId], options: nil)
                    let asset = assetResult[0]

                    asset.requestContentEditingInput(with: PHContentEditingInputRequestOptions()) { (PHContentEditingInput, [AnyHashable : Any]) in
                        print("拍照存储地址", PHContentEditingInput?.fullSizeImageURL)
                        self.imgsURL.insert((PHContentEditingInput?.fullSizeImageURL)!, at: 0)
                    }
                }else {
                    print(error?.localizedDescription)
                }
            }
        }else if picker.sourceType == .photoLibrary {
            let imgURL = info[.imageURL] as! URL
            self.imgsURL.insert(imgURL, at: 0)
            
            
        }
        dismiss(animated: true) {
            self.imgCollection?.reloadData()
        }
    }
    
    
}
<file_sep>/CloudKit_Demo/Tools/extension.swift
//
//  extension.swift
//  CloudKit_Demo
//
//  Created by Mac on 2020/4/21.
//  Copyright © 2020 Mac. All rights reserved.
//

import Foundation
import UIKit
import NotificationCenter


extension UIColor {
    class func dynamicColor (lightColor: UIColor, darkColor:UIColor) -> UIColor {
        let color = UIColor.init { (TC) -> UIColor in
            switch TC.userInterfaceStyle {
            case .dark:
                return darkColor
            case .light:
                return lightColor
            case .unspecified:
                return lightColor
            default:
                return lightColor
            }
        }
        return color
    }
    
    
}


<file_sep>/CloudKit_Demo/Views/Cells/pickImageCell.swift
//
//  pickImageCell.swift
//  CloudKit_Demo
//
//  Created by Mac on 2020/4/9.
//  Copyright © 2020 Mac. All rights reserved.
//

import UIKit

class pickImageCell: UICollectionViewCell {
    
    var imgView : UIImageView?
    var longPress : UILongPressGestureRecognizer!
    var delateBtn : UIButton?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        self.imgView = UIImageView()
        self.imgView?.frame = CGRect(origin: .zero, size: CGSize(width: self.frame.width, height: self.frame.height))
        self.imgView?.layer.cornerRadius = 6
        self.addSubview(self.imgView!)
        self.longPress = UILongPressGestureRecognizer()
        self.addGestureRecognizer(self.longPress)
        
        
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
<file_sep>/CloudKit_Demo/Views/LoginViewController.swift
//
//  LoginViewController.swift
//  CloudKit_Demo
//
//  Created by Mac on 2020/4/16.
//  Copyright © 2020 Mac. All rights reserved.
//

import UIKit
import CloudKit

class LoginViewController: UIViewController {
    
    let userName = UITextField()
    
    let passWord = UITextField()
    
    let register = UIButton()
    
    let login = UIButton()
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view.
        self.setUI()
        
        
    }
    
    private func setUI() {
        view.backgroundColor = .systemBlue
        view.addSubview(self.userName)
        view.addSubview(self.passWord)
        view.addSubview(self.login)
        view.addSubview(self.register)
        
        self.userName.frame.size = CGSize(width: ScreenWidth / 2, height: 40)
        self.userName.backgroundColor = .white
        self.userName.center = CGPoint(x: ScreenWidth/2, y: ScreenHeight/2-100)
        self.userName.layer.cornerRadius = 10
        self.userName.textColor = .black
        self.userName.placeholder = "请输入用户名"
        
        self.passWord.frame.size = CGSize(width: ScreenWidth / 2, height: 40)
        self.passWord.backgroundColor = .white
        self.passWord.center = CGPoint(x: ScreenWidth/2, y: ScreenHeight/2 - 40)
        self.passWord.layer.cornerRadius = 10
        self.passWord.textColor = .black
        self.passWord.placeholder = "请输入密码"
        
        self.passWord.isSecureTextEntry = true
        
        self.login.frame.size = CGSize(width: 100, height: 50)
        self.login.center = CGPoint(x: ScreenWidth/2, y: ScreenHeight/2+40)
        self.login.setTitle("登录", for: [])
        self.login.setTitleColor(.white, for: .normal)
        self.login.addTarget(self, action: #selector(Login), for: .touchUpInside)
        
        self.register.frame.size = CGSize(width: 100, height: 50)
        self.register.center = CGPoint(x: ScreenWidth/2, y: ScreenHeight/2+100)
        self.register.setTitle("注册", for: [])
        self.register.setTitleColor(.white, for: .normal)
        self.register.addTarget(self, action: #selector(Register), for: .touchUpInside)
        
    }
    
    
    @objc func Login() {
        if self.userName.text != "" && self.passWord.text != "" {
            let pbData = CKContainer.default().publicCloudDatabase
            let predicate = NSPredicate(format: "PassWord = %@", self.userName.text!)
            print(predicate)
            pbData.perform(CKQuery.init(recordType: "UserAccouts", predicate: predicate), inZoneWith: nil) { (records, error) in
                if error == nil {
                    print("查询结果", records as Any)
                    if records == [] {
                        ///主线程中进行界面更新，否则会崩溃
                        DispatchQueue.main.async {
                            let alert = UIAlertController(title: "未找到相关用户", message: "请确认您输入的用户名是否正确，或请您注册。", preferredStyle: .alert)
                            
                            let ac1 = UIAlertAction(title: "注册", style: .default) { (_) in
                                //跳转到注册页面
                                self.Register()
                            }
                            
                            let ac2 = UIAlertAction(title: "取消", style: .cancel) { (_) in
                                
                            }
                            alert.addAction(ac1)
                            alert.addAction(ac2)
                            self.present(alert, animated: true, completion: nil)
                        }
                        
                    }else{
                        if records![0]["PassWord"] == self.passWord.text  {
                            print("登录成功")
                            DispatchQueue.main.async {
                                let userDefault = UserDefaults.standard
                                userDefault.set(self.userName.text!, forKey: "userName")
                                
                                ///发送登录成功通知
                                NotificationCenter.default.post(Notification(name: Notification.Name(rawValue: UserLoginSuccessedNotification)))
                                self.dismiss(animated: false, completion: nil)
                            }
                        }
                    }
                    
                }else {
                    print("查询错误",error?.localizedDescription as Any)
                }
            }
            
            
        }else {
            let alert = UIAlertController(title: nil, message: "用户名和密码不能为空！", preferredStyle: .alert)
            let ac = UIAlertAction(title: "确定", style: .cancel) { (_) in
                
            }
            
            alert.addAction(ac)
            self.present(alert, animated: true, completion: nil)
        }
        
    }
    
    @objc func Register() {
        let vc = RegisterViewController()
        vc.isisRegisteSuccessed = self
        self.present(vc, animated: true, completion: nil)
    }
    
}

extension LoginViewController:isRegisteSuccessedDelegate{
    func isisRegisteSuccessed(isisRegisteSuccessed: Bool) {
        self.dismiss(animated: true, completion: nil)
    }
    
    
}

<file_sep>/CloudKit_Demo/Tools/CoreDataManager.swift
//
//  CoreDataManager.swift
//  CloudKit_Demo
//
//  Created by Mac on 2020/5/8.
//  Copyright © 2020 Mac. All rights reserved.
//

import Foundation
import CoreData
import CloudKit

class CoreDataManager {
    static let shared = CoreDataManager()
    
    //MARK: - Core Data stack
    
    lazy var persistentContainer: NSPersistentContainer = {
    
        let container = NSPersistentContainer(name: "CloudKit_Demo")
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        return container
    }()
    
    static var managedContext: NSManagedObjectContext{
        let context = CoreDataManager.shared.persistentContainer.viewContext

        return context
    }

    // MARK: - Core Data Saving support

    func saveContext () {
        let context = persistentContainer.viewContext
        if context.hasChanges {
            do {
                try context.save()
            } catch {
                let nserror = error as NSError
                fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
            }
        }
    }
}

extension CoreDataManager {
    static func saveBlogData(name: String?, des: String?) {
        let Blog = BlogData(context: managedContext)
        Blog.name = name
        Blog.des = des
        CoreDataManager.shared.saveContext()
        
    }
    
    static func saveCDRecords(record:CKRecord) {
        let archiver = NSKeyedArchiver.init(requiringSecureCoding: false)
        record.encode(with: archiver)
        archiver.finishEncoding()
        let Record = CDRecords(context: managedContext)
        Record.cd_record = archiver.encodedData
        Record.writeDate = record.creationDate!
        CoreDataManager.shared.saveContext()
    }
    
}
<file_sep>/CloudKit_Demo/Views/Cells/MainTableViewCell.swift
//
//  MainTableViewCell.swift
//  CloudKit_Demo
//
//  Created by Mac on 2020/4/15.
//  Copyright © 2020 Mac. All rights reserved.
//

import UIKit
import CloudKit
import Kingfisher
import SnapKit

class MainTableViewCell: UITableViewCell {
    
    lazy var imageScroller = UIScrollView()
    
    var record : CKRecord!
    
    var desLabelHeight : CGFloat?
    
    var nameLab : UILabel?
    
    var desLabel : UILabel?
    
    var timeLab : UILabel?
    
    ///避免cell重复加载控件造成卡顿和内存溢出
    var isLoad = false
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
     
        self.setUI()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }
    
    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        self.selectionStyle = .none
        // Configure the view for the selected state
    }
    
    
}

extension MainTableViewCell: UIScrollViewDelegate {
    
    public func setUI() {
        nameLab = UILabel(frame: CGRect(origin: CGPoint(x: 30, y: 10), size: CGSize(width: self.frame.width, height: 20)))
//        nameLab.text = self.record!["Artist"] as? String
        
        self.addSubview(nameLab!)
        
        desLabel = UILabel(frame: CGRect(origin: CGPoint(x: 10, y: 30), size: CGSize(width: self.frame.width - 20, height: self.desLabelHeight ?? 30)))
//        desLabel.text = self.record!["des"] as? String
        desLabel!.numberOfLines = 0
        desLabel!.font = UIFont.systemFont(ofSize: 15)
        self.addSubview(desLabel!)
        
        self.imageScroller = UIScrollView()
        self.imageScroller.isPagingEnabled = true
        self.imageScroller.backgroundColor = .red
        self.imageScroller.showsHorizontalScrollIndicator = false
        self.addSubview(self.imageScroller)
            
        
        timeLab = UILabel(frame: CGRect(origin: CGPoint(x: 20, y: 35 + (self.desLabelHeight ?? 30 ) + UIScreen.main.bounds.width), size: CGSize(width: self.frame.width, height: 20)))
//        timeLab?.text = self.record?.creationDate?.description
        timeLab?.textColor = UIColor.dynamicColor(lightColor: UIColor.init(white: 0.4, alpha: 1), darkColor: .white)
        timeLab?.font = UIFont.systemFont(ofSize: 13)
        self.addSubview(timeLab!)
        

    }
    
    ///获取数据后再加载图片
    public func loadImage() {
        
        let images = self.record!["images"] as! Array<CKAsset>
        
        if images.count > 0 {
            for i in 0..<images.count{
                let imageView = UIImageView(frame:  CGRect(origin: CGPoint(x: CGFloat(i) * UIScreen.main.bounds.width, y: 0), size: CGSize(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.width)))
                imageView.tag = i
                imageView.backgroundColor = UIColor(white: CGFloat(Double(i)/10.0), alpha: 1)
                self.imageScroller.addSubview(imageView)
               
                do {
                    imageView.kf.setImage(with: images[i].fileURL)
                }catch {
                    print("图片读取错误")
                }
                imageView.kf.setImage(with:  images[i].fileURL!)
            }
        }
        
    }

}
<file_sep>/CloudKit_Demo/Views/ViewController.swift
//
//  ViewController.swift
//  CloudKit_Demo
//
//  Created by Mac on 2020/4/8.
//  Copyright © 2020 Mac. All rights reserved.
//

import UIKit
import CloudKit
import Kingfisher
import CoreData

class ViewController: BaseViewController, NSFetchedResultsControllerDelegate {
    
    var btn : UIButton?
    var imgView = UIImageView()
    var tableView = UITableView()
    var Records : Array<CKRecord> = []
    var refresh = UIRefreshControl()

    var isLoadAll = false //是否加载完最早的一条数据
    var RecordIDs : Array<CKRecord.ID> = []
    
    ///CloudKit + CoreData
    var fetchedResultsController: NSFetchedResultsController<BlogData>?
    

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        if UserDefaults.standard.value(forKey: "userName") != nil {
            readCoreData()
            self.setUI()
                
            if UserDefaults.standard.value(forKey: "cursor") != nil {
                self.refreshData()
            }else {
                self.QuaryData()
            }
        }
        
        
        
        NotificationCenter.default.addObserver(self, selector: #selector(QuaryData), name: NSNotification.Name(UpdataBlogNotification), object: nil)
        
    }
    
    deinit {
        ///注销通知
        NotificationCenter.default.removeObserver(self)
    }
    
    override func viewWillAppear(_ animated: Bool) {
        
        let userDefault = UserDefaults.standard
        if userDefault.value(forKey: "userName") == nil {
            let vc = LoginViewController()
            vc.modalPresentationStyle = .fullScreen
            self.present(vc, animated: false, completion: nil)
        }
        
    }
    
    private func setUI() {
        self.tableView = UITableView(frame: CGRect(origin: CGPoint(x: 0, y: self.navigationController!.navigationBar.frame.height+UIApplication.shared.statusBarFrame.height), size: CGSize(width: self.view.frame.width, height: self.view.frame.height - (self.navigationController!.navigationBar.frame.height+UIApplication.shared.statusBarFrame.height) - self.tabBarController!.tabBar.frame.height)))
        self.tableView.backgroundColor = UIColor.dynamicColor(lightColor: .white, darkColor: .black)
        self.tableView.register(MainTableViewCell.self, forCellReuseIdentifier: "MainCell")
        self.tableView.delegate = self
        self.tableView.dataSource = self
        self.tableView.showsVerticalScrollIndicator = false
        
        self.tableView.addSubview(self.refresh)
        self.refresh.addTarget(self, action: #selector(refreshData), for: .valueChanged)
        
        view.addSubview(self.tableView)
        
        
        
    }
    
    @objc
    func QuaryData(){
        //获取上次加载数据的节点
        let cursorData = UserDefaults.standard.value(forKey: "cursor")
        
        var operation : CKQueryOperation!
        
        if cursorData != nil {
            print("节点存在")
            let cursor = unArchiverCursor(data: cursorData as! Data)
            operation = CKQueryOperation(cursor: cursor)
        }else {
            let query = CKQuery(recordType: "BlogData", predicate: NSPredicate(value: true))
            ///添加排序条件，此方法会作用于后面用于更新的CKCursor
            query.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
            
            operation = CKQueryOperation(query: query)
        }
        
        operation?.resultsLimit = 1
        
        ///返回的每一条查询数据
        operation?.recordFetchedBlock = {record in
            if self.RecordIDs.contains(record.recordID){
                return
            }else {
                self.Records.append(record)
                self.RecordIDs.append(record.recordID)
            
                //保存到本地coreData
                CoreDataManager.saveCDRecords(record: record)
            }
        }
        
        let publicDatabase = CKContainer.default().publicCloudDatabase
        
        ///此时才开始获取数据
        publicDatabase.add(operation!)
        
        ///执行完所有获取操作
        operation?.queryCompletionBlock = { (Cursor, e) in
            if e == nil {
                ///保存浏览记录
                print("节点", Cursor)
                if Cursor != nil {
                    let saveCursor = archiverCursor(original: Cursor!)
                    print("转换",saveCursor)
                    UserDefaults.standard.set(saveCursor, forKey: "cursor")
                }else {
                    self.isLoadAll = true
                }
                DispatchQueue.main.async {
                    print("数据量", self.Records.count)
                    self.tableView.reloadData()
                }
            }else {
                print("加载出错", e.debugDescription)
            }
        }
        
    }
    
    @objc func refreshData() {
       //获取上次加载数据的节点
        var operation : CKQueryOperation!
        
    
        let query = CKQuery(recordType: "BlogData", predicate: NSPredicate(value: true))
        ///添加排序条件，此方法会作用于后面用于更新的CKCursor
        query.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
        
        operation = CKQueryOperation(query: query)
        
        operation?.resultsLimit = 1
        
        ///返回的每一条查询数据
        operation?.recordFetchedBlock = {record in
            ///判断是否已经加载了
            if self.RecordIDs.contains(record.recordID) {
                print("已经有了")
                DispatchQueue.main.async {
                    self.refresh.endRefreshing()
                }
            }else{
                self.Records.insert(record, at: 0)
                self.RecordIDs.append(record.recordID)
              
                //保存到本地coreData
                CoreDataManager.saveCDRecords(record: record)
            }
            
        }
        
        let publicDatabase = CKContainer.default().publicCloudDatabase
        
        ///此时才开始获取数据
        publicDatabase.add(operation!)
        
        ///执行完所有获取操作
        operation?.queryCompletionBlock = { (Cursor, e) in
            if e == nil {
                ///保存浏览记录
                print("节点", Cursor)
                if Cursor != nil {
                    let saveCursor = archiverCursor(original: Cursor!)
                    print("转换",saveCursor)
                    UserDefaults.standard.set(saveCursor, forKey: "cursor")
                }
                
                DispatchQueue.main.async {
                    print("刷新数据量", self.Records.count)
                    ///重新按照时间排序
                    self.Records.sort { (record1, record2) -> Bool in
                        record1.creationDate!.compare(record2.creationDate!) == .orderedDescending
                    }
                    self.tableView.reloadData()
                    self.refresh.endRefreshing()
                }
            }else {
                print("加载出错", e.debugDescription)
            }
        }
    }
    
    func readCoreData() {
        let request = NSFetchRequest<CDRecords>(entityName: "CDRecords")
        request.fetchLimit = 10
        let sortDes = NSSortDescriptor(key: "writeDate", ascending: false)
        request.sortDescriptors = [sortDes]
        let results : Array = try! CoreDataManager.managedContext.fetch(request)
        print("现有本地数据量", results.count)
        for result in results {
            let unarchiver = try? NSKeyedUnarchiver.init(forReadingFrom: result.cd_record!)
            let record = CKRecord(coder: unarchiver!)
            self.Records.append(record!)
            self.RecordIDs.append(record!.recordID)
        }
        
    }
    
    
}



extension ViewController: UITableViewDelegate, UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.Records.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "MainCell" ,for: indexPath)  as! MainTableViewCell
        cell.setUI()
        cell.record = self.Records[indexPath.row]
        cell.desLabelHeight = getLabHeigh(labelStr: cell.record?["des"] as! String)
        cell.nameLab?.text = cell.record!["Artist"] as? String
        cell.desLabel!.text = cell.record!["des"] as? String
        cell.desLabel!.frame = CGRect(origin: CGPoint(x: 10, y: 30), size: CGSize(width: cell.frame.width - 20, height: cell.desLabelHeight ?? 30))
        cell.imageScroller.frame = CGRect(origin: CGPoint(x: 0, y: 30 + (cell.desLabelHeight ?? 30)), size: CGSize(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.width))
        cell.imageScroller.snp.makeConstraints { (make) in
            make.bottomMargin.equalToSuperview().offset(-30)
            make.size.equalTo(UIScreen.main.bounds.width)
        }
        for view in cell.imageScroller.subviews {
            view.removeFromSuperview()
        }
        if cell.record["images"] != nil {
            cell.imageScroller.contentSize = CGSize(width: UIScreen.main.bounds.width * CGFloat((cell.record!["images"] as! Array<CKAsset>).count), height: UIScreen.main.bounds.width)
            cell.loadImage()
        }else {
            //            cell.imageScroller.removeFromSuperview()
            
        }
        
        
        
        cell.timeLab?.frame = CGRect(origin: CGPoint(x: 20, y: 35 + (cell.desLabelHeight ?? 30 ) + UIScreen.main.bounds.width), size: CGSize(width: cell.frame.width, height: 20))
        cell.timeLab?.text = cell.record?.creationDate?.description
        
        
        
        return cell
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if self.Records.count == 0 {
            return 100
        }else {
            let record = self.Records[indexPath.row]
            if record["images"] == nil {
                return 40 + getLabHeigh(labelStr: record["des"] as! String)
            }else {
                return self.view.frame.width + 65 + getLabHeigh(labelStr: record["des"] as! String)
            }
            
        }
        
    }
    
    func getLabHeigh(labelStr:String) -> CGFloat {
        let lines = Int(CGFloat(labelStr.count) * 15 / (self.view.frame.width - 20) ) + 1
        return CGFloat((lines * 15) + 20)
        
    }
    
    
    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        DispatchQueue.main.async {
            if indexPath.row == self.Records.count - 1{
                if !self.isLoadAll {
                    self.QuaryData()
                }
            }
        }
    }
    
    func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        for view in cell.subviews {
            view.removeFromSuperview()
        }
    }
    
    
    
}
<file_sep>/CloudKit_Demo/Tools/Tools.swift
//
//  dynamicColor.swift
//  CloudKit_Demo
//
//  Created by Mac on 2020/4/13.
//  Copyright © 2020 Mac. All rights reserved.
//

import Foundation
import UIKit
import CloudKit


let ScreenWidth = UIScreen.main.bounds.width
let ScreenHeight = UIScreen.main.bounds.height



///用户登录成功通知
let UserLoginSuccessedNotification = "UserLoginSuccessedNotification"

///发布后通知刷新
let UpdataBlogNotification = "UpdataBlogNotification"

func archiverCursor(original:CKQueryOperation.Cursor) -> Data {
    let archiver = NSKeyedArchiver.init(requiringSecureCoding: false)
    original.encode(with: archiver)
    archiver.finishEncoding()
    return archiver.encodedData
}

func unArchiverCursor(data:Data) -> CKQueryOperation.Cursor {
    let unarchiver = try? NSKeyedUnarchiver.init(forReadingFrom: data)
    let cursor = CKQueryOperation.Cursor(coder: unarchiver!)
    return cursor!
}
<file_sep>/CloudKit_Demo/Views/MineViews/mineViewController.swift
//
//  mineViewController.swift
//  CloudKit_Demo
//
//  Created by Mac on 2020/4/8.
//  Copyright © 2020 Mac. All rights reserved.
//

import UIKit

class mineViewController: UIViewController {
    
    let RNaviItem = UIBarButtonItem()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view.
        self.setUI()

    }
   
    
    private func setUI() {
        
        self.RNaviItem.image = UIImage(named: "caidan")?.withRenderingMode(.alwaysOriginal)
        self.RNaviItem.target = self
        self.RNaviItem.action = #selector(toSetting)
        self.navigationItem.rightBarButtonItems = [self.RNaviItem]
        
        ///如果带问号可选的话，就不能修改子页面的返回按钮
        self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: self, action: nil)
        self.navigationItem.backBarButtonItem?.tintColor = UIColor.dynamicColor(lightColor: .black, darkColor: .white)
        
        
        ///头像
        
        let iconBtn = UIButton()
        iconBtn.frame = CGRect(origin: CGPoint(x: 20, y: self.navigationController!.navigationBar.frame.height+UIApplication.shared.statusBarFrame.height + 20), size: CGSize(width: 60, height: 60))
        iconBtn.setBackgroundImage(UIImage(named: "touxiang"), for: [])
        view.addSubview(iconBtn)
        
        let nameLab = UILabel()
        nameLab.frame = CGRect(origin: CGPoint(x: 110, y: self.navigationController!.navigationBar.frame.height+UIApplication.shared.statusBarFrame.height + 20), size: CGSize(width: 100, height: 60))
        nameLab.text = UserDefaults.standard.string(forKey: "userName")
        nameLab.textColor = UIColor.dynamicColor(lightColor: UIColor.init(white: 0.2, alpha: 1), darkColor: .white)
        view.addSubview(nameLab)
        
    }
    
    @objc func toSetting() {
        let VC = SettingViewController()
        VC.hidesBottomBarWhenPushed = true
        
        ///强制初始化页面，以便盖住tabBar
        VC.view.backgroundColor = UIColor.dynamicColor(lightColor: .white, darkColor: .black)
        self.navigationController?.pushViewController(VC, animated: true)
        
    }

}
<file_sep>/CloudKit_Demo/Views/MainTabBar.swift
//
//  MainTabBar.swift
//  CloudKit_Demo
//
//  Created by Mac on 2020/4/8.
//  Copyright © 2020 Mac. All rights reserved.
//

import UIKit
import SnapKit

class MainTabBar: UITabBarController,UITabBarControllerDelegate {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        self.addChildViewController(child: ViewController(), title: "主页", imageName: "tabbarhomeselect", selectedImageName: "tabbarhomeselect", index: 0, isEnable: true)
        self.addChild(blankViewController())
        
        self.addChildViewController(child: mineViewController(), title: "我的", imageName: "tabbarhomeselect", selectedImageName: "tabbarhomeselect", index: 2, isEnable: true)
        
        ///主线程中添加才会添加到界面的最上方
        DispatchQueue.main.async {
            self.addBtn()
        }
    
        delegate = self
        NotificationCenter.default.addObserver(self, selector: #selector(loginSuccess(Noti:)), name: NSNotification.Name(rawValue: UserLoginSuccessedNotification), object: nil)
        
    }
    
    deinit {
        ///注销通知
        NotificationCenter.default.removeObserver(self)
    }
    
    private func addChildViewController(child:UIViewController, title:String, imageName:String, selectedImageName:String, index:Int, isEnable:Bool) {
        let navigition = UINavigationController(rootViewController: child)
        child.title = title
        child.tabBarItem.tag = index
        child.tabBarItem.isEnabled = isEnable
        child.tabBarItem.image = UIImage.init(named: imageName)?.withRenderingMode(.automatic)
        child.tabBarItem.selectedImage = UIImage.init(named: selectedImageName)?.withRenderingMode(.automatic)
        self.addChild(navigition)
    }
    
    private func addBtn() {
        let btn = UIButton(frame: CGRect(origin: CGPoint.zero, size: CGSize(width: 50, height: 50)))
        btn.center = CGPoint(x: self.view.frame.width/2, y: 25)
        //        btn.backgroundColor = .red
        btn.setBackgroundImage(UIImage.init(named: "tianjia"), for: [])
        tabBar.addSubview(btn)
        btn.addTarget(self, action: #selector(toAddNew), for: .touchUpInside)
        
    }
    
    @objc
    func toAddNew() {
        let vc = addNewController()
        vc.view.frame = self.view.frame
        present(vc, animated: true, completion: nil)
        
    }
    
    
}


extension MainTabBar {
    ///登录成功
    @objc private func loginSuccess(Noti: Notification) {
        
    }
    
}
