2017-02-03 18 views
0

Ich kann einen einzigen UIView mit dem Code unten verschieben, aber wie verschiebe ich mehrere UIView 's einzeln mit IBOutletCollection und tag Werte?Wie kann ich Bilder ziehen

class TeamSelection: UIViewController { 

    var location = CGPoint(x: 0, y: 0) 

    @IBOutlet weak var ViewTest: UIView! // move a single image 
    @IBOutlet var Player: [UIView]! // collection to enable different images with only one outlet 

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 

     let touch: UITouch = touches.first! as UITouch 
     location = touch.location(in: self.view) 
     ViewTest.center = location 

    } 

} 

Antwort

0

Es gibt zwei grundlegende Ansätze:

  1. Sie durch Ihre Subviews heraus herauszufinden laufen könnte, in dem man die berühren schnitten und bewegen. Aber dieser Ansatz (oder die Verwendung kryptischer tag numerischer Werte zur Identifizierung der Ansicht) ist im Allgemeinen nicht die bevorzugte Methode.

  2. Persönlich würde ich die Drag-Logik in der subview setzen sich:

    class CustomView: UIView {  // or subclass `UIImageView`, as needed 
    
        private var originalCenter: CGPoint? 
        private var dragStart: CGPoint? 
    
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
         originalCenter = center 
         dragStart = touches.first!.location(in: superview) 
        } 
    
        override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 
         guard let touch = touches.first else { return } 
         var location = touch.location(in: superview) 
         if let predicted = event?.predictedTouches(for: touch)?.last { 
          location = predicted.location(in: superview) 
         } 
         center = dragStart! + location - originalCenter! 
        } 
    
        override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { 
         guard let touch = touches.first else { return } 
         let location = touch.location(in: superview) 
         center = dragStart! + location - originalCenter! 
        } 
    } 
    
    extension CGPoint { 
        static func +(lhs: CGPoint, rhs: CGPoint) -> CGPoint { 
         return CGPoint(x: lhs.x + rhs.x, y: lhs.y + rhs.y) 
        } 
        static func -(lhs: CGPoint, rhs: CGPoint) -> CGPoint { 
         return CGPoint(x: lhs.x - rhs.x, y: lhs.y - rhs.y) 
        } 
    } 
    

    Denken Sie daran, „Interaktion mit dem Benutzer aktiviert“, um für die Subviews wenn Sie diesen Ansatz verwenden.

  3. Übrigens, wenn Sie Ansichten wie diese ziehen, stellen Sie sicher, dass Sie keine Einschränkungen für diese Ansichten haben oder wenn die Auto-Layout-Engine als nächstes angewendet wird, wird alles an den ursprünglichen Speicherort verschoben. Wenn Sie automatisches Layout verwenden, ändern Sie im Allgemeinen die constant der Einschränkung.


Ein paar Beobachtungen an diesem ziehen Logik:

  • Vielleicht möchten prädiktiven berührt verwenden, wie oben, lagginess des Widerstand zu verringern.

  • Anstatt die center zum location(in:) der Berührung bewegt, würde ich eher im Auge behalten, wie viel ich es gezogen und entweder die center entsprechend bewegen oder eine entsprechende Übersetzung anwenden. Es ist ein netteres UX, IMHO, denn wenn du die Ecke greifst, kannst du an der Ecke ziehen, anstatt es in die Mitte der Ansicht springen zu lassen, wo die Berührung auf dem Bildschirm war.

+0

Danke, wie würde ich @IBOutlet var Player verwenden: [UIView]! innerhalb der Funktionen, um ein Bild zu bewegen – Chet

+0

@Chet - Die Tatsache, dass Sie Steckdose haben, ist irrelevant. Die Frage ist, wie Sie diese Ansichten instanziiert haben. Wenn Sie sich beispielsweise in IB befinden, stellen Sie sicher, dass die Basisklasse für diese Player-Ansichten die oben gezeigte benutzerdefinierte Klasse ist. Aber das ganze '@ IBOutlet'-Zeug ist unverändert – Rob

+0

Ich habe vergessen, die Unterklasse dem imagueView zuzuordnen – Chet

0

würde ich eine Unterklasse von UIView erstellen, die Ziehen unterstützt. Etwas wie:

class DraggableView: UIView { 

      func setDragGesture() { 
       let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(DraggableView.handlePanGesture(_:))) 
       addGestureRecognizer(panRecognizer) 
      } 

     func handlePanGesture(_ recognizer: UIPanGestureRecognizer) { 
      guard let parentView = self.superview else { return } 

      let translation = recognizer.translation(in: parentView) 
      recognizer.view?.center = CGPoint(x: recognizer.view!.center.x + translation.x, y: recognizer.view!.center.y + translation.y) 
      recognizer.setTranslation(CGPoint.zero, in: self) 
     } 


      func getLocation() -> CGPoint { 
      return UIView().convert(center, to: self.superview) 
     } 
    } 

So können Sie eine Reihe von ziehbar Ansichten hinzufügen und dann für den Standort fragen, wenn Sie die Anzeige, dass View-Controller beenden müssen.

Verwandte Themen