pre select/highlight UICollectionViewCell on first load of view

后端 未结 9 1254
醉酒成梦
醉酒成梦 2021-02-07 05:48

Im trying to preselect the first object/UICollectionViewCell in the UICollectionView? I have tried:

self.dateCollectionView.allowsMultipleSelection=NO;

[self.da         


        
相关标签:
9条回答
  • 2021-02-07 06:11

    For me, putting it in viewDidAppear: cause a second to select, so the user will see both states (i.e. not selected, and selected). To avoid this, I put it in viewWillAppear: instead and worked like a charm

    override func viewWillAppear(_ animated: Bool) {
        let selectedIndexPath = IndexPath(item: 0, section: 0)
        collectionView.selectItem(at: selectedIndexPath, animated: false, scrollPosition: .left)
    }
    
    0 讨论(0)
  • 2021-02-07 06:14

    In viewDidAppear:

    NSIndexPath *indexPathForFirstRow = [NSIndexPath indexPathForRow:0 inSection:0];
    [self.dateCollectionView selectItemAtIndexPath:indexPathForFirstRow animated:NO scrollPosition:UICollectionViewScrollPositionNone];
    [self collectionView:self.dateCollectionView didSelectItemAtIndexPath:indexPathForFirstRow];
    
    0 讨论(0)
  • 2021-02-07 06:19
    • Here is full code link

    In my case. I solved it via subclass a UICollectionView class with Generic types

    // ******************************************
    //
    // MARK: - Config injection, Extend whatever you want
    //
    // ******************************************
    struct CCCollectionViewConfig {
        var itemSize: CGSize?
        var minimumInteritemSpacing: CGFloat?
        var minimumLineSpacing: CGFloat?
        var allowsDefaultSelection: Bool = true
    }
    
    // ******************************************
    //
    // MARK: - Generic CCCollectionView
    //
    // ******************************************
    final class CCCollectionView<T, Cell: UICollectionViewCell>: UICollectionView, UICollectionViewDataSource, UICollectionViewDelegate {
    
        typealias SelectHandler = (T, IndexPath?) -> Void
    
        typealias CellConfigure = (Cell, T) -> Void
    
        var contents: [T] = [] {
            didSet {
                DispatchQueue.main.async {
                    self.reloadData()
                    self.selectedIndexPath = IndexPath(item: (self.config.allowsDefaultSelection) ? 0 : -1, section: 0)
                }
            }
        }
    
        var configure: CellConfigure
    
        var selectHandler: SelectHandler
    
        var selectedIndexPath: IndexPath
    
        private var config: CCCollectionViewConfig
    
        private let identifier = "identifier"
    
        init(contents: [T], config: CCCollectionViewConfig, configure: @escaping CellConfigure, selectHandler: @escaping SelectHandler) {
    
            self.config = config
            self.contents = contents
            self.configure = configure
            self.selectHandler = selectHandler
            self.selectedIndexPath = IndexPath(item: (config.allowsDefaultSelection) ? 0 : -1, section: 0)
    
            let layout = UICollectionViewFlowLayout()
    
            if let size = config.itemSize {
                layout.itemSize = size
            }
    
            layout.minimumInteritemSpacing = config.minimumInteritemSpacing ?? 0
            layout.minimumLineSpacing = config.minimumLineSpacing ?? 0
            layout.scrollDirection = .vertical
            layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
    
            super.init(frame: .zero, collectionViewLayout: layout)
    
            setup()
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
        private func setup() {
            register(Cell.self, forCellWithReuseIdentifier: identifier)
    
            super.delegate = self
            super.dataSource = self
    
            allowsMultipleSelection = false
            isScrollEnabled = false
            backgroundColor = .clear
        }
    
        // ******************************************
        //
        // MARK: - UICollectionViewDataSource, UICollectionViewDelegate
        //
        // ******************************************
    
        func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            return contents.count
        }
    
        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: identifier, for: indexPath) as! Cell
            cell.isSelected = (selectedIndexPath == indexPath)
            let content = contents[indexPath.row]
            configure(cell, content)
            return cell
        }
    
        func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    
            let content = contents[indexPath.row]
            selectHandler(content, indexPath)
    
            /// If selected item is equal to current selected item, ignore it
            if selectedIndexPath == indexPath {
                return
            }
    
            /// Handle selected cell
            let selectedCell = collectionView.cellForItem(at: indexPath)
            selectedCell?.isSelected = true
    
            /// Handle deselected cell
            let deselectItem = collectionView.cellForItem(at: selectedIndexPath)
            deselectItem?.isSelected = false
    
            selectedIndexPath = indexPath
        }
    }
    
    // ******************************************
    //
    // MARK: - CollectionViewCell
    //
    // ******************************************
    final class CCCollectionViewCell: UICollectionViewCell {
    
        var title: String = "" {
            didSet {
                titleLabel.text = title
            }
        }
    
        private let titleLabel: UILabel = {
            let label = UILabel()
            return label
        }()
    
    
        var _isSelected: Bool = false
        override var isSelected: Bool {
            get {
                return _isSelected
            }
            set(newValue) {
                _isSelected = newValue
                updateSelection()
            }
        }
    
        private func updateSelection() -> Void {
            contentView.layer.borderColor = isSelected ? UIColor.red.cgColor : UIColor.green.cgColor
        }
    
        override init(frame: CGRect) {
            super.init(frame: frame)
            contentView.addSubview(titleLabel)
            contentView.layer.cornerRadius = 2.0
            contentView.layer.borderWidth = 2.0
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }
    

    Then use it inside your ViewController

    private let fakeContents = Array(repeating: "123123", count: 40)
    
    /// Collection View Config
    private lazy var config: CCCollectionViewConfig = {
        return CCCollectionViewConfig(itemSize: CGSize(width: 100, height: 30),
                                      minimumInteritemSpacing: 4.0,
                                      minimumLineSpacing: 4.0)
    }()
    
    /// Collection View Config
    private lazy var collectionView: CCCollectionView<String, CCCollectionViewCell> = {
        let cv = CCCollectionView<String, CCCollectionViewCell>(contents: fakeContents, config: config, configure: { (cell: CCCollectionViewCell, content) in
            cell.title = content
        }) { [weak self] (content, indexPath) in
            guard let self = self else { return }
            guard let row = indexPath?.row else { return }
        }
        return cv
    }()
    
    0 讨论(0)
提交回复
热议问题