滚动时 CollectionView FlowLayout 重叠不起作用 [英] CollectionView FlowLayout overlapping when scrolling not working

查看:19
本文介绍了滚动时 CollectionView FlowLayout 重叠不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

希望你们一切顺利

在这里我创建了一个集合视图流布局,一些场景不起作用,请分享您的参考.这是集合视图

 导入 UIKit类视图控制器:UIViewController {@IBOutlet 弱变量集合:UICollectionView!私有让 kCellHeight: CGFloat = UIScreen.main.bounds.width/2+38私有让 kItemSpace: CGFloat = UIScreen.main.bounds.width/2.08懒惰的 var expand_click = false懒惰的 var index_value = [String]()覆盖 func viewDidLoad() {super.viewDidLoad()collection.delegate = 自我collection.dataSource = 自我让布局 = StickyCollectionViewFlowLayout2()layout.minimumLineSpacing = -kItemSpacecollection.collectionViewLayout = 布局集合.reloadData()}}扩展 ViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) ->诠释{返回 15}func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) ->UICollectionViewCell {让 cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as!集合视图单元打印(索引",indexPath.row)返回单元格}func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) ->CGS 大小 {返回CGSize(宽度:view.frame.width-40,高度:kCellHeight)}func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {如果 (15)-1 == indexPath.row {self.showAlert(alertText:",alertMessage:最后一个单元格")}别的{如果 index_value.contains("(indexPath.row)") {self.showAlert(alertText:",alertMessage:重定向")expand_click = 真}别的{index_value.removeAll()index_value.append("(indexPath.row)")expand_click = 真单元格数据 = indexPath.rowcollectionView.performBatchUpdates({},完成:无)}}}}

集合视图单元格

类 CollectionViewCell: UICollectionViewCell {@IBOutlet 弱 var 容器:UIView!覆盖 func layoutSubviews() {container.backgroundColor = .whitecontainer.layer.cornerRadius = 13container.layer.shadowRadius = 2container.layer.shadowOpacity = 0.7container.layer.shadowOffset = CGSize(宽度: 0, 高度: 1)container.layer.shadowColor = UIColor.black.withAlphaComponent(0.45).cgColor}}

<块引用>

  • 单击单元格时,它将展开单元格并移动到其他单元格下方>* 展开的单元格再次单击它将被重定向到另一个页面 forEx(我显示警报)>*最后一个单元格单击它也应该重定向这些都是我自己做的,如果我们有 15 张卡片,它可以正常工作,超过 50 张卡片>滚动不流畅,我们有一个竞争大小的问题,也许我>无法解决问题

**Collection view FlowLayout**类 StickyCollectionViewFlowLayout2: UICollectionViewFlowLayout {var firstItemTransform: CGFloat?覆盖 func layoutAttributesForElements(in rect: CGRect) ->[UICollectionViewLayoutAttributes]?{let items = NSArray (array: super.layoutAttributesForElements(in: rect)!, copyItems: true)print("------------------------------------------------------------------------------------------------------------------------")print("Count-------->",items.count,"<--------Count")print("------------------------------------------------------------------------------------------------------------------------")var headerAttributes: UICollectionViewLayoutAttributes?self.firstItemTransform = nil如果细胞数据!=零{让 min = cellData!打印(分钟)var b = [UICollectionViewLayoutAttributes?]()var a = 假items.forEach({ (object) in让对象=对象为!UICollectionViewLayoutAttributes如果 min == object.indexPath.row {a = 真}别的{如果一个==真{b.附加(对象)}}})对于 b { 中的属性如果属性?.representedElementKind == UICollectionView.elementKindSectionHeader {headerAttributes = 属性}别的 {self.atributeLayout(属性!,headerAttributes:headerAttributes)}}单元格数据 = 无}别的{items.enumerateObjects(using: { (object, idex, stop) -> Void in让属性=对象为!UICollectionViewLayoutAttributes如果 attributes.representedElementKind == UICollectionView.elementKindSectionHeader {headerAttributes = 属性}别的 {self.atributeLayoutReset(属性,headerAttributes:headerAttributes)}})}退货?[UICollectionViewLayoutAttributes]}func atributeLayout(_ attributes: UICollectionViewLayoutAttributes, headerAttributes: UICollectionViewLayoutAttributes?){让 minY = self.collectionView!.bounds.minY + self.collectionView!.contentInset.topvar maxY = attributes.frame.origin.y+attributes.frame.height/2+80如果让 headerAttributes = headerAttributes {maxY -= headerAttributes.bounds.height}让 finalY = max(minY, maxY)var origin = attributes.frame.origin让 deltaY = (finalY - origin.y)/attributes.frame.height + 100如果让 itemTransform = self.firstItemTransform {让 scale = 1 - deltaY * itemTransformattributes.transform = CGAffineTransform(scaleX: scale, y: scale)}origin.y = finalYattributes.frame = CGRect(原点:原点,大小:attributes.frame.size)attributes.zIndex = attributes.indexPath.row}func atributeLayoutReset(_ 属性: UICollectionViewLayoutAttributes, headerAttributes: UICollectionViewLayoutAttributes?){单元格索引 = 无如果 isExpandCell != true {让 minY = self.collectionView!.bounds.minY + self.collectionView!.contentInset.topvar maxY = attributes.frame.origin.y如果让 headerAttributes = headerAttributes {maxY -= headerAttributes.bounds.height}让 finalY = max(minY, maxY)var origin = attributes.frame.origin让 deltaY = (finalY - origin.y)/attributes.frame.height + 100如果让 itemTransform = self.firstItemTransform {让 scale = 1 - deltaY * itemTransformattributes.transform = CGAffineTransform(scaleX: scale, y: scale)}origin.y = finalYattributes.frame = CGRect(原点:原点,大小:attributes.frame.size)attributes.zIndex = attributes.indexPath.row//})}别的{打印(collectionView!.contentInset.top,collectionView!.bounds.minY)让 minY = 0.0 + collectionView!.contentInset.topvar maxY = attributes.frame.origin.y如果让 headerAttributes = headerAttributes {maxY -= headerAttributes.bounds.height}让 finalY = max(minY, maxY)var origin = attributes.frame.origin让 deltaY = (finalY - origin.y)/attributes.frame.height + 100如果让 itemTransform = firstItemTransform {让 scale = 1 - deltaY * itemTransformattributes.transform = CGAffineTransform(scaleX: scale, y: scale)}origin.y = finalYattributes.frame = CGRect(原点:原点,大小:attributes.frame.size)attributes.zIndex = attributes.indexPath.row}}覆盖 func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) ->布尔 {返回假}}

如果有人体验过收藏视图,请分享您的参考资料谢谢

解决方案

你好,请试试我的代码.我在 iPhone 模拟器上测试过,效果很好.

导入 SwiftUI结构卡视图:查看 {静态让 CARD_HEIGHT: CGFloat = 200静态让 CARD_WIDTH: CGFloat = 300静态让 TAB_HEIGHT: CGFloat = 30@State var selected:Int?= 无让卡:Intvar body: 一些视图 {滚动视图 {ZStack(对齐:.top){ForEach(0 ..

编辑

这样使用

让 swiftUIview = CardView(cards: 10, onCardTapped: { car​​d inprint("卡号(卡)点击")})让 uiViewController = UIHostingController(rootView: swiftUIview)

Gif 因过时而被删除.

I hope you all working fine

Here I have created a collection view flow layouts some scenarios not working, please share your references. here is the collection view

    import UIKit
    class ViewController: UIViewController {
        
        @IBOutlet weak var collection: UICollectionView!
        private let kCellHeight: CGFloat = UIScreen.main.bounds.width/2+38
        private let kItemSpace: CGFloat = UIScreen.main.bounds.width/2.08
        lazy var expand_click = false
        lazy var index_value = [String]()
        
        override func viewDidLoad() {
            super.viewDidLoad()
            collection.delegate = self
            collection.dataSource = self
            let layout = StickyCollectionViewFlowLayout2()
            layout.minimumLineSpacing = -kItemSpace
            collection.collectionViewLayout = layout
            collection.reloadData()
        }
    }
    
    extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
        func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            return 15
        }    
        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as! CollectionViewCell
            print("Index",indexPath.row)
            return cell
        }
        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
            return CGSize(width: view.frame.width-40, height: kCellHeight)
        }
        func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
            if (15)-1 == indexPath.row {
                self.showAlert(alertText: "", alertMessage: "last Cell")
            }else{
                if index_value.contains("(indexPath.row)") {
                    self.showAlert(alertText: "", alertMessage: "Redirect")
                    expand_click = true
                }else{
                    index_value.removeAll()
                    index_value.append("(indexPath.row)")
                    expand_click = true
                    cellData = indexPath.row
                    collectionView.performBatchUpdates({
                    }, completion: nil)
                }
            }
        }
    }

collection view cells

class CollectionViewCell: UICollectionViewCell {
    @IBOutlet weak var container: UIView!
   
    override func layoutSubviews() {
        container.backgroundColor = .white
        container.layer.cornerRadius = 13
        container.layer.shadowRadius = 2
        container.layer.shadowOpacity = 0.7
        container.layer.shadowOffset = CGSize(width: 0, height: 1)
        container.layer.shadowColor = UIColor.black.withAlphaComponent(0.45).cgColor
    }    
}

  • When clicked cell it will be expanding the cell and moved to be under the other the cells > * Expanded cell again click it will be redirected to another page forEx (I showed alert) > * the last cell click it's should also redirect These are all I have done my self if we have 15 cards it working fine more than 50 cards > not smooth scrolling and we have a problem for contending size maybe I > could not solve the issue

**Collection view FlowLayout**


class StickyCollectionViewFlowLayout2: UICollectionViewFlowLayout {
    
    var firstItemTransform: CGFloat?
    
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        let items = NSArray (array: super.layoutAttributesForElements(in: rect)!, copyItems: true)
        
        print("------------------------------------------------------------------------------------------------------------------------")
        print("Count-------->",items.count,"<--------Count")
        print("------------------------------------------------------------------------------------------------------------------------")
        
        
        var headerAttributes: UICollectionViewLayoutAttributes?
        
        self.firstItemTransform = nil
        if cellData != nil {
            let min = cellData!
            print(min)
            var b = [UICollectionViewLayoutAttributes?]()
            var a = false
            items.forEach({ (object) in
                let object  = object as! UICollectionViewLayoutAttributes
                if min == object.indexPath.row {
                    a = true
                }else{
                    if a == true {
                        b.append(object)
                    }
                }
            })
            for attributes in b {
                if attributes?.representedElementKind == UICollectionView.elementKindSectionHeader {
                    headerAttributes = attributes
                }
                else {
                    self.atributeLayout(attributes!, headerAttributes: headerAttributes)
                }
            }
            cellData = nil
        }else{
            items.enumerateObjects(using: { (object, idex, stop) -> Void in
                let attributes = object as! UICollectionViewLayoutAttributes
                
                if attributes.representedElementKind == UICollectionView.elementKindSectionHeader {
                    headerAttributes = attributes
                }
                else {
                    self.atributeLayoutReset(attributes, headerAttributes: headerAttributes)
                }
            })
        }
        return items as? [UICollectionViewLayoutAttributes]
    }
    
    func atributeLayout(_ attributes: UICollectionViewLayoutAttributes, headerAttributes: UICollectionViewLayoutAttributes?){
        let minY = self.collectionView!.bounds.minY + self.collectionView!.contentInset.top
        var maxY = attributes.frame.origin.y+attributes.frame.height/2+80
        if let headerAttributes = headerAttributes {
            maxY -= headerAttributes.bounds.height
        }
        let finalY = max(minY, maxY)
        var origin = attributes.frame.origin
        let deltaY = (finalY - origin.y) / attributes.frame.height + 100
        
        if let itemTransform = self.firstItemTransform {
            let scale = 1 - deltaY * itemTransform
            attributes.transform = CGAffineTransform(scaleX: scale, y: scale)
        }
        origin.y = finalY
        attributes.frame = CGRect(origin: origin, size: attributes.frame.size)
        attributes.zIndex = attributes.indexPath.row
    }
    func atributeLayoutReset(_ attributes: UICollectionViewLayoutAttributes, headerAttributes: UICollectionViewLayoutAttributes?){
        cellIndex = nil
        if isExpandCell != true  {
            let minY = self.collectionView!.bounds.minY + self.collectionView!.contentInset.top
            var maxY = attributes.frame.origin.y
            if let headerAttributes = headerAttributes {
                maxY -= headerAttributes.bounds.height
            }
            let finalY = max(minY, maxY)
            var origin = attributes.frame.origin
            let deltaY = (finalY - origin.y) / attributes.frame.height + 100
            if let itemTransform = self.firstItemTransform {
                let scale = 1 - deltaY * itemTransform
                attributes.transform = CGAffineTransform(scaleX: scale, y: scale)
            }
            origin.y = finalY
            attributes.frame = CGRect(origin: origin, size: attributes.frame.size)
            attributes.zIndex = attributes.indexPath.row
            //            })
        }else{
            print(collectionView!.contentInset.top,collectionView!.bounds.minY)
            let minY = 0.0 + collectionView!.contentInset.top
            var maxY = attributes.frame.origin.y
            if let headerAttributes = headerAttributes {
                maxY -= headerAttributes.bounds.height
            }
            let finalY = max(minY, maxY)
            var origin = attributes.frame.origin
            let deltaY = (finalY - origin.y) / attributes.frame.height + 100
            if let itemTransform = firstItemTransform {
                let scale = 1 - deltaY * itemTransform
                attributes.transform = CGAffineTransform(scaleX: scale, y: scale)
            }
            origin.y = finalY
            attributes.frame = CGRect(origin: origin, size: attributes.frame.size)
            attributes.zIndex = attributes.indexPath.row
        }
    }
    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
        return false
    }
}

if anyone experienced collection view please share me your references Thank you

解决方案

Hello please try my code. I have tested on an iPhone simulator and it works great.

import SwiftUI

struct CardView: View {
    
    static let CARD_HEIGHT: CGFloat = 200
    static let CARD_WIDTH: CGFloat = 300
    static let TAB_HEIGHT: CGFloat = 30
    
    @State var selected: Int? = nil
    let cards: Int
    
    var body: some View {
        ScrollView {
            ZStack(alignment: .top) {
                ForEach(0 ..< cards) { card_i in
                    Button {
                        withAnimation {
                            self.selected = self.selected == card_i ? nil : card_i
                        }
                        print("A card was tapped. Do something with card_i here")
                    } label: { self.card }
                    .buttonStyle(PlainButtonStyle())
                    .frame(width: Self.CARD_WIDTH, height: Self.CARD_HEIGHT, alignment: .top)
                    .offset(x: .zero, y: CGFloat(card_i) * Self.TAB_HEIGHT + ((selected ?? cards + 1) < card_i ? Self.CARD_HEIGHT - Self.TAB_HEIGHT / 2 : 0))
                }
            }
            .frame(height: Self.CARD_HEIGHT + Self.TAB_HEIGHT * CGFloat(cards), alignment: .top)
            .padding()
        }
            
    }
    
    var card: some View {
        RoundedRectangle(cornerRadius: 17, style: .continuous)
            .fill(Color.gray)
            .overlay(RoundedRectangle(cornerRadius: 17, style: .continuous).stroke(Color.black, lineWidth: 5))
    }
}

Edit

Use it like this

let swiftUIview = CardView(cards: 10, onCardTapped: { card in 
    print("card number (card) tapped")
})

let uiViewController = UIHostingController(rootView: swiftUIview)

Gif removed because outdated.

这篇关于滚动时 CollectionView FlowLayout 重叠不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆