2016-06-02 10 views
1

Ich habe eine UIImageView, die ich Draggable über eine benutzerdefinierte Klasse namens DraggableImageView2 gemacht habe. Die Klasse wird dann in einem UIViewController mit einem Bild instanziiert und kann innerhalb einer UIView gezogen werden. Die Sache ist, ich möchte die UIImageView beschränken, um die spezifischen Grenzen zu überschreiten, wenn Sie gezogen werden. Hier ist mein aktueller Code:Wie man eine ziehbare UIView auf bestimmte Grenzen beschränkt

import UIKit 

class DraggableImageView2: UIImageView, UIGestureRecognizerDelegate { 

    var dragStartPositionRelativeToCenter : CGPoint? 

    var dragGesture: UIGestureRecognizer! 
    var zoomGesture: UIGestureRecognizer! 

    var lastKnownCenterX: CGFloat = 0.0 
    var lastKnownCenterY: CGFloat = 0.0 

    required init?(coder aDecoder: NSCoder) { 

     super.init(coder: aDecoder) 

     self.initializeGestures() 

    } 


    override init(image: UIImage?) { 

     super.init(image: image) 

     self.initializeGestures() 

    } 

    override init(frame: CGRect) { 

     super.init(frame: frame) 

     self.initializeGestures() 

    } 

    func initializeGestures() { 

     self.userInteractionEnabled = true 
     self.multipleTouchEnabled = true 

     dragGesture = UIPanGestureRecognizer(target: self, action: #selector(DraggableImageView.handlePan(_:))) 

     self.addGestureRecognizer(dragGesture) 

    } 

    func handlePan(recognizer: UIPanGestureRecognizer!) { 

     Scripts.log("PAN >>> MOVE ACTIVATED") 

     if recognizer.state == UIGestureRecognizerState.Began { 

      let locationInView = recognizer.locationInView(superview) 
      dragStartPositionRelativeToCenter = CGPoint(x: locationInView.x - center.x, y: locationInView.y - center.y) 

      return 

     } 

     if recognizer.state == UIGestureRecognizerState.Ended { 

      dragStartPositionRelativeToCenter = nil 

      return 
     } 

     let locationInView = recognizer.locationInView(superview) 

     Scripts.log("PAN LOCATION >>> X = \(self.frame.origin.x) | Y = \(self.frame.origin.y) | LX = \(locationInView.x) | LY = \(locationInView.y) | DX = \(self.dragStartPositionRelativeToCenter!.x) | DY = \(self.dragStartPositionRelativeToCenter!.y)") 

     let xDragMin: CGFloat = 1.0 
     let yDragMin: CGFloat = 1.0 
     let xDragMax: CGFloat = kDEVICE_WIDTH - self.frame.size.width - 1.0 
     let yDragMax: CGFloat = kDEVICE_WIDTH - self.frame.size.height - 1.0 

     var newCenterX: CGFloat = locationInView.x - self.dragStartPositionRelativeToCenter!.x 
     var newCenterY: CGFloat = locationInView.y - self.dragStartPositionRelativeToCenter!.y 

     if self.frame.origin.x < xDragMin { 

      Scripts.log("PAN LOCATION >>> X MIN PAST BOUNDS") 

      newCenterX = lastKnownCenterX 

     } 

     if self.frame.origin.y < yDragMin { 

      Scripts.log("PAN LOCATION >>> Y MIN PAST BOUNDS") 

      newCenterY = lastKnownCenterY 

     } 

     if self.frame.origin.x > xDragMax { 

      Scripts.log("PAN LOCATION >>> X MAX PAST BOUNDS") 

     } 

     if self.frame.origin.y > yDragMax { 

      Scripts.log("PAN LOCATION >>> Y MAX PAST BOUNDS") 

     } 


     UIView.animateWithDuration(0.1) { 
      self.center = CGPoint(x: newCenterX, 
            y: newCenterY) 
     } 

     lastKnownCenterX = newCenterX 
     lastKnownCenterY = newCenterY 

    } 


    func handlePinch(recognizer: UIPinchGestureRecognizer!) { 

     Scripts.log("PINCH >>> ZOOM ACTIVATED") 

     //self.bringSubviewToFront(recognizer.view!) 

     recognizer.view?.transform = CGAffineTransformScale((recognizer.view?.transform)!, recognizer.scale, recognizer.scale) 
     recognizer.scale = 1 

    } 

    func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool { 

     Scripts.log("shouldRecognizeSimultaneouslyWithGestureRecognizer WAS CALLED") 

     return true 

    } 

} 

ich nur habe angefangen, die Arbeit am xDragMin und yDragMin Teil. Alles funktioniert, um es zu stoppen, wenn es weniger als die xDragMin ist, aber das Problem wird aus irgendeinem seltsamen Grund, wenn Sie versuchen, es herausziehen, wird es in diesem X-Punkt eingefroren. Das Gleiche gilt für die yDragMin, eine, wenn die min erreicht, stoppt es wie es sollte, kann aber nicht aus dem Y-Punkt herausziehen.

+0

Can versuchst du, 'lastKnownCenterX' und' lastKnownCenterY' zu loggen? Wenn diese Werte irgendwie auf etwas weniger als "xDragMin" oder "xDragY" gesetzt würden, würde der Rahmen Ihrer Ansicht definitiv in dieser Position hängen bleiben. –

+0

@KyleParent gerade versucht, es zu protokollieren. Nein, es scheint nicht so, als ob die letzten bekannten Punkte niedriger als die Drag Min Points gesetzt wurden. Hier ist eine Beispielausgabe, wo es eingefroren ist: LETZTE BEKANNTE LAGE: PRE: >>> X = 56,75 | Y = 301.75 Zuletzt bekannt Ort: POST: >>> X = 56,75 | Y = 301,75 – Lavvo

+0

Wie lautet die 'frame.origin.x' der Ansicht, wenn' lastKnownCenterX' 56.75 ist? –

Antwort

0

Also nach etwas mehr Graben und Herumspielen, habe ich anscheinend mein eigenes Problem lösen können, zumindest für die X Bounds Min. Hier ist, was ich getan habe:

(1) hinzugefügt, um diese neuen Variablen

var isWithinXBounds: Bool = true 
var lastKnownLX: CGFloat = 0.0 

(2) Die Logik beginnend mit "wenn self.frame.origin.x < xDragMin" benötigt fein abgestimmt werden. Dieser Zustand ist vollkommen in Ordnung, bis er die X-Grenzen erreicht. Sobald dies der Fall ist, wird self.frame.origin.x niemals geändert (DUH), da seine Position jetzt gesperrt ist. Ich brauche eine andere Bedingung, um zu überprüfen, ob, sobald die Schranken getroffen worden sind, d. H. Gesperrt, überprüfe, ob sich die Berührung des Benutzers in eine + ve-Richtung bewegt. Wenn ja, stellen Sie dann den BOOL Wert auf TRUE zurück, die die x-Position frei schaltet

if self.frame.origin.x < xDragMin { 

     Scripts.log("PAN LOCATION >>> X MIN PAST BOUNDS") 

     self.isWithinXBounds = false 

     //If TOUCH still moving in negative direction 
     if locationInView.x - lastKnownLX < 0 { 

      newCenterX = lastKnownCenterX 

     } 
     else { 

      self.isWithinXBounds = true 

     } 

    } 

(3) Dies ist die Bedingung, die dann die UIImageView wird entsperren basierend auf dem BOOL Wert:

if isWithinXBounds { 

     lastKnownCenterX = newCenterX 
     lastKnownLX = locationInView.x 

    }