0
votes

I'm developing an app where users swipe through "cards" which are basically UIViews populated with data from an API.

When the app first opens, cards are created and added as subviews to the superview. Every time a user swipes, the card is removed from the superview.

While the user is swiping, more cards are created and cached in the background.

When the user is on the last card, I add the cached cards to the superview, behind the card that is currently being displayed.

The issue is that while the cards are being added to the superview, my gesture recognizer stops working/glitches (user can't swipe). After a few seconds it starts working again and the user can swipe.

How do I stop the recognizer from glitching? Any insight would be appreciated.

Thank you!

Here's the code that creates/adds the cards // Creating the cards func createCards(firstCall:Bool){

    APICall.begin () { (info) in

        DispatchQueue.main.async {
            for i in info {

                let frontView = frontView()
                let backView = backView()

                // Set up front and back views
                self.viewSetup(view: frontView)
                self.viewSetup(view: backView)

                // Set up card view 
                let view = cardView(frame: frame)
                view.addSubview(backView)
                view.addSubview(frontView)
                self.viewSetup(view: view)
                view.isHidden = true

                // function that add recognizer
                self.dragging(view: view)

                // cacheCard
                if !firstCall{
                    self.cache.add(cardView: view)
                // add to view
                }else{
                    self.view.addSubview(view)
                }

            }

            // Reveal current card
            if firstCall {
                self.view.subviews.last?.isHidden = false
            }

            print("DONE")
        }
    }

}

Heres the code that add the recognizers/ adds cache

// dragging gesture helper
func draggig(card: view){
    let gesture = UIPanGestureRecognizer(target: self, action: #selector(ViewController.wasDragged(_:)))
    view.addGestureRecognizer(gesture)
    view.isUserInteractionEnabled = true

}

// dragged gestrues
func wasDragged(_ gesture: UIPanGestureRecognizer){

    // Only allow dragging when front is showing
    if(showingFront){

        // Dragging code
        let helper = draggingBeganHelper(gesture: gesture)
        let card:UIView = helper[0] as! UIView
        var rotation:CGAffineTransform = helper[1] as! CGAffineTransform
        var stretch:CGAffineTransform = helper.last as! CGAffineTransform

        if gesture.state == UIGestureRecognizerState.ended {

            rotation = CGAffineTransform(rotationAngle: 0)
            stretch = rotation.scaledBy(x: 1, y: 1)

            //Remove card from superview
            card.removeFromSuperview()

            // Store cards in cache
            if(self.view.subviews.count == lastCardIndex + cardOffset){

                createCards(false)

            }

            // When at the second to last card
            else if self.view.subviews.count == lastCardIndex+1{
                if cardCacheArray.isEmpty {
                    createCards(true)
                }
                else{
                    DispatchQueue.main.async {
                        for i in cardCacheArray{
                            self.view.insertSubview(i, belowSubview: self.view.subviews[lastCardIndex])
                        }
                        self.cache.empty()
                    }
                }
            }
        }
    }

}

func draggingBeganHelper(gesture: UIPanGestureRecognizer) -> [AnyObject]{
    // Card dragging gesture setup
    let translation = gesture.translation(in: self.view)
    let card = gesture.view
    card?.center = CGPoint(x: (card?.center.x)! + translation.x, y: (card?.center.y)! + translation.y)
    let xFromCenter = (card?.center.x)! - self.view.bounds.width/2
    let scale = min(100/abs(xFromCenter),1)
    let rotation = CGAffineTransform(rotationAngle:  xFromCenter/200)
    let stretch = rotation.scaledBy(x: scale, y: scale)
    card?.transform = stretch

    return [card!,rotation as AnyObject,stretch as AnyObject]
}
1
Because things work (however eventually) the way you want it probably means you've coded the "base line" right. It would help if you could post some code for us to see. - user7014451
@dfd added the code - Orr Yakobi

1 Answers

0
votes

Figured it out. Loading too many UIViews at once. Much better and smoother approacher would be to continuously recycling two UIViews