简体   繁体   中英

Stop UIView from going off screen

I have a UIView that is a circle. That is all the app is - I can move the circle around the screen using a UIPanGestureRecognizer. Now I don't want my circle to be able to be dragged off screen. For example, if I drag the circle to the right, it should stop moving the circle when the right edge hits the edge of the window.

Here is my code:

 switch rec.state {
        case .Began:
            x = fingerLocation.x - (myView?.center.x)!
            y = fingerLocation.y - (myView?.center.y)!
            break


        case .Changed:
            myView?.center.x = fingerLocation.x - x
            myView?.center.y = fingerLocation.y - y

            if (myView?.center.x)! + (myView!.bounds.width/2) >= view.bounds.width {
                myView?.center.x = view.bounds.width - myView!.bounds.width/2
            }
            break
        case .Ended:
            myView?.center = CGPointMake(fingerLocation.x - x, fingerLocation.y - y)
            break
}

This code works if I drag the circle slowly toward the edge. If I drag quickly, the circle will go over the edge, and jump back into view the second another .Changed state is sent. How can I stop the circle from ever going over the edge?

You could check first if the fingerLocation would result in an offscreen view,
and move the view only if it would not move offscreen.

case .Changed: 
   let currentRightEdge = CGRectGetMaxX(myView!.frame)
   let potentialRightEdge = currentRightEdge + fingerLocation.x - x
   if  potentialRightEdge >= view.bounds.width {
     myView?.center.x = view.bounds.width - myView!.bounds.width/2
   }
   else {
     myView?.center.x = potentialRightEdge
   }
   myView?.center.y = fingerLocation.y - y

Also, I do not think you need the break in Swift ;-).

The problem might be that if the view goes offscreen, you set the myView?.center.x twice. Try this:

case .Changed:
            myView?.center.y = fingerLocation.y - y
            var newX : Int = fingerLocation.x - x

            if (newX + (myView!.bounds.width/2)) >= view.bounds.width {
                myView?.center.x = view.bounds.width - myView!.bounds.width/2
            } else {
                myView?.center.x = newX
            }
            break

Try something like this:

case .Changed:
    var targetX = fingerLocation.x - x
    if targetX < 0 {
        targetX = 0
    } else if targetX > CGRectGetWidth(view.bounds) {
        targetX = CGRectGetWidth(view.bounds)
    }

    var targetY = fingerLocation.y - y
    if targetY < 0 {
        targetY = 0
    } else if targetY > CGRectGetHeight(view.bounds) {
        targetY = CGRectGetHeight(view.bounds)
    }

    myView?.center = CGPoint(x: targetX, y: targetY)

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