简体   繁体   中英

UICollectionView inside UIView not working

I'm trying to add UICollectionView inside a UIView. But it's not interacting in any way. DidSelect in not called. Scrolling is not working.

import UIKit

class AddressSelectionView: UIView {
    
    let mapImageView = UIImageView(image: UIImage(named: "sel_location_map_icon"))
    let lblTitle = AppLabel(font: .regularFont(ofSize: 18), text: "Select Location", color: .Hex_003032)
    let lblSubTitle = AppLabel(font: .regularFont(ofSize: 10), text: "Select the address where you are ordering", color: .okColor)
    
    lazy var addressCollectionView: UICollectionView = {
        let collectionView = UICollectionView(frame: bounds, collectionViewLayout: createLayout())
        collectionView.delegate = self
        collectionView.dataSource = self
        collectionView.registerCell(SelectLocationHorizontalCell.self)
        collectionView.backgroundColor = .clear
        return collectionView
    }()
    
    private var selectedIndex: Int?
    
    init(name: String) {
        super.init(frame: .zero)
        setupUI()
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        addressCollectionView.reloadData()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupUI() {
        isUserInteractionEnabled = true
        self.backgroundColor = .C2E6E0
        self.setCornerRadius(10)
        
        let stack1 = UIStackView(arrangedSubviews: [lblTitle, lblSubTitle])
        stack1.axis = .vertical
        stack1.alignment = .leading
        
        let view1 = UIView()
        view1.addSubview(stack1)
        stack1.snp.makeConstraints { make in
            make.center.leading.trailing.equalToSuperview()
        }
        
        let stack2 = UIStackView(arrangedSubviews: [view1, addressCollectionView])
        stack2.axis = .vertical
        stack2.distribution = .fillEqually
        
        if let image = mapImageView.image {
            let ratio = image.size.height / image.size.width
            mapImageView.snp.makeConstraints { make in
                make.height.equalTo(mapImageView.snp.width).multipliedBy(ratio)
            }
        }
        
        let stackView = UIStackView(arrangedSubviews: [mapImageView, stack2])
        stackView.axis = .horizontal
        stackView.alignment = .fill
        stackView.spacing = 8
        self.addSubview(stackView)
        
        stackView.snp.makeConstraints { make in
            make.edges.equalTo(self)//.inset(UIEdgeInsets(top: 12, left: 12, bottom: 12, right: 12))
        }
    }
    
    
    private func createLayout() -> UICollectionViewLayout {
        let item = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .estimated(100), heightDimension: .fractionalHeight(1)))
        let size = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1))
        let group = NSCollectionLayoutGroup.vertical(layoutSize: size, subitems: [item])
        let layoutSection = NSCollectionLayoutSection(group: group)
        return UICollectionViewCompositionalLayout(section: layoutSection)
    }
}

extension AddressSelectionView: UICollectionViewDelegate, UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 10
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(SelectLocationHorizontalCell.self, for: indexPath)
            cell.nameLabel.text = "Hello Ravi"
            cell.isSelectGredientCell(selectedIndex == indexPath.row)
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        selectedIndex = indexPath.row
        collectionView.reloadData()
    }
}

Any help would be appropriated.

Cell code

class SelectLocationHorizontalCell: UICollectionViewCell, NibLoadableView, ReusableView {
    @IBOutlet weak var nameLabel : UILabel!
    @IBOutlet weak var gredientView : GradientView!

    override func awakeFromNib() {
        super.awakeFromNib()
        self.nameLabel.font = UIFont.regularFont(ofSize: 10)
        gredientView.setCornerRadius(10 * Screen.Scale)
        setCornerRadius(10 * Screen.Scale)
        self.applyShadow(5 * Screen.Scale, CGSize.init(width: 0, height:5 * Screen.Scale), UIColor.init(red: 0, green: 0.19, blue: 0.2, alpha: 0.2), 1)
    }
    
    func isSelectGredientCell(_ isSelectCell : Bool) {
        if isSelectCell {
            self.gredientView.setGredientColors(colors: [UIColor.colorFromHex("EFEDD6").cgColor, UIColor.colorFromHex("FFCC46").cgColor])
        } else {
            self.gredientView.setGredientColors(colors: [UIColor.colorFromHex("C2E6E0").cgColor, UIColor.colorFromHex("BAD09D").cgColor])
        }
    }
    
    func configureCell(_ model: AddressModel?, isSelected: Bool) {
        nameLabel.text = model?.addressName
        self.isSelectGredientCell(isSelected)
    }
    
    func configureCell(_ model: AddressModel?, selectedAddressModel : AddressModel?) {
        nameLabel.text = model?.addressName
        self.isSelectGredientCell(model == selectedAddressModel)
    }
    
    func configureFamilyMemberData(_ model: DependentPersonModel?, selectedFamilyMembers : DependentPersonModel?) {
        nameLabel.text = model?.dependentName
        self.isSelectGredientCell(model?.familyDependentsID == selectedFamilyMembers?.familyDependentsID)
    }


}

class GradientView: UIView {
    override open class var layerClass: AnyClass {
       return CAGradientLayer.classForCoder()
    }

    func setGredientColors(colors : [CGColor]) {
        let gradientLayer = layer as! CAGradientLayer
        gradientLayer.colors = colors
    }
}

A tip for getting help here on Stack Overflow -- post code that reproduces the issue, but does NOT need supporting code.

We should be able to copy/paste your code and run it. With the code you posted, as-is, there are a couple dozen errors because you're using "helper" functions that are known only to you.

Also, I strongly recommend that you start simple .

And, include image(s) that show the problem -- in this case, it would help to see how you expect the layout to look.

Here's what I got after stripping your code down so it will run -- needing only SnapKit in addition to this code:

class ViewController: UIViewController {

    let addSelView = AddressSelectionView(name: "test")
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.addSubview(addSelView)
        
        addSelView.snp.makeConstraints { make in
            make.top.equalTo(view.safeAreaLayoutGuide).offset(20.0)
            make.leading.equalTo(view.safeAreaLayoutGuide).offset(20.0)
            make.trailing.equalTo(view.safeAreaLayoutGuide).offset(-20.0)
            make.height.equalTo(100.0)
        }
    }

}

class SelectLocationHorizontalCell: UICollectionViewCell {
    let nameLabel = UILabel()
    let gredientView = GradientView()

    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    func commonInit() {
        nameLabel.textAlignment = .center

        contentView.addSubview(gredientView)
        contentView.addSubview(nameLabel)
        
        gredientView.snp.makeConstraints { make in
            make.edges.equalTo(contentView)
        }
        nameLabel.snp.makeConstraints { make in
            make.edges.equalTo(contentView.layoutMarginsGuide)
        }
    }
    
    func isSelectGredientCell(_ isSelectCell : Bool) {
        if isSelectCell {
            self.gredientView.setGredientColors(colors: [UIColor.red.cgColor, UIColor.yellow.cgColor])
        } else {
            self.gredientView.setGredientColors(colors: [UIColor.cyan.cgColor, UIColor.yellow.cgColor])
        }
    }

}

class GradientView: UIView {
    override open class var layerClass: AnyClass {
        return CAGradientLayer.classForCoder()
    }
    
    func setGredientColors(colors : [CGColor]) {
        let gradientLayer = layer as! CAGradientLayer
        gradientLayer.colors = colors
    }
}

class AddressSelectionView: UIView {
    
    let mapImageView = UIImageView(image: UIImage(named: "sel_location_map_icon"))
    let lblTitle = UILabel()
    let lblSubTitle = UILabel()
    
    lazy var addressCollectionView: UICollectionView = {
        let collectionView = UICollectionView(frame: bounds, collectionViewLayout: createLayout())
        collectionView.delegate = self
        collectionView.dataSource = self
        collectionView.register(SelectLocationHorizontalCell.self, forCellWithReuseIdentifier: "c")
        collectionView.backgroundColor = .clear
        return collectionView
    }()
    
    private var selectedIndex: Int?
    
    init(name: String) {
        super.init(frame: .zero)
        setupUI()
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        addressCollectionView.reloadData()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupUI() {
        
        lblTitle.text = "Select Location"
        lblSubTitle.text = "Select the address where you are ordering"
        
        isUserInteractionEnabled = true
        self.backgroundColor = .systemYellow
        
        let stack1 = UIStackView(arrangedSubviews: [lblTitle, lblSubTitle])
        stack1.axis = .vertical
        stack1.alignment = .leading
        
        let view1 = UIView()
        view1.addSubview(stack1)
        
        stack1.snp.makeConstraints { make in
            make.center.leading.trailing.equalToSuperview()
        }
        
        let stack2 = UIStackView(arrangedSubviews: [view1, addressCollectionView])
        stack2.axis = .vertical
        stack2.distribution = .fillEqually
        
        if let image = mapImageView.image {
            let ratio = image.size.height / image.size.width
            mapImageView.snp.makeConstraints { make in
                make.height.equalTo(mapImageView.snp.width).multipliedBy(ratio)
            }
        }
        
        let stackView = UIStackView(arrangedSubviews: [mapImageView, stack2])
        stackView.axis = .horizontal
        stackView.alignment = .fill
        stackView.spacing = 8
        self.addSubview(stackView)
        
        stackView.snp.makeConstraints { make in
            make.edges.equalTo(self)
        }
    }
    
    
    private func createLayout() -> UICollectionViewLayout {
        let item = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .estimated(100), heightDimension: .fractionalHeight(1)))
        let size = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1))
        let group = NSCollectionLayoutGroup.vertical(layoutSize: size, subitems: [item])
        let layoutSection = NSCollectionLayoutSection(group: group)
        return UICollectionViewCompositionalLayout(section: layoutSection)
    }
}

extension AddressSelectionView: UICollectionViewDelegate, UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 10
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "c", for: indexPath) as! SelectLocationHorizontalCell
        cell.nameLabel.text = "Ravi \(indexPath.item)"
        cell.isSelectGredientCell(selectedIndex == indexPath.row)
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        selectedIndex = indexPath.row
        collectionView.reloadData()
    }
}

The output:

在此处输入图像描述

and, scrolling the collection view vertically:

在此处输入图像描述

and then selecting a cell:

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM