2013-10-20 13 views
6

Ich habe eine UILabel, hardWayLabel, innerhalb einer UIView, hardWayView. Ich brauche diese Ansicht (und folglich das Etikett), um zu einer neuen Position auf der äußersten linken Seite des Bildschirms zu animieren. Während sich das Etikett jedoch an der richtigen Position befindet, bewegt sich die Ansicht weiterhin weit von der linken Seite des Bildschirms weg. Ich verwende den folgenden Code für die Animation (die ich viele andere Male in meinem app erfolgreich):Warum animiert mein UIView zur falschen Position?

 CGRect frame = hardWayView.frame; 
     frame.origin.x = painPoint.x; 
     frame.origin.y = painPoint.y; 
     hardWayView.frame = frame; 
     [UIView beginAnimations:nil context:nil]; 
     [UIView setAnimationDuration:.25]; 

Ich habe NSLog verwendet, um sicherzustellen, dass painPoint.x und painPoint.y sind, was sie sein sollten 9which ist bestätigt durch die Tatsache, dass das UILabel in der richtigen Position endet. Ich denke, die eigentliche Frage ist, warum sich die UIView weiterhin über die Bildschirmgrenzen hinaus bewegt (und nur dann, wenn die UIView von der Mitte des Bildschirms aus nach links animiert wird).

Ich habe Autolayout aktiviert, obwohl ich nicht denke, dass dies der Schuldige ist. Dieses Problem tritt auf, wenn ich die App auf dem iPhone Simulator mit iOS 7 ausführe, und ich kann den Simulator nicht mit iOS 6 laufen lassen. Daher kann ich das Problem nicht auf iOS 7 isolieren (obwohl könnte es sein? eine alte Version von Xcode und die App verwendet keine Storyboards).

Hier ist eine Bildschirmaufnahme des Problems. Wie Sie sehen, funktioniert das Verschieben der beiden Ansichten von links nach rechts normal. Wenn Sie die Ansichten jedoch nach links verschieben, scheint eine der Ansichten (der schwarze Hintergrund) über die linke obere Ecke des Bildschirms hinauszugehen, während die Beschriftung (in orangefarbenem Text) an die richtige Stelle verschoben wird. Explanatory video

Update: Hier ist ein bisschen mehr Code. Es ist fast identisch mit anderen Teilen meiner Anwendung, die einwandfrei funktionieren, was ein bisschen wie ein Gehirn-Blaster ist.

NSString *stringOfRands = tDict[@"originalRand"]; 
if ([stringOfRands rangeOfString:@"+"].location != NSNotFound) 
{ 
    NSArray *arrayOfRands = [stringOfRands componentsSeparatedByString:@" + "]; 

    for (int z=1; z<[arrayOfRands count]; z++) 
    { 
      NSString *updateValue = arrayOfRands[z]; 
      NSInteger newHiddenPosition = [self findBlank:leftSpaces]; 

      NSDictionary *updateStuff = @{@"updateValue": updateValue, @"workingMasterDict":tDict, @"newPos":@(newHiddenPosition), @"newCGPto":@"left", @"@parent":colorV}; 

      [self revealHidden:updateStuff]; 

     } 
} 

Ich glaube, das Problem wirklich während des revealHidden Verfahren geschieht, wo die Animation genannt wird.

[leftSpaces replaceObjectAtIndex:[hardWayPos intValue] withObject:[NSString stringWithFormat:@"full"]]; 
CGPoint painPoint = [[leftPoints objectAtIndex:[hardWayPos intValue]] CGPointValue];  
[UIView animateWithDuration:0.25 animations:^{ 
     CGRect frame = hardWayView.frame; 
     frame.origin.x = painPoint.x; 
     frame.origin.y = painPoint.y; 
     hardWayView.frame = frame; 
    } completion:^(BOOL finished) { 
     // 
    }]; 

hardWayView.hidden=0; 
hardWayView.backgroundColor = [UIColor blueColor]; 
hardWayLabel.textColor = [UIColor orangeColor]; 

habe ich versucht, machen frame.origin.x und .y tatsächlichen Zahlen (im Vergleich zu Variablen) und das gleiche Muster folgt: die UILabel animiert an die richtige Stelle und die UIView animiert von der oberen linken Ecke des Bildschirms off

+0

Schalten Sie das automatische Layout aus und testen Sie es. Es ist wahrscheinlich der Schuldige. – Joel

+0

@Joel leider nicht. Die gleiche Bewegung tritt auf, wenn das automatische Layout deaktiviert ist. – zch

+0

Zuerst ändern Sie den Rahmen und dann starten Sie die Animation. – Exploring

Antwort

10

Whooaa! Nach mehrmaligem Debugging habe ich endlich das Problem gefunden !! :) Lass mich dir sagen ... du hast dort einen interessanten Code. Wie auch immer, Sie werden überrascht sein, wie albern das Problem war; bereit? Hier

ist das Problem:

Strecken Linie 540 Sie haben ein zusätzliches Zeichen „@“, das ist, warum, wenn Sie versuchen, den Wert abzurufen sie es nicht finden können:

//ERROR HERE 
NSArray *arrayOfRands = [stringOfRands componentsSeparatedByString:@" + "]; 

for (int z=1; z<[arrayOfRands count]; z++) 
{ 
    NSString *updateValue = arrayOfRands[z]; 
    NSInteger newHiddenPosition = [self findBlank:leftSpaces]; 

    // This is the line with the error!! 
    // You have @"@parent" but it should be @"parent"  
    NSDictionary *updateStuff = @{@"updateValue": updateValue, @"workingMasterDict":tDict, @"newPos":@(newHiddenPosition), @"newCGPto":@"left", @"@parent":colorV}; 

    [self revealHidden:updateStuff]; 

} 

Es war sehr interessant, um deinen Code zu debuggen!

Prost :)

+0

Sie sind fantastisch. In der Tat, das war das Problem, und ich danke Ihnen für Ihre Zeit bei der Suche nach einem so dummen Tippfehler. Ich hasse die Prämisse, mich dafür zu entschuldigen, dass ich jemanden gebeten habe, meinen Code durchzugehen, aber die Hässlichkeit dieser Datei, die Sie bereinigt haben, ist eine Ausnahme. Ich sagte mir, ich wollte nur die App schreiben und sie dann aufräumen/später über Objective-C lernen ... Es ist unnötig zu sagen, dass dieser Code in Zukunft viel Aufräumen hat. Prost! – zch

+0

Awesome Luis .. wie für Ihre Hingabe zu helfen zch. :) – dRAGONAIR

+0

@dRAGONAIR danke. Deshalb sind wir alle hier ... um uns gegenseitig zu helfen – LuisCien

6

Sie sehen hardWayView.frame = frame; vor dem Start der Animation so, dass die UIView den Standort ändert und dann animiert. Schaltstellen zwischen

hardWayView.frame = frame; 
[UIView beginAnimations:nil context:nil]; 

sollte es beheben.

Unabhängig davon würde ich dringend empfehlen, zu Animationsblöcken zu bewegen. Der obige Code sollte wie folgt aussehen:

[UIView animateWithDuration:0.4 animations:^{ 
CGRect frame = hardWayView.frame; 
frame.origin.x = painPoint.x; 
frame.origin.y = painPoint.y; 
hardWayView.frame = frame; 
} completion:^(BOOL finished) { 
    // 
}]; 
+0

Vielen Dank für den Vorschlag - und ich werde sicherstellen, dass alle Vorkommen meines Animationscodes durch die Blockierungsmethode ersetzt werden. Diese Änderung schien jedoch keine Auswirkungen zu haben. Das Problem besteht weiterhin darin, dass sich die UIView immer noch außerhalb des Bildschirms bewegt, unabhängig davon, auf was "frame.origin.x" und ".y" eingestellt sind. – zch

1

Wäre es nicht besser, Code im Completion Block zu haben? (Oder vor dem animateWithDuration-Block).

[UIView animateWithDuration:0.25 animations:^{ 
       CGRect frame = hardWayView.frame; 
       frame.origin.x = painPoint.x; 
       frame.origin.y = painPoint.y; 
       hardWayView.frame = frame; 
      } completion:^(BOOL finished) { 

      hardWayView.hidden=0; 
      hardWayView.backgroundColor = [UIColor blueColor]; 
      hardWayLabel.textColor = [UIColor orangeColor]; 

      NSDictionary *hardWay = @{@"view": hardWayView, @"label": hardWayLabel, @"intValue":[NSString stringWithFormat: @"%@", hardWayLabel.text], @"hiddenBool":@0, @"position":@([hardWayPos intValue]), @"originalRand": [NSString stringWithFormat: @"%@", hardWayLabel.text]}; 
      [masterDict replaceObjectAtIndex:[masterDict indexOfObject:miniMaser] withObject:hardWay]; 

      }]; 

Außerdem, wenn es ich war, würde ich einen eindeutigen Namen für jedes rect verwenden, um das Debuggen zu erleichtern. z.B. Rufe nicht immer dein rect "Frame" auf. Nennen Sie es centerFrame, leftFrame, rightFrame.

Wenn Sie den Frame des hardWayView am Ende der Animation abmelden meldet er, was Sie erwarten?

Wenn Sie sich am Anfang der Animation aus dem Rahmen des hardWayView ausloggen meldet es, was Sie erwarten?

Meine Vermutung ist der Rahmen von hardWayView ist nicht, was Sie denken, dass es ist.

Funktioniert es wie erwartet, wenn Sie den Frame direkt einstellen, ohne ihn zu animieren?

Verwandte Themen