2

I'm trying to draw a circle for a visible cell of CollectionView, look like this

enter image description here

I tried to make it trough addSubview and then removeFromSuperview the previous label, but it doesn't work

let myIndex1 = IndexPath(row: 0, section: 0)
    let myIndex2 = IndexPath(row: 1, section: 0)
if indexPath.row == 0 {

    collectionView.cellForItem(at:myIndex1)?.addSubview(labelNew)
            labelNew.layer.backgroundColor = selectedItem.title.cgColor

        }

        if indexPath.row == 1 {

            labelNew.removeFromSuperview()
            collectionView.cellForItem(at:myIndex2)?.addSubview(labelNew2)
            labelNew2.layer.backgroundColor = selectedItem.title.cgColor

        }

What is the right way to draw a circle around a cell of CollectionView which is in the centre at the moment?

Diana
  • 683
  • 1
  • 8
  • 17
  • Can you share any sample project? – Dharmesh Kheni May 05 '19 at 10:49
  • @Dharmesh Yeah, for example, I'm using this project from Github https://github.com/rserentill/iOS-WheelMenu and I want to draw an additional circle around a visible cell. So you can see in this project that label changes every time when cell changes. I want to do the same for an additional circle which I'll draw around the cell. Like here https://ibb.co/L6nSxjb – Diana May 05 '19 at 10:59
  • So you are trying to achieve what is mentioned in your question with this https://github.com/rserentill/iOS-WheelMenu lib? – Dharmesh Kheni May 05 '19 at 11:03
  • @Dharmesh I'm using Github's project as a start project. I'm trying to achieve this https://ibb.co/L6nSxjb – Diana May 05 '19 at 11:04
  • Got it. let me check – Dharmesh Kheni May 05 '19 at 11:05
  • 1
    I believe this circle view shouldn't belong to the collection view cell, but should be added as a subview to the collection view's superview as well. Then just set proper frame, so the circle matches desired position right above the cell. – Antonin Charvat May 05 '19 at 11:31
  • Something like this: https://i.gyazo.com/1a13acb2e23b9c70df01af80f14687c3.gif? – Dharmesh Kheni May 05 '19 at 11:44
  • @Dharmesh No, additional circle around of the previous cell must be removed when the next cell appears – Diana May 05 '19 at 11:53
  • ok that make sense. – Dharmesh Kheni May 05 '19 at 11:55
  • 1
    Check this out: https://i.gyazo.com/0e7cef36687cbf61c8f3e13d7d988dfd.gif – Dharmesh Kheni May 05 '19 at 12:03
  • @Dharmesh yes, I'm trying to do this – Diana May 05 '19 at 12:10
  • @Antonin Charvat I'm trying, but I can't calculate y-position of the background label for the cell. I've got this https://ibb.co/jTCpQvv – Diana May 05 '19 at 12:12
  • 1
    Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/192861/discussion-between-dharmesh-and-diana). – Dharmesh Kheni May 05 '19 at 12:12

1 Answers1

2

For the library you are using. Add an background image in your cell which will be shown as same size as your collectionView and set it hidden by default. then you need to apply the logic in your scrollViewDidScroll method and show background image for cell which is in centre like:

let indexPath = IndexPath(item: currentIndex, section: 0)
if let cell = wheelMenuCollectionView.cellForItem(at: indexPath) as? WheelMenuCollectionViewCell {
    cell.backImage.isHidden = false
}

And to remove previous cell background image you need to add

for (index, _) in items.enumerated() {
    if index != currentIndex {
        let oldIndexPath = IndexPath(item: index, section: 0)
        if let cell = wheelMenuCollectionView.cellForItem(at: oldIndexPath) as? WheelMenuCollectionViewCell {
            cell.backImage.isHidden = true
        }
    }
}

and your scrollViewDidScroll method will look like:

func scrollViewDidScroll(_ scrollView: UIScrollView) {

    let maxOffset = scrollView.bounds.width - scrollView.contentSize.width
    let maxIndex = CGFloat(self.items.count - 1)
    let offsetIndex = maxOffset / maxIndex

    let currentIndex = Int(round(-scrollView.contentOffset.x / offsetIndex)).clamped(to: (0 ... self.items.count-1))

    if self.items[currentIndex].id != self.selectedItem.id {
        self.selectedItem = self.items[currentIndex]
    }

    let indexPath = IndexPath(item: currentIndex, section: 0)
    if let cell = wheelMenuCollectionView.cellForItem(at: indexPath) as? WheelMenuCollectionViewCell {
        cell.backImage.isHidden = false
    }

    for (index, _) in items.enumerated() {
        if index != currentIndex {
            let oldIndexPath = IndexPath(item: index, section: 0)
            if let cell = wheelMenuCollectionView.cellForItem(at: oldIndexPath) as? WheelMenuCollectionViewCell {
                cell.backImage.isHidden = true
            }
        }
    }
}

Now to show first cell highlighted when user start the app you need to add

DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: {
        let indexPath = IndexPath(item: 0, section: 0)
        if let cell = self.wheelMenuCollectionView.cellForItem(at: indexPath) as? WheelMenuCollectionViewCell {
            cell.backImage.isHidden = false
        }
    })

in your viewWillAppear method.

Check THIS sample project for more info.

Dharmesh Kheni
  • 71,228
  • 33
  • 160
  • 165