21 Replies
      Latest reply on May 17, 2018 9:04 AM by TheRealStarone
      TheRealStarone Level 1 Level 1 (0 points)

        Hello,

         

        I have a pretty simple setup... each row in my Collectionview has a slider and "percent" label below it.  When the user adjusts the slider I want to update the percent label.  The problem is that adjusting the slider doesn't select the row so I can't get the indexPath.  Without the index path I can't get the item so I can't access the label.

         

        I have seen two suggestions repeatedly... one tries to use "superview", but that won't work because the type casting doesn't line up.  The other has multiple iterations of trying to use the coordinates of the tap, but I can't get any of them to work.

         

        Thank you!

        • Re: Collectionview Moving slider in row does not select the row
          Claude31 Level 7 Level 7 (4,255 points)

          I want to update the percent label

           

          What is this percent label ? What does it measures ? The position of the slider ?

           

          If so, why do you want to change the selection ? you have to update directly the label in the IBAction in response to the sent event of the slider :

          - value changed event, to update when dragging the thumb

          - touch up inside when tapping inside

          - touch up outside when tapping outside (may be the same IBAction as for inside)

           

          That would look like this

              @IBAction func sliderChanged(_ sender: UISlider) {
          
                  let max = sender.maximumValue
                  let min = sender.minimumValue
                  let percent = Int(100.0 * (sender.value - sender.minimumValue) / (sender.maximumValue - sender.minimumValue))
                  label.text = String(percent) + " %"
          
                  sender.setNeedsDisplay()     // Not always needed
              }
          
            • Re: Collectionview Moving slider in row does not select the row
              TheRealStarone Level 1 Level 1 (0 points)

              Thank you for your response...

               

              Yes, the percent label shows the position of the slider...  the problem is that I can't access it.  It is a member of the collection view row, not the view controller.  It really doesn't matter if the row gets selected, I just need access to the index path so I can get the item and use

               

              item.percentLabel.text

                • Re: Collectionview Moving slider in row does not select the row
                  Claude31 Level 7 Level 7 (4,255 points)

                  Exact, the slider is hidden and is not in general manipulated directly.

                   

                  So, I tried along this way (but did not fully test):

                  - in IB, add a swipeGestureRecogniqer to collection

                  - in the viewController where the collectionView is, add:

                      @IBAction func swipeDetected(_ sender: UISwipeGestureRecognizer) {
                          print("Swipe detected")
                            // here compute the first visible row, taht will let you compute the %
                      }
                  
                  
                  

                   

                  It does work like this.

                  But I had to add the gesture programmatically :

                  class Item1ViewController: UIViewController,UICollectionViewDataSource,UICollectionViewDelegate, UIGestureRecognizerDelegate {
                      @IBOutlet weak var collectionView: UICollectionView!
                  
                      override func viewDidLoad() {
                          super.viewDidLoad()
                  
                          let swipeGestureUp = UISwipeGestureRecognizer(target: self, action: #selector(swipeDetected))
                          swipeGestureUp.numberOfTouchesRequired = 1
                          swipeGestureUp.direction = .up
                          swipeGestureUp.delegate = self
                          collectionView.addGestureRecognizer(swipeGestureUp)
                  
                          let swipeGestureDown = UISwipeGestureRecognizer(target: self, action: #selector(swipeDetected))
                          swipeGestureDown.numberOfTouchesRequired = 1
                          swipeGestureDown.direction = .down
                          swipeGestureDown.delegate = self
                          collectionView.addGestureRecognizer(swipeGestureDown)
                  
                          let swipeGestureLeft = UISwipeGestureRecognizer(target: self, action: #selector(swipeDetected))
                          swipeGestureLeft.numberOfTouchesRequired = 1
                          swipeGestureLeft.direction = .left
                          swipeGestureLeft.delegate = self
                          collectionView.addGestureRecognizer(swipeGestureLeft)
                  
                          let swipeGestureRight = UISwipeGestureRecognizer(target: self, action: #selector(swipeDetected))
                          swipeGestureRight.numberOfTouchesRequired = 1
                          swipeGestureRight.direction = .right
                          swipeGestureRight.delegate = self
                          collectionView.addGestureRecognizer(swipeGestureRight)
                         
                          collectionView.isScrollEnabled = false // Needed for vertical swipe to be detected ; but clearly, not good !
                      }
                  
                  

                  The problem in my test app is that I have to desable collection view scrolling for vertical swipe to be detected !

                  So you should evaluate the swipe, or decide to move by one row for each swipe, and scroll to the new row (may be select it) in the swipeDetected func.

                   

                      @objc func swipeDetected(sender: UISwipeGestureRecognizer) {
                          print("Swipe detected", sender.direction)
                       // Here, for up and down, scroll by 1 row and redraw accordingly
                      }
                  
              • Re: Collectionview Moving slider in row does not select the row
                Mark6519 Level 1 Level 1 (0 points)

                I know this is already a long thread and I haven't read all of it so appollogies if this is already said or not relevant (I'm pretty new to Swift etc.).

                 

                I have a collection view of images, to get the image tapped I added a gesture recogniser to the image view. Note I'm only doing this to add a border to selected items. In your case you may have to specify a custom cell class to get to the slider.

                 

                Something like:

                      // In viewDidLoad

                      let imagesCVGR = UITapGestureRecognizer(target: self, action: #selector(myTappedFunc))

                      imagesCVGR.delegate = self

                      imagesCVGR.cancelsTouchesInView = false

                      imagesCollectionView.addGestureRecognizer(imagesCVGR)

                 

                 

                   @objc func myTappedFunc(sender: UITapGestureRecognizer){

                    

                      var myRow = 0

                      var indexPath: IndexPath = IndexPath()

                      var loc: CGPoint

                    

                      // Get the point tapped and then the index path for the cell at that point.

                      loc = sender.location(in: imagesCollectionView)

                      if let iP = imagesCollectionView.indexPathForItem(at: loc) {

                         indexPath = iP

                         myRow = iP.row

                      }

                 

                  // Get the cell that was tapped from the indexPath. You should now be able

                  // to get to the slider etc from within the cell.

                  let cell = imagesCollectionView.cellForItem(at: indexPath as IndexPath)

                 

                  // Etc.

                 

                   }