2015-10-14 44 views
7

In iOS 9 führte Apple die bis UIKit-Dynamics ein.Kollisionsgrenzenpfad einer UIView in iOS 9 einstellen

Ich habe kein Problem bei der Einstellung dieser UIDynamicItemCollisionBoundsTypeRectangle oder wenn ich dies auf UIDynamicItemCollisionBoundsTypeEllipse.

Der Screenshot unten von einem Spiel, das ich mache, wo die collisionBoundsType des Spielers Rechteck gesetzt und die Kugel gesetzt ist Ellipse:

enter image description here

Wenn jedoch stelle ich den collisionBoundsType des Spieler Weg bekomme ich seltsame Verhalten wie hier zu sehen:

enter image description here

der Blick höher erscheint, als es sollte, und die Kollisionskörper nach rechts von wo es sein sollte.

Zur Zeit habe ich collisionBoundingPath Satz dazu:

- (UIBezierPath *)collisionBoundingPath 
{ 
    maskPath = [[UIBezierPath alloc] init]; 
    [maskPath addArcWithCenter:CGPointMake(SLIME_SIZE, SLIME_SIZE) radius:SLIME_SIZE startAngle:0*M_PI endAngle:M_PI clockwise:NO]; 
    return maskPath; 
} 

Zusätzlich meine drawRect Funktion wie folgt aussieht:

- (void) drawRect:(CGRect)rect 
{ 
    if (!_color){ 
    [self returnDefualtColor]; 
    } 
    if (!maskPath) maskPath = [[UIBezierPath alloc] init]; 
    [maskPath addArcWithCenter:CGPointMake(SLIME_SIZE, SLIME_SIZE) radius:SLIME_SIZE startAngle:0*M_PI endAngle:M_PI clockwise:NO]; 
    [_color setFill]; 
    [maskPath fill]; 
} 

Warum ist das passiert? Wie stelle ich den Pfad des Kollisionskörpers so ein, dass er der Zeichnung in der Ansicht entspricht?

Zusätzlich ist das Rot nur der Hintergrund der Ansicht (d. H. view.backgroundColor = [UIColor redColor];).

+0

Kein Zeichnungsexperte, aber die Dokumentation schlägt vor, dass der Pfad ein Polygon sein sollte.Ihr Code fügt einen Bogen hinzu, schließt den Pfad jedoch nicht. Vielleicht sollten Sie '[maskPath closePath]' aufrufen, um einen geschlossenen Pfad zu erstellen, der den Unterschied ausmachen kann? –

+0

Es wird automatisch geschlossen – WMios

+0

Für das Ausfüllen von 'drawRect' wird dies der Fall sein. Bist du dir sicher für deinen 'collisionBoundingPath'? Wo sagt es in den Dokumenten, dass es den Weg schließt? –

Antwort

2

Aus der Dokumentation auf der UIDynamicItem here scheint die folgende Aussage über das Koordinatensystem für Wege darzustellen, was falsch ist:

Das Bahnobjekt Sie einen konvexen Polygon mit Zähler repräsentieren erstellen müssen - im Uhrzeigersinn oder im Uhrzeigersinn Wicklung, und der Pfad darf nicht sich selbst schneiden. Der (0, 0) -Punkt des Pfades muss sich am Mittelpunkt des entsprechenden dynamischen Elements befinden. Wenn der Mittelpunkt nicht mit dem Ursprung des Pfads übereinstimmt, funktioniert das Kollisionsverhalten möglicherweise nicht, da erwartet wird.

Hier heißt es, dass die (0,0) für den Pfad muss der Mittelpunkt sein.

Ich würde denken, dass die Mitte Ihres Bogenweges (0,0) sein sollte und nicht (SLIME_SIZE/2,SLIME_SIZE/2). Haben Sie vielleicht die Breite und Höhe des UIView-Frames auf SLIME_SIZE und nicht auf SLIME_SIZE*2 gesetzt?

SLIME_SIZE scheint wirklich den Radius zu definieren, so sollte die Rahmenbreite SLIME_SIZE*2 sein. Wenn es als SLIME_SIZE eingestellt ist, würde das erklären, warum Sie eine Korrektur durch SLIME_SIZE/2 als Korrektur benötigen.

+0

Große Antwort, das erklärte wirklich die Gründe, warum meine Reparatur funktionierte. – WMios

1

Ich konnte dies beantworten, indem:

- (UIBezierPath *)collisionBoundingPath 
{ 
    maskPath = [[UIBezierPath alloc] init]; 
    [maskPath addArcWithCenter:CGPointMake(SLIME_SIZE, SLIME_SIZE) radius:SLIME_SIZE startAngle:0*M_PI endAngle:M_PI clockwise:NO]; 
    return maskPath; 
} 

zu:

- (UIBezierPath *)collisionBoundingPath 
{ 
    maskPath = [[UIBezierPath alloc] init]; 
    [maskPath addArcWithCenter:CGPointMake(SLIME_SIZE/2, SLIME_SIZE/2) radius:SLIME_SIZE startAngle:0*M_PI endAngle:M_PI clockwise:NO]; 
    return maskPath; 
} 

Der wesentliche Unterschied ist, dass ich das Zentrum des Bogens, der durch 2 durch Division der X- und Y-Werte verändern

1

Debugging Physik ist eine Sache. Es ist wahrscheinlich nichts, worüber iOS-Nutzer viel nachgedacht haben, da sie im Allgemeinen sehr einfache Dinge mit UIKit Dynamics gemacht haben. Das ist eine Schande, denn es ist einer der besten Aspekte der letzten iOS-Versionen und bietet eine wirklich unterhaltsame Möglichkeit, um überzeugende Benutzererlebnisse zu schaffen.

So ... wie Physik zu debuggen? Ein Weg ist, sich geistig vorzustellen, was vor sich geht, und dann das mit dem, was vor sich geht, zu korrelieren und die Dissonanz zwischen dem Imaginären und dem Realen zu finden und dann das Problem durch eine Mischung von Eliminierungsprozessen, mentalen oder realen Versuchen zu lösen & Fehler und Abzug, bis das Problem festgestellt und gelöst ist. Eine andere besteht darin, eine visuelle Darstellung aller geschaffenen und interagierenden Darstellungen zu haben, die ausreichend Feedback liefern, um die Art und Ausmaße von Elementen, ihren Beziehungen und Vorfällen/Ereignissen schneller zu bestimmen und Probleme mit der tatsächlichen Sicht zu lösen.

Zu diesem Zweck wurden seit ihrer Einführung verschiedene visuelle Debugger und Builder für Physiksimulationen erstellt.

Leider hat iOS keinen solchen bildschirmbasierten Editor oder "Szeneneditor" für UIKit Dynamics, und was für diese Art des visuellen Debuggens in Sprite Kit und Scene Kit verfügbar ist, ist bestenfalls rudimentär.

Es gibt jedoch CALayers, die in allen UIKit Views vorhanden sind, in denen CAShapeLayers manuell erstellt und gezeichnet werden können, um alle physikalischen Elemente, ihre Grenzen und ihre Anker und Beziehungen genau darzustellen.

CAShapeLayers sind ein "Container" für CGPaths und können verschiedene Farben für Outline und Fill und mehr als ein CGPath-Element in einem einzelnen CAShapeLayer haben.

Und die große Rob zu zitieren:.

„Wenn Sie eine CAShapeLayer als Schicht auf eine Ansicht hinzufügen, Sie müssen nicht zu sich jede Zeichnung Code implementieren Sie einfach die CAShapeLayer hinzufügen und Du bist fertig, du kannst zum Beispiel später den Pfad ändern, und er wird automatisch von für dich neu gezeichnet. CAShapeLayer bringt dich aus den Unkräutern zum Schreiben deiner eigenen drawRect- oder drawLayer-Routinen. "

Wenn Sie eine enorme Anzahl interagierender Elemente haben und sie debuggen wollen, könnte CAShapeLayer die Performance-Probleme ins Spiel kommen, an welcher Stelle Sie shouldRasterize verwenden können jeweils in eine Bitmap zu konvertieren, und eine deutliche Leistungssteigerung erhalten, wenn Grenzen treffen, die durch die "dynamischen" Fähigkeiten von CAShapeLayers entstehen.

Um CASHapeLayers darzustellen, gibt es einen einfachen Prozess für die Erzeugung von gestrichelten Linien, indem Sie einfach Eigenschaften festlegen. Hier finden Sie die Grundlagen zum Einrichten der Eigenschaften eines CAShapeLayer und die Verwendung eines Arrays zum Erstellen einer gestrichelten 5-5-5-Kontur mit einem Blockstrich, Breite 3, keine Füllung.

CAShapeLayer *shapeLayer = [CAShapeLayer layer]; 
[shapeLayer setBounds:self.bounds]; 
[shapeLayer setPosition:self.center]; 
[shapeLayer setFillColor:[[UIColor clearColor] CGColor]]; 
[shapeLayer setStrokeColor:[[UIColor blackColor] CGColor]]; 
[shapeLayer setLineWidth:3.0f]; 
[shapeLayer setLineJoin:kCALineJoinRound]; 
[shapeLayer setLineDashPattern: 
[NSArray arrayWithObjects:[NSNumber numberWithInt:10], 
    [NSNumber numberWithInt:5],nil]];