Schatten um einen View zeichnen

  • Schatten um einen View zeichnen

    Hallo,

    ich habe mir eine UIView-Subklasse gebaut, die einen Schatten um den enthaltenen View zeichnen soll. Doch leider erscheint kein Schatten :(

    Hier ist die drawRect-Methode:

    Quellcode

    1. - (void)drawRect:(CGRect)inRect {
    2. CGContextRef theContext = UIGraphicsGetCurrentContext();
    3. CGContextSaveGState(theContext);
    4. CGContextSetShadowWithColor(theContext, offset, blur, [UIColor blackColor].CGColor);
    5. [super drawRect:inRect];
    6. CGContextRestoreGState(theContext);
    7. }


    Was mache ich verkehrt?
    „Meine Komplikation hatte eine Komplikation.“
  • RE: Schatten um einen View zeichnen

    Original von macmoonshine
    Hallo,

    ich habe mir eine UIView-Subklasse gebaut, die einen Schatten um den enthaltenen View zeichnen soll. Doch leider erscheint kein Schatten :(

    Hier ist die drawRect-Methode:

    Quellcode

    1. - (void)drawRect:(CGRect)inRect {
    2. CGContextRef theContext = UIGraphicsGetCurrentContext();
    3. CGContextSaveGState(theContext);
    4. CGContextSetShadowWithColor(theContext, offset, blur, [UIColor blackColor].CGColor);
    5. [super drawRect:inRect];
    6. CGContextRestoreGState(theContext);
    7. }


    Was mache ich verkehrt?



    Für mich sieht das so aus, dass du den Schatten deiner View in die eigene View zeichnen willst, geht jedoch nicht, da daine View kleiner ist als diene View inklusive Schatten...

    Versuch einfach mal ein Rechteck in dein View zu zeichnen das kleiner als deine View ist, indem du:

    [super drawRect:inRect];

    durch:

    CGContextFillRect(theContext, aRect);

    ersetzt, wobei aRect kleiner als dein inRect sein soll. Wenn du dann ein Rechteck mit einem Schatten erhälst, dann stimmt das was ich oben vermutet habe.

    mfg Henri
  • Danke für Deinen Tipp. Der hat mich auf den richtigen Gedankengang gebracht. Sowas Ähnliches hatte ich auch schon probiert. Das hatte aber auch nicht funktioniert, weil die Subviews drüber gezeichnet wurden.

    Ich habe jetzt eine Lösung gefunden: Ich überschreibe layoutSubviews und verkleinere darin den Subview, dass er Platz für den Schatten lässt. Der super-Aufruf in drawRect ist der Funktion zum Schattenzeichnen schnurz. Deswegen zeichne ich ein Rechteck in der Farbe des Views.

    Das Ganze sieht dann so aus:

    Quellcode

    1. - (CGRect)innerFrame {
    2. CGRect theInnerFrame;
    3. CGRect theFrame = self.frame;
    4. if(offset.width < 0) {
    5. theInnerFrame.origin.x = theFrame.origin.x;
    6. theInnerFrame.size.width = theFrame.size.width + offset.width;
    7. }
    8. else {
    9. theInnerFrame.origin.x = theFrame.origin.x + offset.width;
    10. theInnerFrame.size.width = theFrame.size.width - offset.width;
    11. }
    12. if(offset.height < 0) {
    13. theInnerFrame.origin.y = theFrame.origin.y;
    14. theInnerFrame.size.height = theFrame.size.height + offset.height;
    15. }
    16. else {
    17. theInnerFrame.origin.y = theFrame.origin.y + offset.height;
    18. theInnerFrame.size.height = theFrame.size.height - offset.height;
    19. }
    20. return theInnerFrame;
    21. }
    22. - (void)drawRect:(CGRect)inRect {
    23. CGContextRef theContext = UIGraphicsGetCurrentContext();
    24. CGContextSaveGState(theContext);
    25. CGContextSetShadowWithColor(theContext, offset, blur, [UIColor blackColor].CGColor);
    26. CGContextSetFillColorWithColor(theContext, self.backgroundColor.CGColor);
    27. CGContextFillRect(theContext, [self innerFrame]);
    28. CGContextRestoreGState(theContext);
    29. [super drawRect:inRect];
    30. }
    31. -(void)layoutSubviews {
    32. [super layoutSubviews];
    33. UIView *theView = [self.subviews objectAtIndex:0];
    34. CGRect theFrame = [self innerFrame];
    35. theView.frame = theFrame;
    36. }
    Alles anzeigen
    „Meine Komplikation hatte eine Komplikation.“
  • Original von gritsch
    naja, das ist schon sehr kompliziert gemacht!

    schau dir mal NSInsetRect(...) an ;)

    Hab' ich mir schon fast gedacht, dass es einfacher geht. NSInsetRect gibt's aber leider nicht auf dem iPhone. Ich berechne auch keinen Innenrahmen sondern eine Verschiebung einer horizontalen und einer vertikalen Seite.

    Original von gritsch
    im draw selbst würd ich dann:

    1. abchecken ob überhaupt ein subview da ist,

    2. falls eines da ist, den frame vom subview verwenden und nicht den berechneten (den hast du dem subview ja gesetzt)

    Der Subview ist immer da, da der View nix anderes machen soll, als einen Schatten zeichnen. Die Idee des zweiten Punktes gefällt mir ;) Probier' ich mal aus.
    „Meine Komplikation hatte eine Komplikation.“
  • Jo, geht einfacher:

    Quellcode

    1. - (void)drawRect:(CGRect)inRect {
    2. UIView *theView = [self.subviews objectAtIndex:0];
    3. CGRect theFrame = theView.frame;
    4. CGContextRef theContext = UIGraphicsGetCurrentContext();
    5. CGSize theOffset;
    6. theOffset.width = theFrame.origin.x > 0 ?
    7. theFrame.origin.x : theFrame.size.width - self.frame.size.width;
    8. theOffset.height = theFrame.origin.y > 0 ?
    9. theFrame.origin.y : theFrame.size.height - self.frame.size.height;
    10. CGContextSaveGState(theContext);
    11. CGContextSetShadowWithColor(theContext, theOffset, blur, [UIColor blackColor].CGColor);
    12. CGContextSetFillColorWithColor(theContext, self.backgroundColor.CGColor);
    13. CGContextFillRect(theContext, theView.frame);
    14. CGContextRestoreGState(theContext);
    15. [super drawRect:inRect];
    16. }
    Alles anzeigen


    unde der andere Kram fliegt raus.
    „Meine Komplikation hatte eine Komplikation.“