Swift:在CollectionView布局更改中寻找消除代码重复的建议

时间:2018-07-30 09:32:11

标签: swift uicollectionview refactoring flowlayout

我正在寻找最佳实践建议,以消除代码重复。

我有几种不同的CollectionView布局LineUps,用于将球员的位置更改到足球场上。

我可以通过按菜单中的“排队”按钮来更改阵容。

extension TimerBar: LineUpDelegate {
func lineUpSelected(value: String) {
    pitchLayout = value

    switch pitchLayout {
    case "3-2-1":
        print("Change to 3-2-1")
        UIView.animate(withDuration: 0.5, animations: {
            pitchCollectionView?.collectionViewLayout.invalidateLayout()
            pitchCollectionView?.setCollectionViewLayout(lineup7_321, animated: false)
         })
    case "3-1-2":
        print("Change to 3-1-2")
        UIView.animate(withDuration: 0.5, animations: {
            pitchCollectionView?.collectionViewLayout.invalidateLayout()
            pitchCollectionView?.setCollectionViewLayout(lineup7_312, animated: false)
        })
    case ...

    default:
        print(error)
    }
}

目前,setCollectionLayout方法调用了不同的布局类,但是这些文件中唯一的区别是七行代码:

if (indexPath.section == 0 && indexPath.item == 0) {attributes.center = CGPoint(x: column3, y: row15)}
if (indexPath.section == 0 && indexPath.item == 1) {attributes.center = CGPoint(x: column1, y: row3)}
if (indexPath.section == 0 && indexPath.item == 2) {attributes.center = CGPoint(x: column3, y: row3)}
if (indexPath.section == 0 && indexPath.item == 3) {attributes.center = CGPoint(x: column5, y: row3)}
if (indexPath.section == 0 && indexPath.item == 4) {attributes.center = CGPoint(x: column3, y: row45)}
if (indexPath.section == 0 && indexPath.item == 5) {attributes.center = CGPoint(x: column2, y: row6)}
if (indexPath.section == 0 && indexPath.item == 6) {attributes.center = CGPoint(x: column4, y: row6)}

由于我仍在学习Swift,所以我的问题是,在这种情况下,如何消除代码重复。什么是最佳做法解决方案?

我的自定义布局类的副本

import UIKit

class LineUp7_3_1_2: UICollectionViewLayout {

private var cellLayoutAttributes: [IndexPath: UICollectionViewLayoutAttributes] = [:]
private var center: CGPoint!
private var itemSize: CGSize!
private var radiusOfCircleViews: CGFloat!
private var numberOfItems: Int!

var sectionCount : Int?
var cellCount : Int?

// MARK: Overrides

override func prepare() {

    super.prepare()


    guard let collectionView = collectionView else { return }

    register(PitchView.classForCoder(), forDecorationViewOfKind: decorationPitch)
    register(BenchView.classForCoder(), forDecorationViewOfKind: decorationBench)

    radiusOfCircleViews = CGFloat(33.5)
    itemSize = CGSize(width: radiusOfCircleViews * 2, height: radiusOfCircleViews * 2)
    center = CGPoint(x: (collectionView.bounds.midX), y: collectionView.bounds.midY)

    sectionCount = self.collectionView?.numberOfSections
    cellCount = self.collectionView?.numberOfItems(inSection: 0)
}

override var collectionViewContentSize: CGSize {
    return collectionView!.bounds.size
}

override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {

    benchHeight = 70
    pitchHeight = collectionViewContentSize.height - benchHeight!
    pitchWidth = collectionViewContentSize.width

    let halfCell = pitchHeight! / 12

    let row1 = pitchHeight! - halfCell
    let row15 = row1 - halfCell
    let row2 = row15 - halfCell
    let row25 = row2 - halfCell
    let row3 = row25 - halfCell
    let row35 = row3 - halfCell
    let row4 = row35 - halfCell
    let row45 = row4 - halfCell
    let row5 = row45 - halfCell
    let row55 = row5 - halfCell
    let row6 = row55 - halfCell

    let cellwidth = ((pitchWidth! - 32) / 5)
    let column1 = ((pitchWidth! - 32) / 10) + 16
    let column15 = ((pitchWidth! - 32) / 5) + 16
    let column2 = column1 + cellwidth
    let column25 = column15 + cellwidth
    let column3 = column2 + cellwidth
    let column35 = column25 + cellwidth
    let column4 = column3 + cellwidth
    let column45 = column35 + cellwidth
    let column5 = column4 + cellwidth

    let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)

    if (indexPath.section == 0 && indexPath.item == 0) {attributes.center = CGPoint(x: column3, y: row15)}
    if (indexPath.section == 0 && indexPath.item == 1) {attributes.center = CGPoint(x: column1, y: row3)}
    if (indexPath.section == 0 && indexPath.item == 2) {attributes.center = CGPoint(x: column3, y: row3)}
    if (indexPath.section == 0 && indexPath.item == 3) {attributes.center = CGPoint(x: column5, y: row3)}
    if (indexPath.section == 0 && indexPath.item == 4) {attributes.center = CGPoint(x: column3, y: row45)}
    if (indexPath.section == 0 && indexPath.item == 5) {attributes.center = CGPoint(x: column2, y: row6)}
    if (indexPath.section == 0 && indexPath.item == 6) {attributes.center = CGPoint(x: column4, y: row6)}

    let itemCount = collectionView!.numberOfItems(inSection: 1)

    if indexPath.section == 1 {
        for i in 0..<indexPath.item + 1 {
            let z = ((pitchWidth!) / (CGFloat(itemCount) + 1 ))
            let x = (CGFloat(i) * z) + z
            let y = pitchHeight! + (benchHeight! / 2 + 2)
            attributes.center = CGPoint(x: x, y: y)
        }
    }

    attributes.size = itemSize

    return attributes
}

override func layoutAttributesForDecorationView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {

    var frame = CGRect.zero

    if let rows = collectionView?.numberOfItems(inSection: 0), indexPath.row < rows{
        if let cellAtrtributes = layoutAttributesForItem(at: indexPath){
            frame = cellAtrtributes.frame
        }
    }

    if elementKind == decorationPitch {
        let layoutAttributes = UICollectionViewLayoutAttributes(forDecorationViewOfKind: decorationPitch, with: indexPath)

        layoutAttributes.frame = CGRect(x: Int(frame.minX), y: Int(frame.maxY), width: Int(frame.size.width), height: Int(frame.size.height))

        layoutAttributes.zIndex = -1

        return layoutAttributes }
    else {
        let layoutAttributes = UICollectionViewLayoutAttributes(forDecorationViewOfKind: decorationBench, with: indexPath)

        layoutAttributes.frame = CGRect(x: Int(frame.minX), y: Int(frame.maxY), width: Int(frame.size.width), height: Int(frame.size.height))

        layoutAttributes.zIndex = -1

        return layoutAttributes
    }
}

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {

    guard let collectionView = collectionView else { return super.layoutAttributesForElements(in: rect) }
    var visibleAttributes: [UICollectionViewLayoutAttributes] = []

    for section : Int in 0..<sectionCount! {
        let indexPath = IndexPath(row: 0, section: section)

        if section == 0 {
            let background = self.layoutAttributesForDecorationView(ofKind: decorationPitch, at: indexPath)

            print("Pitch Height is \(String(describing: pitchHeight))")
            print("Pitch Width is \(String(describing: pitchWidth))")

            background?.frame = CGRect(x: 0, y: 0, width: pitchWidth!, height: pitchHeight!)
            visibleAttributes.append(background!)
        }

        if section == 1 {
            let bench = self.layoutAttributesForDecorationView(ofKind: decorationBench, at: indexPath)

            bench?.frame = CGRect(x: 0, y: pitchHeight!, width: pitchWidth!, height: benchHeight!)
            visibleAttributes.append(bench!)
        }

    }

    for item in 0 ..< collectionView.numberOfItems(inSection: 0) {
        //let header = self.layoutAttributesForSupplementaryView(ofKind: UICollectionElementKindSectionHeader, at: IndexPath(item: item, section: 0))!

        let indexPath = IndexPath(item: item, section: 0)

        if let attr = layoutAttributesForItem(at: indexPath) {

            //visibleAttributes.append(header)
            visibleAttributes.append(attr)
        }
    }

    for item in 0 ..< collectionView.numberOfItems(inSection: 1) {
        let indexPath = IndexPath(item: item, section: 1)
        if let attr = layoutAttributesForItem(at: indexPath) {
            visibleAttributes.append(attr)
        }
    }
    return visibleAttributes
}
}

非常感谢您的帮助或建议。

0 个答案:

没有答案