2017-11-16 8 views
0

Ich habe eine UIView in einer Portrait-App.Wie man zentriertes Quadrat nach oben animiert

  • Die Ansicht wird vertikal zentriert und horizontal mit AutoLayout ("manuell" können Storyboards).
  • Die width entspricht die (main)view.width * 0.9
  • Die height die gleiche Größe der Breite ist (es ist ein Quadrat).

Ich möchte in diesem UIView eine Schaltfläche tippen und sie animieren nur vertikal, bis sie den oberen Rand des Bildschirms erreicht (z. B. Höhe * 0,9, 10 Punkte, was auch immer möglich ist).

Wenn ich noch einmal klicke, möchte ich die Ansicht wieder auf ihre ursprüngliche Position positionieren (zentriert wie beim ersten Antippen).

Während des Übergangs sollte das Quadrat nicht tappbar sein.

Nach dem Lesen vieler Beiträge konnte ich nicht verstehen, was der beste Weg ist, dies zu tun

Ich denke, ich sollte einen Weg finden, um die aktuelle "Position" der Beschränkungen zu erhalten und eine Beschränkung der "endgültigen" Position zuzuweisen, aber ich war nicht in der Lage, es zu tun.

Jede Hilfe

+0

Was sind die Einschränkungen für die Ansicht? – Sweeper

+0

Wie ich schon sagte, ist es vertikal und horizontal zur ViewController-Hauptansicht zentriert und seine Höhe und Breite sind definiert als 0.9 der Breite der ViewController Breite –

+0

Setze uiview center wie x = (main) view.center.x, und y wie y = squreView.frame.origion.x + squreView.frame.height/2 All diese Sachen in uiview.Animation-Funktion und wenn Sie zurück wollen squre Zentrum wie (main) view.center –

Antwort

0

geschätzt Während Sie Automatische Anordnung animieren können - die Einschränkung nehmen Sie die centerY Zwangs und legen Sie seine konstant auf einen Wert, nach oben bewegen würde (zB constant = -(UIScreen.main.bounds.height/2)), würde ich mit empfehlen Ansicht transform Eigenschaft.

So die Ansicht nach oben zu bewegen, die Sie verwenden können:

let topMargin = CGFloat(20) 
let viewHalfHeight = self.view.bounds.height/2 
let boxHalfHeight = self.box.bounds.height/2 
UIView.animate(withDuration: 0.2) { 
    box.transform = CGAffineTransform.identity 
     .translatedBy(x: 0, y: -(viewHalfHeight - (boxHalfHeight + topMargin))) 
} 

Sie box.center zum view.center Zusammenhang bewegen - also, wenn Sie die Box nach oben verschieben möchten, müssen Sie seine center bewegen um die halbe Höhe (weil die Ansicht centerY ist genau height/2 weit von der Ansicht top). Das ist jedoch nicht genug, denn dann ist nur eine untere Hälfte der Box sichtbar (jetzt die box.centerY == view.top). Daher müssen Sie es um die box.bounds.height/2 (in meinem Code boxHalfHeight) verschieben - um die obere Hälfte sichtbar zu machen. Und zu diesem boxHalfHeight fügst du topMargin hinzu, so dass es etwas Spielraum zum oberen gibt.

Dann bewegen die box zurück in die ursprüngliche Position:

UIView.animate(withDuration: 0.2) { 
    box.transform = CGAffineTransform.identity 
} 

EDIT

Wenn Sie wirklich mit automatischen Layout gehen wollen, müssen Sie die centerY Constraint eine Referenz haben, so zum Beispiel, wenn es auf diese Weise erstellt:

let boxCenterYConstraint = self.box.centerYAnchor.constraint(equalTo: self.view.centerYAnchor) 
boxCenterYConstraint.isActive = true 

Dann folgendes versuchen:

// calculating the translation is the same 
let topMargin = CGFloat(20) 
let viewHalfHeight = self.view.bounds.height/2 
let boxHalfHeight = self.box.bounds.height/2 
let diff = -(viewHalfHeight - (boxHalfHeight + topMargin)) 

boxCenterYConstraint.constant = diff 
self.view.setNeedsLayout() 
UIView.animate(withDuration: 0.2) { 
    self.view.layoutIfNeeded() 
} 

und Animation zurück:

boxCenterYConstraint.constant = 0 
self.view.setNeedsLayout() 
UIView.animate(withDuration: 0.2) { 
    self.view.layoutIfNeeded() 
} 
+0

Der erste Code bewegt die Ansicht nach unten (und es ist halb off-Screen). Ich will es und 10 Punkte (oder so ..., nur um Kollisionen mit der Zeit, Batterie, etc. zu vermeiden) beginnend von oben. Das Voranstellen eines Minuszeichens an self.view ... verursacht denselben Effekt (aber von oben beginnend) –

+0

'CGAffineTransform.identity.translatedBy (x: 0, y: - (self.view.bounds.height/2))' tut nicht arbeiten?es sollte die Ansicht nach oben verschieben (das Minuszeichen war mein Fehler ..) –

+0

Es verschiebt die Ansicht nach oben, aber es wird halb off-screen angezeigt: Es sollte vollständig (jedes Gerät) auf dem Bildschirm und es sollte 10 Punkte sein von Rand zu –

0

Sie alles über diese in die falsche Richtung gehen.

Fügen Sie eine Einschränkung hinzu, die die Ansicht an die Spitze anpinnt, und fügen Sie eine Einschränkung hinzu, die die Ansicht an centerY anpinnt. Es wird sich beschweren, also wähle eins und deaktiviere es (ich denke, die Eigenschaft in Interface Builder heißt Installed).

Wenn der Ausgangszustand die Ansicht in der Mitte ist, deaktivieren Sie die Integritätsbedingung, die sie an die Spitze anheftet, und umgekehrt.

Jetzt schreiben Sie IBOutlets für beide Constraints in Ihrem Controller und verbinden Sie sie mit diesen Constraints. Stellen Sie sicher, dass die Deklaration dieser Variablen nicht weak ist, andernfalls wird die Variable null, wenn die Einschränkung deaktiviert ist.

Wenn Sie Ihre Animation umschalten möchten, können Sie eine Einschränkung aktivieren und die andere deaktivieren.

@IBOutlet var topConstraint: NSLayoutConstraint! 
@IBOutlet var centerConstraint: NSLayoutConstraint! 

func toggleState(moveToTop: Bool) { 
    UIView.animateWithDuration(0.25) { 
    self.topConstraint.isActive = moveToTop 
    self.centerConstraint.isActive = !moveToTop 
    self.view.layoutIfNeeded() 
    } 
} 
Verwandte Themen