Project download link
Ich glaube nicht, ist es notwendig, Quarz verlassen diese Wiedergabe zu erreichen. Alles, was Sie beschrieben haben, und alles, was ich aus Impress.js zusammengetragen habe, scheint replizierbar zu sein, indem Transformationen (meist 2D, einige 3D) auf eine Reihe von UILabels angewendet werden, die zu einer Containeransicht hinzugefügt werden Hauptansicht.
Um dies zu tun, das Projekt, das ich erstellt wurde, verwendet eine Unterklasse von UILabel
dem Titel „ImpressLabel“ mit einer zusätzlichen Funktion init wo statt dem Etikett einen Rahmen vorbei, können Sie es eine Größe, einen Mittelpunkt und ein CGFloat
für den Pass Label-Rotation auf der Z-Achse. Diese Transformation wird beim Instanziieren auf die Beschriftung angewendet, sodass sie beim Einrichten der Beschriftungen bereits in der von Ihnen angegebenen Position und Transformation auf dem Bildschirm angezeigt wird.
Dann, soweit die Konfiguration des Textes geht, können Sie das Etikett ein NSAttributedString
anstelle von NSString
übergeben. Auf diese Weise können Sie verschiedene Teile des Strings können unabhängig voneinander in dem Etikett sein, verschiedene Größen, Schriftart, Farben, Hintergrundfarben usw. ein Beispiel der obigen beiden Absätzen Hier ist, so verschiedene Wörter ändern:
ImpressLabel *label1 = [[ImpressLabel alloc] initWithSize:CGSizeMake(260.0f, 80.0f) andCenterPointInSuperview:CGPointMake(500.0f, 500.0f) andRotationInSuperview:0.0f andEndingScaleFactor:1.3];
NSMutableAttributedString *firstLabelAttributes = [[NSMutableAttributedString alloc] initWithString:@"then you should try\nimpress.js*\n* no rhyme intended"];
[firstLabelAttributes addAttribute:NSFontAttributeName
value:[UIFont systemFontOfSize:label1.font.pointSize - 2]
range:NSMakeRange(0, 19)];
[firstLabelAttributes addAttribute:NSFontAttributeName
value:[UIFont systemFontOfSize:label1.font.pointSize - 8]
range:NSMakeRange(firstLabelAttributes.string.length - 19, 19)];
[firstLabelAttributes addAttribute:NSFontAttributeName
value:[UIFont boldSystemFontOfSize:label1.font.pointSize + 14]
range:NSMakeRange(23, 11)];
[label1 setNumberOfLines:3];
[label1 setAttributedText:firstLabelAttributes];
[label1 setTextAlignment:NSTextAlignmentCenter];
[containmentView addSubview:label1];
Jetzt, auf mehr von den Eingeweiden der ganzen Operation. Wie ich oben erwähnt habe, fügt diese Unterklasse jedem Label eine Tippgeste hinzu. Wenn ein Tippen erkannt wird, passieren ein paar Dinge. Die Ansicht mit den Beschriftungen wird durch Anpassen der Skalierung verschoben/zurück/entfernt. Es wird auch beginnen, zu rotieren und seinen Ankerpunkt in der Hauptansicht so anzupassen, dass die ausgewählte Beschriftung auf dem Bildschirm in der richtigen Ausrichtung zentriert wird, wenn die Animation stoppt. Dann, während dies alles läuft, wird das Alpha des ausgewählten Labels auf 1,0 f angehoben, während das Alpha des Rests auf 0,25 f gesenkt wird.
- (void)tapForRotationDetected:(UITapGestureRecognizer *)sender {
CABasicAnimation *scale = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
[scale setToValue:[NSNumber numberWithFloat:0.8]];
[scale setAutoreverses:YES];
[scale setDuration:0.3];
//Create animation to adjust the container views anchorpoint.
CABasicAnimation *adjustAnchor = [CABasicAnimation animationWithKeyPath:@"anchorPoint"];
[adjustAnchor setFromValue:[NSValue valueWithCGPoint:self.superview.layer.anchorPoint]];
[adjustAnchor setToValue:[NSValue valueWithCGPoint:CGPointMake(self.center.x/self.superview.frame.size.width, self.center.y/self.superview.frame.size.height)]];
[adjustAnchor setRemovedOnCompletion:NO];
[adjustAnchor setFillMode:kCAFillModeForwards];
//Create animation to rotate the container view within its superview.
CABasicAnimation *rotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
//Create the animation group to apply these transforms
CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
[animationGroup setAnimations:@[adjustAnchor,rotation]];
[animationGroup setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
[animationGroup setDuration:0.6];
//Apply the end results of the animations directly to the container views layer.
[self.superview.layer setTransform:CATransform3DRotate(CATransform3DIdentity, DEGREES_TO_RADIANS(-self.rotationInSuperview), 0.0f, 0.0f, 1.0f)];
[self.superview.layer setAnchorPoint:CGPointMake(self.center.x/self.superview.frame.size.width, self.center.y/self.superview.frame.size.height)];
[self.superview.layer addAnimation:animationGroup forKey:@"animationGroup"];
//Animate the alpha property of all ImpressLabels in the container view.
[self.superview bringSubviewToFront:self];
[UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
for (ImpressLabel *label in sender.view.superview.subviews) {
if ([label isKindOfClass:[ImpressLabel class]]) {
if (label != self) {
[label setAlpha:0.25f];
}else{
[label setAlpha:1.0f];
}
}
}
} completion:nil];
}
nun einige der Bedenken in der Frage genannten Adresse.
Ich habe dieses Projekt in Zuteilungen Werkzeug Instruments profiliert und es verbraucht nur etwa 3,2 MB insgesamt, so würde ich sagen, dieser Ansatz effizient genug ist.
Das von mir zur Verfügung gestellte Beispiel animiert die meisten Objekte im 2D-Raum, mit Ausnahme der Skalierungsanimation, die bestenfalls eine Illusion ist. Was ich hier gemacht habe, soll als ein Beispiel dafür dienen, wie das gemacht werden kann und ist keine 100% vollständige Demonstration, weil, wie ich oben erwähnte, Animation wirklich nicht mein Fachgebiet ist. Wenn man jedoch über die Dokumente blickt, scheint es der Schlüssel zu sein, ein Etikett in der dritten Dimension rotieren zu lassen und seine Superansicht anzupassen, um alle Etiketten zu drehen und das ausgewählte Etikett flach zu lassen, wäre die Verwendung von CATransform3DInvert()
. Obwohl ich noch keine Zeit hatte, um herauszufinden, ob es funktioniert, scheint es genau das zu sein, was in diesem Szenario benötigt wird.
Soweit Spiegelung geht, glaube ich nicht, dass es Probleme mit der richtigen Skalierung alles geben wird. Wenn man über Apples Multiple Display Programming Guide schaut, sieht es so aus, als ob das an die NSNotification
UIScreenDidConnectNotification
übergebene Objekt ein UIScreen
Objekt ist. Da dies der Fall ist, können Sie leicht nach diesen Anzeigengrenzen fragen und die Rahmen der Etiketten und der Containeransicht entsprechend anpassen.
Anmerkung: In diesem Beispiel werden nur 0, 90, 180 und -90 Grad transformiert richtig 100% animieren, aufgrund der Koordinaten des Ankerpunkt falsch erzeugt wird. Es sieht so aus, als ob die Lösung bei CGPointApplyAffineTransform(<#CGPoint point#>, <#CGAffineTransform t#>)
liegt, aber ich hatte wieder nicht so viel Zeit damit zu spielen, wie ich es mir gewünscht hätte. In jedem Fall sollte dies ausreichen, um mit Ihrer Reproduktion zu beginnen.
Dies hat definitiv mein Interesse geweckt, und wenn ich die Möglichkeit habe, nochmal daran zu arbeiten, werde ich diesen Beitrag gerne mit neuen Informationen ergänzen. Hoffe das hilft!
Wie auch immer, sehen Sie sich CATransformLayer als eine Möglichkeit an, Layer zu gruppieren und zu transformieren. –
Aktualisierte Frage, um nach dem Skalieren eines UILabel auf den Speicherverbrauch zu konzentrieren. Die vorherige Frage war zu weit gefasst (und als solche geschlossen). Obwohl die derzeit akzeptierte Antwort fantastisch ist, wird das Problem in der aktualisierten Frage nicht angesprochen. Während ich noch ein Bounty darauf setzen möchte, habe ich sehr wenig Rep, um weitere 500 fallen zu lassen. – Luke