Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   iOS Radial CGGradient (https://www.delphipraxis.net/178783-radial-cggradient.html)

Crocotronic 27. Jan 2014 14:00

Radial CGGradient
 
Liste der Anhänge anzeigen (Anzahl: 2)
Hallo!
Für meine App brauche ich einen Kreis, der farblich mit Grün beginnt und dann immer röter wird, ohne dass sich die Anfangsfarbe mit der Endfabe vermischt (siehe Anhang 1). Wie das geht, habe ich mir hier abgeguckt und in eine Klasse gesteckt. Jetzt habe ich nur das Problem, dass mir dazu der richtige Gradient fehlt. Was ich raus bekomme, seht ihr auch im Anhang. Auf der Apple-Seite gibt es einiges dazu, aber ich hab immer noch keine Ahnung wie ich das anstellen soll.
Kann mir da vielleicht jemand helfen?

Mein bisheriger Code(Ausschnitt):
Delphi-Quellcode:
 components[0]:= (255/255);
 components[1]:= (50/255);
 components[2]:= (50/255);
 components[3]:= 1;

 components[4]:= (110/255);
 components[5]:= (255/255);
 components[6]:= (48/255);
 components[7]:= 1;

 baseSpace:= CGColorSpaceCreateDeviceRGB();
 gradient:= CGGradientCreateWithColorComponents(baseSpace, @components, nil, 2);
 CGColorSpaceRelease(baseSpace);
 baseSpace:= nil;

 centerPoint:= CGPointMake(ARect.size.width/2, ARect.size.height/2);

 CGContextDrawRadialGradient(context, gradient, centerPoint, 0, centerPoint, ARect.size.width, kCGGradientDrawsAfterEndLocation);
 CGGradientRelease(gradient);
 gradient:= nil;
Viele Grüße
Croco

Crocotronic 5. Feb 2014 20:32

AW: Radial CGGradient
 
Ich hab nun gefunden was ich brauche, aber leider nur in Objective-C.
Hier ist der Code.
In Delphi übersetzt sieht das so aus:
Delphi-Quellcode:
procedure TForm1.UIView1DrawRect(Sender: TObject; ARect: TRectF);
var context: CGContextRef;
    dim: Double;
    subdiv: Integer;
    r,g: Double;
    halfinteriorPerim: Double;
    halfexteriorPerim: Double;
    smallBase: Double;
    largeBase: Double;
    cell: UIBezierPath;
    incr: Double;
    n: Integer;
    rect: CGrect;
begin
 rect:= CGrectMake(aRect.Location.X,aRect.Location.Y,aRect.Size.Width,aRect.Size.Height);

 context:= UIGraphicsGetCurrentContext();

 TUIColor.Wrap(TUIColor.OCClass.whiteColor).setFill;
 UIRectFill(rect);
 dim:= MIN(rect.size.width, rect.size.height);
 subdiv:= 512;
 r:= dim/4;
 g:= dim/2;

 halfinteriorPerim:= PI*r;
 halfexteriorPerim:= PI*g;
 smallBase:= halfinteriorPerim/subdiv;
 largeBase:= halfexteriorPerim/subdiv;

 cell:= TUIBezierPath.Wrap(TUIBezierPath.Alloc.CGPath);
 cell.moveToPoint(CGPointMake(-smallBase/2,r));
 cell.addLineToPoint(CGPointMake(smallBase/2,r));

 cell.addLineToPoint(CGPointMake(largeBase/2,g));
 cell.addLineToPoint(CGPointMake(-largeBase/2,g));
 cell.closePath;

 incr:= PI/subdiv;

 //[[NSColor whiteColor]set];
//    CGContextRef ctx = [[NSGraphicsContext currentContext] graphicsPort];
 CGContextTranslateCTM(context, rect.size.width/2, rect.size.height/2);

 CGContextScaleCTM(context, 0.9, 0.9);
 CGContextRotateCTM(context,PI/2);
 CGContextRotateCTM(context,-incr/2);
 for n:= 0 to subdiv do
 begin
  TUIColor.Wrap(TUIColor.OCClass.blueColor).setFill;
  cell.fill;
  cell.stroke;
  CGContextRotateCTM(context,-incr);
 end;
end;
Funktioniert nur nicht ^^
Weiß jemand warum?

Steku 5. Feb 2014 21:16

AW: Radial CGGradient
 
Hi,

schau' dir doch mal die "mb color lib" an. Da sind
soweit ich mich erinnern kann auch Radial/Ring Color Picker
mit dabei.

Hier mal als Anregung schauen:http://mxs.bergsoft.net/index.php?p=2
Die Sourcen sind auch dabei, vielleicht bringt es dich einen Schritt weiter.

Grüße
Steku

Uppss, IOS, sorry völlig übersehen...

jensw_2000 5. Feb 2014 22:04

AW: Radial CGGradient
 
Zitat:

Zitat von Crocotronic (Beitrag 1246869)
Funktioniert nur nicht ^^
Weiß jemand warum?

"Funktioniert nicht" ist immer einer der deutlichsten Hinweise auf einen Fehler oder dessen Ursache. :wink:

Ich rate mal ins Blaue.
Du rufst die "drawRect" Methode nicht zufällig irgendwo manuell auf, oder?
Das ist eine interne Instanzmethode von UIView.
Wenn Du per Code eine UIView "customDrawen" willst, musst Du dafür eine von UIView abgeleitete Klasse erstellen, die drawRect überlädt. Der View LifeCycle ruft dein eigenes "drawRect" dann automatisch für dich auf, immer wenn iOS der Meinung ist, die View hat sich verändert und muss neu aufgebaut werden.

Da kannst Du natürlich eingreifen, indem Du Cocoa per "UIView.setNeedsDisplay" klarmachst, dass Deine View zum nächst möglichen Zeitpunkt neu gerendert werden soll. Nach dem erneuten rendern setzt Cocoa das "needsDisplay Flag" wieder für Dich zurück.

Crocotronic 6. Feb 2014 16:23

AW: Radial CGGradient
 
Zitat:

Zitat von jensw_2000 (Beitrag 1246875)
Ich rate mal ins Blaue.

Falsch geraten :P
Ich habe mir eine Klasse gebaut, die von UIView erbt und die DrawRect-Methode überschreibt.
Genau gesagt habe ich genau das hier übersetzt.
Funktioniert auch einwandfrei mit dem LinearGradient. Jetzt möchte ich aber einen Kreis, der bei Rot anfängt und bei Grün endet.
Eine Anwendung könnte z.B. eine Drehzahlanzeige (hier natürlich von Grün->Rot) sein.
Deshalb bauche ich ja so einen AngleGradient. Nur irgendwie glaub ich ist mir da etwas bei der Übersetzung misslungen...

jensw_2000 6. Feb 2014 16:46

AW: Radial CGGradient
 
Liste der Anhänge anzeigen (Anzahl: 2)
Dann schau mal ob Dir das weiterhilft.:)

Diese Klasse ist zufällig in einem der Oxygene UIKit Samples enthalten.
Ich hoffe von den Jungs nimmt mir das jetzt keiner krumm, dass ich die Übersetzung an FMXler rausgebe. :pale:

Crocotronic 6. Feb 2014 17:29

AW: Radial CGGradient
 
Ist ja ne lustige Sprache :cyclops:
Zitat:

Zitat von jensw_2000 (Beitrag 1246986)
Ich hoffe von den Jungs nimmt mir das jetzt keiner krumm, dass ich die Übersetzung an FMXler rausgebe. :pale:

:lol: Dann danke ich recht herzlich, dass du das Risiko auf dich genommen hast :wink:

Meine nachgeschriebene Klasse sieht so ziemlich 1:1 so aus (kann ich später auch mal online stellen), jetzt bleibt nur noch die Frage wie ich das ganze von Grün nach Rot wandern lass, ohne dass das Grün am Ende wieder leicht orange wird.

jensw_2000 6. Feb 2014 17:41

AW: Radial CGGradient
 
Ich glaube dazu muss man anstatt des Kreises einen langen rechteckigen View mit einem rot-grün Verlauf horizontal füllen und zum Kreis biegen. Frag mich jetzt nicht wie das geht ... Irgendein CoreGraphics- oder Cocos2DTransform wird das sicher können.

jensw_2000 6. Feb 2014 18:23

AW: Radial CGGradient
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ach verdammt... Jetzt habe ich nur noch bunte Kreise im Kopf. :?
Hier noch schnell 2 Lösungsansätze, damit ich endlich konzentriert weiterarbeiten kann :P

1. Schau mal in den Screenshot.
Du könntest den Gradient relativ leicht mit einem Rotation Transform ein paar Grad nach links drehen und rechts eine rechteckige Fläche in den GraphicsContext malen.
Dann hast Du Deine farblich getrennte Start/Endposition.

2.
male die den Verlauf einfach in Photoshop und hänge ein PNG als Background Image rein, anstatt des Gradients. Den Cycle machst Du in diesem Fall einfach transparent.

Crocotronic 6. Feb 2014 19:07

AW: Radial CGGradient
 
Du bist genial!!! :party:
So werd ichs machen. Vielen, vielen Dank!


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:32 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz