无故事王国
2023-11-01 b3269976c84d03208f633cd0136a6f78e8dd53f7
瀑布流优化
2个文件已添加
16个文件已修改
625 ■■■■■ 已修改文件
WanPai.xcodeproj/project.pbxproj 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Common/Layout/FlowLayout.swift 482 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Common/Layout/UCCateDecorationView.swift 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Common/Layout/WaterFallFlowLayout.swift 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Network/Services.swift 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Root/Activity/VC/ActivityStudentListVC.swift 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Root/Activity/View/StudentUpdateInfoView.swift 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Root/Course/VC/CourseDetailApplyVC.swift 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Root/Course/VC/CourseDetailVC.swift 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Root/Course/VC/StudentExchangeVC.swift 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Root/Home/VC/HomeVC.swift 41 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Root/Home/VC/HomeVC.xib 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Root/Login/VC/LoginVC.swift 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Root/Login/VC/LoginVC.xib 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Root/Other/TCell/StudentInfo_3_TCell.swift 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Root/Other/View/StoresChooseView.swift 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Root/Other/View/StoresChooseView.xib 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai/Root/Yard/VC/YardDetailVC.swift 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WanPai.xcodeproj/project.pbxproj
@@ -175,6 +175,8 @@
        13CCC4BD2A4A820100DEDF19 /* StudentCourseDetailHeadView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13CCC4BC2A4A820100DEDF19 /* StudentCourseDetailHeadView.xib */; };
        13CE11CE2AF1F23300F6ACA4 /* CommmonBannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13CE11CD2AF1F23300F6ACA4 /* CommmonBannerView.swift */; };
        13CE11D02AF203E000F6ACA4 /* JJPageControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13CE11CF2AF203E000F6ACA4 /* JJPageControl.swift */; };
        13CE11D22AF2595100F6ACA4 /* FlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13CE11D12AF2595100F6ACA4 /* FlowLayout.swift */; };
        13CE11D42AF25C6400F6ACA4 /* UCCateDecorationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13CE11D32AF25C6400F6ACA4 /* UCCateDecorationView.swift */; };
        13D084552A40666A005B05D5 /* CalendarPickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13D084542A40666A005B05D5 /* CalendarPickerView.swift */; };
        13D084572A406672005B05D5 /* CalendarPickerView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13D084562A406672005B05D5 /* CalendarPickerView.xib */; };
        13D084592A4071F2005B05D5 /* YardBookingListVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13D084582A4071F2005B05D5 /* YardBookingListVC.swift */; };
@@ -472,6 +474,8 @@
        13CCC4BC2A4A820100DEDF19 /* StudentCourseDetailHeadView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = StudentCourseDetailHeadView.xib; sourceTree = "<group>"; };
        13CE11CD2AF1F23300F6ACA4 /* CommmonBannerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommmonBannerView.swift; sourceTree = "<group>"; };
        13CE11CF2AF203E000F6ACA4 /* JJPageControl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JJPageControl.swift; sourceTree = "<group>"; };
        13CE11D12AF2595100F6ACA4 /* FlowLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlowLayout.swift; sourceTree = "<group>"; };
        13CE11D32AF25C6400F6ACA4 /* UCCateDecorationView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UCCateDecorationView.swift; sourceTree = "<group>"; };
        13D084542A40666A005B05D5 /* CalendarPickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarPickerView.swift; sourceTree = "<group>"; };
        13D084562A406672005B05D5 /* CalendarPickerView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CalendarPickerView.xib; sourceTree = "<group>"; };
        13D084582A4071F2005B05D5 /* YardBookingListVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YardBookingListVC.swift; sourceTree = "<group>"; };
@@ -954,6 +958,8 @@
        8D5C15102A31886D00A8BCC9 /* Layout */ = {
            isa = PBXGroup;
            children = (
                13CE11D32AF25C6400F6ACA4 /* UCCateDecorationView.swift */,
                13CE11D12AF2595100F6ACA4 /* FlowLayout.swift */,
                8D710F6C2A31897C0031E2D1 /* WaterFallFlowLayout.swift */,
            );
            path = Layout;
@@ -1706,6 +1712,7 @@
                8D5C150E2A31885B00A8BCC9 /* CommonAlertView.swift in Sources */,
                139A39F62A4139E000737AFB /* WelfareWeeklyListVC.swift in Sources */,
                133435032A40407200F23951 /* CalendarItemCCell.swift in Sources */,
                13CE11D42AF25C6400F6ACA4 /* UCCateDecorationView.swift in Sources */,
                8D7017892A3308DC00473C40 /* Common_1_TCell.swift in Sources */,
                13D7BA922A4BCE480007E4B7 /* WelfareBillListVC.swift in Sources */,
                1376A6A12A4A7E1E00D4C851 /* CourseChargeTCell.swift in Sources */,
@@ -1713,6 +1720,7 @@
                8D6D58D12A39906F0003CFE6 /* ActivitySignupListSubVC.swift in Sources */,
                134BD50A2A5FF72900786819 /* OBSUploader.swift in Sources */,
                1375464B2A581716001FA77A /* HomeModel.swift in Sources */,
                13CE11D22AF2595100F6ACA4 /* FlowLayout.swift in Sources */,
                8D70178D2A330E5700473C40 /* CourseDetailVC.swift in Sources */,
                1355ABFD2A4C15C7002B25E4 /* RechargeRecordVC.swift in Sources */,
                134BD52C2A6008BA00786819 /* YYPaymentManager.swift in Sources */,
WanPai/Common/Layout/FlowLayout.swift
New file
@@ -0,0 +1,482 @@
//
//  FlowLayout.swift
//  SwiftTest
//
//  Created by 王欣 on 2021/1/20.
//  Copyright © 2021 王欣. All rights reserved.
//
import UIKit
private class UsedCarSectionInfo{
    typealias LayoutAttribute = UICollectionViewLayoutAttributes
    private var linesLastValue:[Int:CGRect] = [:]
    var headerAttribute:LayoutAttribute?
    var itemAttribute:[LayoutAttribute] = []
    var footerAttribute:LayoutAttribute?
    var decorAttribute:LayoutAttribute?
    let colum:Int
    let origin:CGPoint
    let itemWidth:CGFloat
    let minimumInteritemSpacing:CGFloat
    let celledgeInset:UIEdgeInsets
    init(colum:Int,itemWidth:CGFloat,minimumInteritemSpacing:CGFloat,edgeInset:UIEdgeInsets) {
        self.colum = colum
        self.itemWidth = itemWidth
        self.celledgeInset = edgeInset
        self.origin = .init(x: edgeInset.left, y: edgeInset.top)
        self.minimumInteritemSpacing = minimumInteritemSpacing
    }
    ///获取当前section的y轴最大值
    func maxY() -> CGFloat {
        if let footer = footerAttribute{
            return footer.frame.maxY
        }
        if let _ = itemAttribute.last{
            return findExtremeValue(true).1.maxY + celledgeInset.bottom
        }
        if let header = headerAttribute{
            return header.frame.maxY
        }
        return celledgeInset.top
    }
    ///获取当前section的y轴最大值
    func minY() -> CGFloat {
        if let header = headerAttribute{
            return header.frame.minY
        }
        if let firstItem = itemAttribute.first{
            return firstItem.frame.minY
        }
        if let footer = headerAttribute{
            return footer.frame.minY
        }
        return celledgeInset.top
    }
    ///更新排序
    func updateRect(colum:Int,value:CGRect)  {
        linesLastValue[colum] = value
    }
    func initLinesLastValue(_ rect:CGRect)  {
        linesLastValue[0] = rect
        for index in 1 ..< Int(colum) {
            linesLastValue[index] = CGRect(x: rect.minX + (minimumInteritemSpacing + rect.width) * CGFloat(index), y: rect.minY + 0.1 * CGFloat(index) , width: rect.width, height: -(0.1 * CGFloat(index)))
        }
    }
    /// 对比每列的最后一个元素,获取最大值或最小值
    func findExtremeValue(_ max: Bool) -> (Int, CGRect) {
        if let value = linesLastValue.compactMap({ ($0, $1) }).sorted(by: {
            if max == false {
                return $0.1.maxY > $1.1.maxY
            } else {
                return $0.1.maxY < $1.1.maxY
            }
        }).last {
            return value
        }
        return (0, CGRect(origin: origin, size: .zero))
    }
}
@objc public protocol UICollectionViewDelegateWaterFlowLayout: UICollectionViewDelegateFlowLayout {
    /**
     返回当前section中的列数
     */
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, colum section: Int) -> Int
    /**
     返回当前section中cell的行间距
     */
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacing section: Int) -> CGFloat
    /**
     返回当前section中cell的内间距
     */
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sectionInsetForItems section: Int) -> UIEdgeInsets
    /**
     返回当前indexpath的高度,可以根据宽度来计算
     */
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, itemWidth: CGFloat, caculateHeight indexPath: IndexPath) -> CGFloat
}
@objc public class FlowLayout: UICollectionViewFlowLayout {
    // 插入的条目 --- 操作数组 ---
    private lazy var insertingIndexPaths = [IndexPath]()
    // 刷新的条目
    private lazy var reloadIndexPaths    = [IndexPath]()
    // 删除的条目
    private lazy var deletingIndexPaths  = [IndexPath]()
    // --- 操作数组 ---
    // 分区的内容信息,用来做布局处理
    private lazy var sectionInfos: [Int: UsedCarSectionInfo] = [:]
    //    private lazy var animator: UIDynamicAnimator = UIDynamicAnimator(collectionViewLayout: self)
    public enum BounceStyle {
        case subtle
        case regular
        case prominent
        var damping: CGFloat {
            switch self {
            case .subtle: return 0.8
            case .regular: return 0.7
            case .prominent: return 0.5
            }
        }
        var frequency: CGFloat {
            switch self {
            case .subtle: return 2
            case .regular: return 1.5
            case .prominent: return 1
            }
        }
    }
    private var damping: CGFloat = BounceStyle.regular.damping
    private var frequency: CGFloat = BounceStyle.regular.frequency
    // updateItem doesn't take into account size changes
    // so we track visible size changes and re-prepare
    // behaviors on change
    private var visibleItemsSizeCache: [IndexPath:CGSize] = [:]
    private var visibleIndexPaths: Set<IndexPath> = Set()
    /**
     获取每个item的宽度
     */
    func getItemWidth(for section: Int) -> CGFloat {
        if let collectionView = self.collectionView, let delegate = collectionView.delegate as? UICollectionViewDelegateWaterFlowLayout {
            let edge = delegate.collectionView(collectionView, layout: self, sectionInsetForItems: section)
            let colum = delegate.collectionView(collectionView, layout: self, colum: section)
            var totalLineSpace: CGFloat = 0
            if colum > 1 {
                totalLineSpace = minimumInteritemSpacing * CGFloat(colum - 1)
            }
            let width = (collectionView.bounds.size.width - edge.left - edge.right - totalLineSpace) / CGFloat(colum)
            return width
        }
        return UIScreen.main.bounds.width
    }
    /// 获取当前各分区y轴最大的值
    private func maxY() -> CGFloat {
        if let sectionInfo = sectionInfos.values.sorted(by: { $0.maxY() > $1.maxY() }).first {
            return sectionInfo.maxY()
        }
        return 0
    }
}
/// 滑动代理事件
extension FlowLayout {
    @objc public func scrollToHeader(with section: Int) {
        let indexPath = IndexPath(row: 0, section: section)
        scrollWith(indexPath, isHeader: true, isFooter: false)
    }
    @objc public func scrollToFooter(with section: Int) {
        let indexPath = IndexPath(row: 0, section: section)
        scrollWith(indexPath, isHeader: false, isFooter: true)
    }
    @objc public func scrolllToIndex(index: IndexPath) {
        scrollWith(index, isHeader: false, isFooter: false)
    }
    private func scrollWith(_ indexPath: IndexPath, isHeader: Bool, isFooter: Bool) {
        let sectionInfo = sectionInfos[indexPath.section]
        if isHeader, let att = sectionInfo?.headerAttribute {
            collectionView?.setContentOffset(CGPoint(x: 0, y: att.frame.origin.y), animated: true)
            return
        }
        if isHeader, let att = sectionInfo?.footerAttribute {
            collectionView?.setContentOffset(CGPoint(x: 0, y: att.frame.origin.y), animated: true)
            return
        }
        if let att = sectionInfo?.itemAttribute[indexPath.row] {
            collectionView?.setContentOffset(CGPoint(x: 0, y: att.frame.origin.y), animated: true)
        }
    }
}
/**
 重写布局相关的方法
 */
extension FlowLayout {
    typealias LayoutAttribute = UICollectionViewLayoutAttributes
    /**
     当集合视图第一次显示其内容时,以及当由于视图的更改而显式或隐式地使布局失效时,就会发生布局更新。在每次布局更新期间,集合视图首先调用这个方法,让布局对象有机会为即将到来的布局操作做准备。
     这个方法的默认实现不做任何事情。子类可以覆盖它,并使用它来设置数据结构或执行后续执行布局所需的任何初始计算。
     */
    override public func prepare() {
        print(#function)
        super.prepare()
        sectionInfos.removeAll()
        //        animator.removeAllBehaviors()
        self.register(UCCateDecorationView.self, forDecorationViewOfKind: "UCCateDecorationView")
        guard let collectionView = self.collectionView, let delegate = collectionView.dataSource as? UICollectionViewDelegateWaterFlowLayout else {
            return
        }
        let sectionNum = collectionView.numberOfSections
        /// 获取到分区
        for sectionIndex in 0 ..< sectionNum {
            let section = IndexPath(row: 0, section: sectionIndex)
            let cellEdge = delegate.collectionView(collectionView, layout: self, sectionInsetForItems: sectionIndex)
            ///获取section的列间距
            let lineSpace = delegate.collectionView(collectionView, layout: self, minimumLineSpacing: sectionIndex)
            /// 查看布局中存在几列
            let colum = delegate.collectionView(collectionView, layout: self, colum: sectionIndex)
            let sectionInfo = UsedCarSectionInfo(colum: colum, itemWidth: getItemWidth(for: sectionIndex), minimumInteritemSpacing: minimumInteritemSpacing, edgeInset: cellEdge)
            sectionInfos[sectionIndex] = sectionInfo
            /// 处理header数据
            if let att = layoutAttributesForSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, at: section)?.copy() as? LayoutAttribute {
                var maxY: CGFloat = 0
                if section.section > 0, let preInfo = sectionInfos[section.section - 1] { maxY = preInfo.maxY() }
                var frame = att.frame
                frame.origin = CGPoint(x: frame.origin.x, y: maxY)
                att.frame = frame
                sectionInfo.headerAttribute = att
                //                addItem(att, in: collectionView)
            }
            /// 处理cell数据
            let cellNumForSection = collectionView.numberOfItems(inSection: sectionIndex)
            for index in 0 ..< cellNumForSection {
                let indexPath = IndexPath(row: index, section: sectionIndex)
                if let att = layoutAttributesForItem(at: indexPath)?.copy() as? LayoutAttribute {
                    var frame = att.frame
                    let height = delegate.collectionView(collectionView, layout: self, itemWidth: sectionInfo.itemWidth, caculateHeight: indexPath)
                    frame.size = .init(width: sectionInfo.itemWidth, height: height)
                    var newOrigin = CGPoint.zero
                    if indexPath.row == 0 {
                        newOrigin = .init(x: sectionInfo.origin.x, y: maxY() + sectionInfo.celledgeInset.top)
                        frame.origin = newOrigin
                        sectionInfo.initLinesLastValue(frame)
                    } else {
                        ///查找当前section中哪列最短
                        let tuple = sectionInfo.findExtremeValue(false)
                        let caluteMinimumLineSpacing = tuple.1.size.height < 0 ? 0 : lineSpace
                        newOrigin = CGPoint(x: tuple.1.minX, y: tuple.1.maxY + caluteMinimumLineSpacing)
                        frame.origin = newOrigin
                        sectionInfo.updateRect(colum: tuple.0, value: frame)
                    }
                    att.frame = frame
                    sectionInfo.itemAttribute.append(att)
                    //                    addItem(att, in: collectionView)
                }
            }
            // 处理footer数据
            if let att = layoutAttributesForSupplementaryView(ofKind: UICollectionView.elementKindSectionFooter, at: section)?.copy() as? LayoutAttribute {
                var maxY: CGFloat = 0
                maxY = sectionInfo.maxY()
                var frame = att.frame
                frame.origin = CGPoint(x: frame.origin.x, y: maxY)
                att.frame = frame
                sectionInfo.footerAttribute = att
                //                addItem(att, in: collectionView)
            }
            if section.section == 0{
                if let att = layoutAttributesForDecorationView(ofKind: "UCCateDecorationView", at: section)?.copy() as? LayoutAttribute{
                    let offsetX:CGFloat = 400
                    let newOrigin = CGPoint.init(x: collectionView.bounds.origin.x, y: sectionInfo.minY() - offsetX)
                    let newSize = CGSize.init(width: collectionView.bounds.width, height: sectionInfo.maxY() - sectionInfo.minY() + offsetX)
                    att.frame = CGRect.init(origin: newOrigin, size: newSize)
                    sectionInfo.decorAttribute = att
                    //                addItem(att, in: collectionView)
                }
            }
        }
    }
    /**
     private func addItem(_ item: UICollectionViewLayoutAttributes, in view: UICollectionView) {
     let behavior = UIAttachmentBehavior(item: item, attachedToAnchor: floor(item.center))
     animator.addBehavior(behavior, damping, frequency)
     visibleIndexPaths.insert(item.indexPath)
     visibleItemsSizeCache[item.indexPath] = item.bounds.size
     }
     */
    override public var collectionViewContentSize: CGSize {
        if let collectionView = self.collectionView {
            let contentSize = CGSize(width: collectionView.bounds.width, height: max(maxY(), collectionView.bounds.height))
            return contentSize
        }
        return .zero
    }
    /// 没有直接返回super调用,是因为在增加,删除,刷新等操作中,会再次执行该方法,布局计算是以当前的item的下一个做变化操作,和要求动画不符
    override public func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        if let sectionInfo = sectionInfos[indexPath.section], sectionInfo.itemAttribute.count > indexPath.row {
            return sectionInfo.itemAttribute[indexPath.row]
        }
        return super.layoutAttributesForItem(at: indexPath)
    }
    /// 没有直接返回super调用,是因为在增加,删除,刷新等操作中,会再次执行该方法,布局计算是以当前的item的下一个做变化操作,和要求动画不符
    override public func layoutAttributesForSupplementaryView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        if let sectionInfo = sectionInfos[indexPath.section] {
            if elementKind == UICollectionView.elementKindSectionHeader, let att = sectionInfo.headerAttribute {
                return att
            }
            if elementKind == UICollectionView.elementKindSectionFooter, let att = sectionInfo.footerAttribute {
                return att
            }
        }
        return super.layoutAttributesForSupplementaryView(ofKind: elementKind, at: indexPath)
    }
    public override func layoutAttributesForDecorationView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        let att = UICollectionViewLayoutAttributes.init(forDecorationViewOfKind: elementKind, with: indexPath)
        att.zIndex = -1
        return att
    }
    /// 返回当前rect中包含的布局信息
    override public func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        return sectionInfos.values.flatMap { (info) -> [LayoutAttribute] in
            var arr = [UICollectionViewLayoutAttributes]()
            if let header = info.headerAttribute, header.frame.intersects(rect) {
                arr.append(header)
            }
            arr.append(contentsOf: info.itemAttribute.filter { $0.frame.intersects(rect) })
            if let footer = info.footerAttribute, footer.frame.intersects(rect) {
                arr.append(footer)
            }
            if let att = info.decorAttribute,att.frame.intersects(rect){
                arr.append(att)
            }
            return arr
        }
    }
}
/// item增加删除相关的方法
extension FlowLayout {
    /// 监听视图内容item变化操作
    override public func prepare(forCollectionViewUpdates updateItems: [UICollectionViewUpdateItem]) {
        super.prepare(forCollectionViewUpdates: updateItems)
        for update in updateItems {
            if let indexPath = update.indexPathAfterUpdate,update.updateAction == .insert {
                insertingIndexPaths.append(indexPath)
            }
            if let indexPath = update.indexPathAfterUpdate, update.updateAction == .reload {
                reloadIndexPaths.append(indexPath)
            }
            if let indexPath = update.indexPathBeforeUpdate, update.updateAction == .delete {
                deletingIndexPaths.append(indexPath)
            }
        }
    }
    /// item将要显示的时候调用,处理相关动画
    override public func initialLayoutAttributesForAppearingItem(at itemIndexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        let attributes = super.initialLayoutAttributesForAppearingItem(at: itemIndexPath)
        if insertingIndexPaths.contains(itemIndexPath), let copyModel = attributes?.copy() as? LayoutAttribute {
            if let sectionInfo = sectionInfos[itemIndexPath.section], sectionInfo.itemAttribute.count > itemIndexPath.row {
                let att = sectionInfo.itemAttribute[itemIndexPath.row]
                copyModel.alpha = 0
                copyModel.frame = att.frame
                copyModel.transform = CGAffineTransform(scaleX: 0.3, y: 0.3)
            }
            return copyModel
        }
        if reloadIndexPaths.contains(itemIndexPath), let copyModel = attributes?.copy() as? LayoutAttribute {
            if let sectionInfo = sectionInfos[itemIndexPath.section], sectionInfo.itemAttribute.count > itemIndexPath.row {
                let att = sectionInfo.itemAttribute[itemIndexPath.row]
                copyModel.alpha = 0
                copyModel.frame = att.frame
            }
            return copyModel
        }
        return attributes
    }
    /// 视图变化完成调用
    override public func finalizeCollectionViewUpdates() {
        super.finalizeCollectionViewUpdates()
        insertingIndexPaths.removeAll()
        deletingIndexPaths.removeAll()
        reloadIndexPaths.removeAll()
    }
    /// 删除item会执行此代理方法,处理删除相关的动画
    override public func finalLayoutAttributesForDisappearingItem(at itemIndexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        let attributes = super.finalLayoutAttributesForDisappearingItem(at: itemIndexPath)
        if deletingIndexPaths.contains(itemIndexPath), let copyModel = attributes?.copy() as? LayoutAttribute {
            copyModel.alpha = 0.0
            copyModel.transform = CGAffineTransform(scaleX: 0.2, y: 0.2)
            return copyModel
        }
        return attributes
    }
    /**
     open override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
     guard let view = collectionView else { return false }
     animator.behaviors.forEach {
     guard let behavior = $0 as? UIAttachmentBehavior,
     let item = behavior.items.first else {
     return
     }
     update(behavior: behavior, and: item, in: view, for: newBounds)
     animator.updateItem(usingCurrentState: item)
     }
     return false // animator will automatically notify FlowLayout to invalidate
     }
     */
    private func update(behavior: UIAttachmentBehavior, and item: UIDynamicItem, in view: UICollectionView, for bounds: CGRect) {
        let delta = CGVector(dx: bounds.origin.x - view.bounds.origin.x, dy: bounds.origin.y - view.bounds.origin.y)
        let resistance = CGVector(dx: abs(view.panGestureRecognizer.location(in: view).x - behavior.anchorPoint.x) / 1000, dy: abs(view.panGestureRecognizer.location(in: view).y - behavior.anchorPoint.y) / 1000)
        switch scrollDirection {
        case .horizontal: item.center.x += delta.dx < 0 ? max(delta.dx, delta.dx * resistance.dx) : min(delta.dx, delta.dx * resistance.dx)
        case .vertical: item.center.y += delta.dy < 0 ? max(delta.dy, delta.dy * resistance.dy) : min(delta.dy, delta.dy * resistance.dy)
        @unknown default:
            item.center.y += delta.dy < 0 ? max(delta.dy, delta.dy * resistance.dy) : min(delta.dy, delta.dy * resistance.dy)
        }
        item.center = floor(item.center)
    }
}
extension UIDynamicAnimator {
    open func addBehavior(_ behavior: UIAttachmentBehavior, _ damping: CGFloat, _ frequency: CGFloat) {
        behavior.damping = damping
        behavior.frequency = frequency
        addBehavior(behavior)
    }
}
fileprivate func floor(_ point: CGPoint) -> CGPoint {
    CGPoint(x: floor(point.x), y: floor(point.y))
}
WanPai/Common/Layout/UCCateDecorationView.swift
New file
@@ -0,0 +1,22 @@
//
//  MyDecorationView.swift
//  SwiftTest
//
//  Created by 王欣 on 2021/1/28.
//  Copyright © 2021 王欣. All rights reserved.
//
import UIKit
class UCCateDecorationView: UICollectionReusableView {
    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = UIColor.clear
    }
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
WanPai/Common/Layout/WaterFallFlowLayout.swift
@@ -11,6 +11,7 @@
    func waterFlowLayout(_ waterFlowLayout: WaterFallFlowLayout, itemHeight indexPath: IndexPath) -> CGFloat
}
@available(*,deprecated,message: "废弃")
class WaterFallFlowLayout: UICollectionViewFlowLayout {
    weak var delegate: WaterFallLayoutDelegate?
WanPai/Network/Services.swift
@@ -1065,13 +1065,14 @@
    }
        /// 编辑参赛人员信息
    class func editParticipant(id:Int,height:Int,weight:Int,phone:String?)->Observable<BaseResponse<SimpleModel>>{
    class func editParticipant(id:Int,height:Int,weight:Int,phone:String?,isStudent:Int)->Observable<BaseResponse<SimpleModel>>{
        let params = ParamsAppender.build(url: All_Url)
            .interface(url: "competition/api/participant/editParticipant")
            .append(key: "id", value: id)
            .append(key: "height", value: height)
            .append(key: "weight", value: weight)
            .append(key: "phone", value: phone)
            .append(key: "isStudent", value: isStudent)
        return NetworkRequest.request(params: params, method: .post, progress: true)
    }
WanPai/Root/Activity/VC/ActivityStudentListVC.swift
@@ -65,6 +65,7 @@
        cell.img_radio.isHidden = true
        cell.activityDetailPartModel = viewModel.dataSource.value[indexPath.row]
        cell.btn_verifiy.isHidden = !viewModel.dataSource.value[indexPath.row].idcard.isEmpty
        cell.btn_delete.isHidden = viewModel.dataSource.value[indexPath.row].isStudent == 0
        cell.delClouse = {index in
            CommonAlertView.show(title: "提示", content: "确认删除当前人员吗?") { [weak self] status in
                guard let weakSelf = self else { return }
WanPai/Root/Activity/View/StudentUpdateInfoView.swift
@@ -74,7 +74,7 @@
        guard tf_weight.text!.int != 0 else {alertError(msg: "请输入正确的体重");return}
        self.endEditing(true)
        Services.editParticipant(id: model!.id, height: tf_height.text!.int!, weight: tf_weight.text!.int!, phone: tf_phone.text).subscribe(onNext: {data in
        Services.editParticipant(id: model!.id, height: tf_height.text!.int!, weight: tf_weight.text!.int!, phone: tf_phone.text,isStudent: model!.isStudent).subscribe(onNext: {data in
            alertSuccess(msg: "修改成功")
            DispatchQueue.main.asyncAfter(deadline: .now()+1) {
                NotificationCenter.default.post(name: StudentUpdate_Nofi, object: nil)
WanPai/Root/Course/VC/CourseDetailApplyVC.swift
@@ -283,6 +283,7 @@
                    label_coin.isHidden = true;fallthrough
                case .cashCoin:
                    if subM.originalPrice == 0{label_originPrice.isHidden = true}
                    label_originPrice.isHidden = (subM.paymentPrice == subM.originalPrice && subM.paymentPrice != 0 && subM.originalPrice != 0)
                        //玩湃币
                    label_coin.attributedText = AttributedStringbuilder.build()
@@ -298,8 +299,10 @@
                        label_vipPrice.isHidden = true
                        if subM.paymentPrice < subM.vipPrice && subM.paymentPrice != 0{
                            label_price.text = (subM.paymentPrice * studentCount - (selectCouponModel?.favorable ?? 0)).currency()
                        }else{
                        }else if subM.vipPrice != 0{
                            label_price.text = (subM.vipPrice * studentCount - (selectCouponModel?.favorable ?? 0)).currency()
                        }else{
                            label_price.text = (subM.paymentPrice * studentCount - (selectCouponModel?.favorable ?? 0)).currency()
                        }
                    }else{
                            //非会员
WanPai/Root/Course/VC/CourseDetailVC.swift
@@ -84,7 +84,7 @@
                            label_coin.isHidden = true;fallthrough
                        case .cashCoin:
                            if subM.originalPrice == 0{label_originPrice.isHidden = true}
                            label_originPrice.isHidden = (subM.paymentPrice == subM.originalPrice && subM.paymentPrice != 0 && subM.originalPrice != 0)
                                //玩湃币
                            label_coin.attributedText = AttributedStringbuilder.build()
                                .add(string: "玩湃币:", withFont: UIFont.systemFont(ofSize: 14, weight: .semibold), withColor: UIColor(hexStr: "#3F3F3F"))
@@ -99,8 +99,10 @@
                                label_vipPrice.isHidden = true
                                if subM.paymentPrice < subM.vipPrice && subM.paymentPrice != 0{
                                    label_price.text = subM.paymentPrice.currency()
                                }else{
                                }else if subM.vipPrice < subM.paymentPrice && subM.vipPrice != 0{
                                    label_price.text = subM.vipPrice.currency()
                                }else{
                                    label_price.text = subM.paymentPrice.currency()
                                }
                            }else{
                                    //非会员
WanPai/Root/Course/VC/StudentExchangeVC.swift
@@ -25,7 +25,7 @@
    override func viewDidLoad() {
        super.viewDidLoad()
        title = "切换运动营成员"
        selectIndex = 0
        viewModel.configure(tableView,needMore: false)
        viewModel.beginRefresh()
        btn_add.imagePosition = .right
@@ -74,6 +74,7 @@
        let model = viewModel.dataSource.value[indexPath.row]
        let cell = tableView.dequeueReusableCell(withIdentifier: "_StudentInfo_3_TCell") as! StudentInfo_3_TCell
        cell.studentProfile1Model = model
        cell.viewModel = viewModel
        if selectIndex != nil{
            if indexPath.row == selectIndex{
WanPai/Root/Home/VC/HomeVC.swift
@@ -23,7 +23,7 @@
    @IBOutlet weak var label_vipInfo: UILabel!
    @IBOutlet weak var view_banner: CommonBannerView!
    @IBOutlet weak var btn_localTap: TapBtn!
    private var layout:WaterFallFlowLayout!
    private var layout:FlowLayout!
    @IBOutlet weak var label_store: UILabel!
    private var items = Array<Any>()
    private var storeModel:HomeStoreModel?
@@ -70,10 +70,8 @@
    override func setUI() {
        view.backgroundColor = UIColor(hexStr: "EEF0F3")
        
        layout = WaterFallFlowLayout()
        layout.cols = 2
        layout = FlowLayout()
        layout.sectionInset = UIEdgeInsets(top: 14, left: 34, bottom: 14, right: 34)
        layout.delegate = self
        collectionView.collectionViewLayout = layout
        collectionView.delegate = self
        collectionView.dataSource = self
@@ -173,13 +171,8 @@
    private func updateUI(){
            //重置Layout,不然不更新
        layout = WaterFallFlowLayout()
        layout.itemCount = items.count
        layout.delegate = self
        layout.cols = 2
        layout.sectionInset = UIEdgeInsets(top: 14, left: 34, bottom: 14, right: 34)
        collectionView.collectionViewLayout = self.layout
        collectionView.reloadData()
        self.collectionView.collectionViewLayout = self.layout
        self.collectionView.reloadData()
        hiddenHUD()
    }
@@ -233,7 +226,31 @@
    }
}
extension HomeVC:UICollectionViewDelegate{
extension HomeVC:UICollectionViewDelegate,UICollectionViewDelegateWaterFlowLayout{
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, colum section: Int) -> Int {
        return 2
    }
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacing section: Int) -> CGFloat {
        return 10
    }
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sectionInsetForItems section: Int) -> UIEdgeInsets {
        return UIEdgeInsets(top: 0, left: 34, bottom: 14, right: 34)
    }
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, itemWidth: CGFloat, caculateHeight indexPath: IndexPath) -> CGFloat {
        let item = items[indexPath.row]
        if let m = item as? HomeStoreConfigModel{
            return m.cellHeight
        }
        if let m = item as? HomeStoreTopBannerModel{
            return m.cellHeight
        }
        return 200
    }
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        var simpleModel:NormalSimpleModel?
WanPai/Root/Home/VC/HomeVC.xib
@@ -52,7 +52,7 @@
                                        <constraint firstAttribute="width" constant="23" id="90D-DW-LT3"/>
                                    </constraints>
                                </imageView>
                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="定位获取中..." textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VD5-cz-3Fs">
                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="定位获取中..." textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VD5-cz-3Fs">
                                    <rect key="frame" x="73" y="21" width="194" height="19.333333333333329"/>
                                    <fontDescription key="fontDescription" type="system" pointSize="16"/>
                                    <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.56999999999999995" colorSpace="calibratedRGB"/>
WanPai/Root/Login/VC/LoginVC.swift
@@ -28,6 +28,7 @@
    @IBOutlet weak var btn_reader: UIButton!
    @IBOutlet weak var cons_stackHei: NSLayoutConstraint!
    @IBOutlet weak var stack_handleView: UIStackView!
    @IBOutlet weak var view_threeParty: UIView!
    
    @IBOutlet weak var cons_loginWidth: NSLayoutConstraint!
@@ -39,6 +40,8 @@
    }
    
    override func setUI() {
        view_threeParty.isHidden = !WXApi.isWXAppInstalled()
        btn_wechat.imagePosition = .top
        btn_wechat.spacingBetweenImageAndTitle = 8
        
WanPai/Root/Login/VC/LoginVC.xib
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22154" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
    <device id="retina6_12" orientation="portrait" appearance="light"/>
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22130"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/>
        <capability name="Named colors" minToolsVersion="9.0"/>
        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
        <capability name="System colors in document resources" minToolsVersion="11.0"/>
@@ -29,6 +29,7 @@
                <outlet property="tf_phone" destination="dXR-3c-p7o" id="7Dm-0N-TNe"/>
                <outlet property="tf_verify" destination="yYG-aW-Yzi" id="v9Z-15-f29"/>
                <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
                <outlet property="view_threeParty" destination="mZh-Vi-57o" id="3xE-7t-wM7"/>
            </connections>
        </placeholder>
        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
WanPai/Root/Other/TCell/StudentInfo_3_TCell.swift
@@ -21,6 +21,7 @@
    @IBOutlet weak var btn_isDefault: UIButton!
    private let disposeBag = DisposeBag()
    var viewModel:StudentExchangeViewModel?
    var studentProfile1Model:StudentProfile1Model!{
        didSet{
@@ -48,8 +49,9 @@
    @IBAction func tobeDefaultAction(_ sender: UIButton) {
        guard studentProfile1Model.isNot == 2 else {return}
        Services.courseDefaultSet(id: studentProfile1Model.stuId).subscribe(onNext: { data in
            NotificationCenter.default.post(name: StudentUpdate_Nofi, object: nil)
        Services.courseDefaultSet(id: studentProfile1Model.stuId).subscribe(onNext: {[weak self] data in
            alertSuccess(msg: "设置成功")
            self?.viewModel?.beginRefresh()
        }).disposed(by: disposeBag)
    }
WanPai/Root/Other/View/StoresChooseView.swift
@@ -54,7 +54,7 @@
            if m.provinceCode != 0{
                storesView.provinceModel = CityProfileModel(id: 0, code: m.provinceCode, name: m.province)
                storesView.getData(m.provinceCode)
                storesView.getStore(m.cityCode,provinceCode: m.provinceCode)
                storesView.getStore(nil,provinceCode: m.provinceCode)
            }
            if m.cityCode != 0{
WanPai/Root/Other/View/StoresChooseView.xib
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22154" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
    <device id="retina6_12" orientation="portrait" appearance="light"/>
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22130"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/>
        <capability name="Named colors" minToolsVersion="9.0"/>
        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
        <capability name="System colors in document resources" minToolsVersion="11.0"/>
@@ -26,16 +26,20 @@
                            <nil key="highlightedColor"/>
                        </label>
                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="YCO-sD-KY4" customClass="TapBtn" customModule="WanPai" customModuleProvider="target">
                            <rect key="frame" x="100.66666666666666" y="222" width="256.33333333333337" height="50"/>
                            <rect key="frame" x="101" y="222" width="256" height="50"/>
                            <subviews>
                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="选择门店" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sjM-7I-k3g">
                                    <rect key="frame" x="14.999999999999986" y="15.333333333333313" width="65.333333333333329" height="19.333333333333329"/>
                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="选择门店" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sjM-7I-k3g">
                                    <rect key="frame" x="15" y="15.333333333333313" width="211" height="19.333333333333329"/>
                                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/>
                                    <color key="textColor" red="0.51372549019607838" green="0.51372549019607838" blue="0.51372549019607838" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                    <nil key="highlightedColor"/>
                                </label>
                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="icon_down_arrow" translatesAutoresizingMaskIntoConstraints="NO" id="ZlA-4r-lHH">
                                    <rect key="frame" x="224.33333333333331" y="18" width="20" height="14"/>
                                    <rect key="frame" x="231" y="21" width="13" height="8"/>
                                    <constraints>
                                        <constraint firstAttribute="height" constant="8" id="TcL-kk-jBs"/>
                                        <constraint firstAttribute="width" constant="13" id="piS-eF-9Jb"/>
                                    </constraints>
                                </imageView>
                            </subviews>
                            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
@@ -43,6 +47,7 @@
                                <constraint firstAttribute="trailing" secondItem="ZlA-4r-lHH" secondAttribute="trailing" constant="12" id="00m-AT-M0M"/>
                                <constraint firstItem="ZlA-4r-lHH" firstAttribute="centerY" secondItem="YCO-sD-KY4" secondAttribute="centerY" id="E8h-qe-LrY"/>
                                <constraint firstItem="sjM-7I-k3g" firstAttribute="leading" secondItem="YCO-sD-KY4" secondAttribute="leading" constant="15" id="UeS-kg-X5f"/>
                                <constraint firstItem="ZlA-4r-lHH" firstAttribute="leading" secondItem="sjM-7I-k3g" secondAttribute="trailing" constant="5" id="aLn-On-uKz"/>
                                <constraint firstAttribute="height" constant="50" id="fpC-Dp-ggR"/>
                                <constraint firstItem="sjM-7I-k3g" firstAttribute="centerY" secondItem="YCO-sD-KY4" secondAttribute="centerY" id="osj-6j-rNm"/>
                            </constraints>
@@ -100,7 +105,10 @@
                            </connections>
                        </button>
                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="门店名称:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Iwt-0W-DTT">
                            <rect key="frame" x="14" y="237.33333333333331" width="81.666666666666671" height="19.333333333333314"/>
                            <rect key="frame" x="14" y="237.33333333333331" width="82" height="19.333333333333314"/>
                            <constraints>
                                <constraint firstAttribute="width" constant="82" id="mWq-d4-rBF"/>
                            </constraints>
                            <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
                            <color key="textColor" red="0.34509803921568627" green="0.34509803921568627" blue="0.34509803921568627" alpha="0.81000000000000005" colorSpace="custom" customColorSpace="sRGB"/>
                            <nil key="highlightedColor"/>
@@ -115,7 +123,7 @@
                                    <nil key="highlightedColor"/>
                                </label>
                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="icon_down_arrow" translatesAutoresizingMaskIntoConstraints="NO" id="uVb-d4-a48">
                                    <rect key="frame" x="195" y="18" width="20" height="14"/>
                                    <rect key="frame" x="202" y="21" width="13" height="8"/>
                                </imageView>
                            </subviews>
                            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
@@ -163,7 +171,7 @@
                                    <nil key="highlightedColor"/>
                                </label>
                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="icon_down_arrow" translatesAutoresizingMaskIntoConstraints="NO" id="p7S-Td-vXl">
                                    <rect key="frame" x="195" y="18" width="20" height="14"/>
                                    <rect key="frame" x="202" y="21" width="13" height="8"/>
                                </imageView>
                            </subviews>
                            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
@@ -252,7 +260,7 @@
        </view>
    </objects>
    <resources>
        <image name="icon_down_arrow" width="20" height="14"/>
        <image name="icon_down_arrow" width="13" height="8"/>
        <namedColor name="FE6E0D">
            <color red="0.99199998378753662" green="0.53299999237060547" blue="0.0080000003799796104" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
        </namedColor>
WanPai/Root/Yard/VC/YardDetailVC.swift
@@ -138,7 +138,7 @@
                weakSelf.web_introduce.loadHTMLString(model.introduce.jq_wrapHtml(), baseURL: nil)
                weakSelf.view_banner.frame = CGRect(origin: .zero, size: CGSize(width: JQ_ScreenW, height: JQ_ScreenW * 0.56))
                let imgs = model.imgs.components(separatedBy: ",")
                var items = [CommonBannerModel]()
                for (index,img) in imgs.enumerated(){
@@ -236,6 +236,9 @@
        view_selectYardType.isHidden = true
        scrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 75, right: 0)
        tf_person.text = UserInfoModel.get()?.userName ?? ""
        tf_phone.text = UserInfoModel.get()?.userPhone ?? ""
    }
        /// 查询优惠券