// // AKExcelDateManager.swift // YunYingSwift // // Created by AlasKu on 17/2/10. // Copyright © 2017年 innostic. All rights reserved. // import UIKit class AKExcelDataManager: NSObject { //MARK: - Properties /// excelView var excelView : AKExcelView? /// AllExcel Data var dataArray : [[String]]? /// freezeCollection Width var freezeWidth : CGFloat = 0 /// freezeColectionView cells Size var freezeItemSize = [String]() /// slideCollectionView Cells Size var slideItemSize = [String]() /// slideCollectionView Cells Size var slideWidth : CGFloat = 0 /// headFreezeCollectionView Data var headFreezeData = [String]() /// headSlideCollectionView Data var headSlideData = [String]() /// contentFreezeCollectionView Data var contentFreezeData = [[String]]() /// contentSlideCollectionView Data var contentSlideData = [[String]]() /// 支持颜色 var contentSlideDataTextColor = [[UIColor]]() /// slideItemOffSetX var slideItemOffSetX = [CGFloat]() private func resetData() { dataArray?.removeAll() freezeWidth = 0 freezeItemSize.removeAll() slideItemSize.removeAll() slideWidth = 0 headFreezeData.removeAll() headSlideData.removeAll() contentFreezeData.removeAll() contentSlideData.removeAll() contentSlideDataTextColor.removeAll() slideItemOffSetX.removeAll() } //MARK: - Private Method private func loadData() { var arrM = [[String]]() if let headerTitles = excelView?.headerTitles { arrM.append(headerTitles) } if let contentData = excelView?.contentData { for model in contentData { arrM.append(model.valuesFor(excelView?.properties)) } } dataArray = arrM } private func configData() { guard let excelView = excelView, let dataArray = dataArray, dataArray.count > (excelView.headerTitles == nil ? 0 : 1) else { return } if let _ = excelView.headerTitles { headFreezeData = dataArray[0].prefix(upTo: excelView.leftFreezeColumn).compactMap({ $0 }) headSlideData = dataArray[0].suffix(from: excelView.leftFreezeColumn).compactMap({ $0 }) contentFreezeData = dataArray[1.. (excelView.headerTitles == nil ? 0 : 1) else { return } var fItemSize = [String]() var sItemSize = [String]() let col = dataArray.first!.count // 标题那一行或者数据第一行 for i in 0 ..< col { var colW = CGFloat() for j in 0 ..< dataArray.count { let value = dataArray[j][i] var size = value.getTextSize(font: excelView.contentTextFontSize, size: CGSize(width: excelView.itemMaxWidth, height: excelView.itemHeight)) if j == 0 && excelView.headerTitles != nil { size = value.getTextSize(font: excelView.headerTextFontSize, size: CGSize(width: excelView.itemMaxWidth, height: excelView.itemHeight)) } if let columnWidthSetting = excelView.columnWidthSetting, let setWidth = columnWidthSetting[i] { size = CGSize(width: setWidth, height: excelView.itemHeight) } let targetWidth = size.width + 2 * excelView.textMargin // 若这个字符串宽度大于上一个单元格的宽度,目的是为了统一每一列的宽度 if targetWidth >= colW { colW = targetWidth } colW = max(excelView.itemMinWidth, min(excelView.itemMaxWidth, colW)) } // 滑动scroll节点 slideItemOffSetX.append(slideWidth) if i < excelView.leftFreezeColumn { fItemSize.append(NSCoder.string(for: CGSize(width: colW, height: excelView.itemHeight - 1))) freezeWidth += colW + 1 // 这里加1的原因是为了解决浮点数计算误差 dPrint("fItemSize is \(NSCoder.string(for: CGSize(width: colW, height: excelView.itemHeight - 1)))") dPrint("fItemSize is \(freezeWidth)") } else { sItemSize.append(NSCoder.string(for: CGSize(width: colW, height: excelView.itemHeight - 1))) slideWidth += colW + 1 // 这里加1的原因是为了解决浮点数计算误差 dPrint("sItemSize is \(NSCoder.string(for: CGSize(width: colW, height: excelView.itemHeight - 1)))") dPrint("slideWidth is \(slideWidth)") } } freezeItemSize = fItemSize slideItemSize = sItemSize } //MARK: - Public Method func caculateData() { resetData() loadData() configData() caculateWidths() } } //MARK: - String Extension extension String { func getTextSize(font:UIFont,size:CGSize) -> CGSize { let dic = NSDictionary(object: font, forKey: NSAttributedString.Key.font as NSCopying) let stringSize = self.boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: dic as? [NSAttributedString.Key : Any] , context:nil).size return stringSize } } extension NSObject { func propertyNames() -> [String] { return Mirror(reflecting: self).children.compactMap { $0.label } } func valueFor(_ property:String) -> String? { var value : String? for case let (label?, anyValue) in Mirror(reflecting:self).children { if label.isEqual(property) { value = anyValue as? String } } return value } func valuesFor(_ properties:[String]?) -> [String] { if let pros = properties { var arrM = [String]() for pro in pros { arrM.append(valueFor(pro)!) } return arrM } var values = [String]() for case let (_?, anyValue) in Mirror(reflecting:self).children { values.append(anyValue as? String ?? "") } return values } }