"Overlay" o.ä. soll durchsicht auf Bild dahinter bieten

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Mir ist Dein Vorgehen nicht ganz klar. Grundsätzlich solltest Du zwischen der Darstellung des Bildes und der Blende trennen. Noch einmal die unterschiedlichen Lösungswege:
    1. Du legst die Blende auf das Bild. Dann zeichnest Du den Rahmen und lässt das Innere transparent.
    2. Du legst das Bild vor einen Hintergrund in der Farbe der Blende. Da maskierst Du den verdeckten Bereich durch eine Maske aus. Für die Maske verwendest Du einen Layer den Du an theImageView.layer.mask zuweist. Für dieses Vorgehen brauchst Du nur eine Klasse für den Layer. Die Views sind Standardviews. Für die Animation kannst Du dann CoreAnimation verwenden.
    „Meine Komplikation hatte eine Komplikation.“
  • Ok. mein imageview hat wieder die standardklasse.

    Wie muss die Klasse für solch einen Layer aussehen? Dynamische Properties für x, y, usw. der Mask, oder? Und welche Methode muss ich dann zum einstellen von x,y, usw. nutzen?
    Hast du evtl. n Link wo eine Layerklasse für eine Maske beschrieben ist? In dem onlinebuch ist das für mich nicht ganz klar beschrieben...
  • Ich glaube wir reden aneinander vorbei. Oder ich checks einfach nicht. Den Link hab ich gelesen ja. Die 1. Antwort dort zeigt mir wie animiert wird.

    Es soll wie ein Schlüsselloch sein, das sich vergrößert. Nur rund.

    Hab jetzt ein neues Projekt aufgemacht um von Anfang an mein problem sauber aufzubauen.

    imageview hat bild.
    imageview bekommt maske mit

    Quellcode

    1. theImage.layer.mask = [self maskWithRect:theImage.layer.bounds];


    Quellcode

    1. - (CALayer *)maskWithRect:(CGRect)inRect {
    2. int radius = 50;
    3. int centerX = inRect.origin.x;
    4. int centerY = inRect.origin.y;
    5. CGMutablePathRef thePath = CGPathCreateMutable();
    6. CAShapeLayer *theMask = [CAShapeLayer layer];
    7. theMask.frame = inRect;
    8. theMask.fillColor = [UIColor blackColor].CGColor;
    9. //CGPathAddEllipseInRect(thePath, NULL, inRect);
    10. CGPathAddEllipseInRect(thePath, NULL,
    11. CGRectMake(centerX , centerY, 2*radius, 2*radius));
    12. theMask.path = thePath;
    13. CGPathRelease(thePath);
    14. return theMask;
    15. }
    Alles anzeigen


    Animation dann mit

    Quellcode

    1. NSTimeInterval duration = 5.5;// match this to the value of the UIView animateWithDuration: call
    2. [CATransaction begin];
    3. [CATransaction setValue:[NSNumber numberWithFloat:duration] forKey:kCATransactionAnimationDuration];
    4. self.theImage.layer.mask.position = CGPointMake(260, 260);
    5. self.theImage.layer.mask.bounds = CGRectMake(0, 0, 200, 200);
    6. [CATransaction commit];


    So gehts nicht. Er animiert nicht. Ist klar.

    Wenn ich jetzt ne eigene Layerklasse schreib, muss dann die Animation irgendwo in dieser Klasse rein? Und ich setz im Viewcontroller einfach bounds der maske?

    Ich frage mich ob ich der 1. bin mit dem Problem. Irgendwo muss es doch n Beispielprojekt geben...:)
  • Naja, da sind ein paar Kniffe notwendig. Vom Prinzip her klappt's aber. Da sich die Größe des Kreises mit den Bounds ändert, muss auch needsDisplayForKey: entsprechend angepasst werden. Das ist die ganze Layer-Implementierung:

    Quellcode

    1. ​@implementation CircleLayer
    2. + (BOOL)needsDisplayForKey:(NSString *)inKey {
    3. return [inKey isEqualToString:@"bounds"] || [inKey isEqualToString:@"position"] || [super needsDisplayForKey:inKey];
    4. }
    5. - (void)drawInContext:(CGContextRef)inContext {
    6. CGContextSetFillColorWithColor(inContext, [UIColor blackColor].CGColor);
    7. CGContextFillEllipseInRect(inContext, self.bounds);
    8. }
    9. @end
    Alles anzeigen

    So fügst Du den (geschlossenen) Layer hinzu:

    Quellcode

    1. UIView *theView = self.imageView;
    2. CGRect theBounds = theView.bounds;
    3. CGPoint theCenter = CGPointMake(CGRectGetMidX(theBounds), CGRectGetMidY(theBounds));
    4. CALayer *theLayer = [CircleLayer layer];
    5. theView.layer.mask = theLayer;
    6. theLayer.bounds = CGRectZero;
    7. theLayer.position = theCenter;


    und so öffnest Du ihn:

    Quellcode

    1. UIView *theView = self.imageView;
    2. CALayer *theLayer = theView.layer.mask;
    3. [CATransaction begin];
    4. [CATransaction setAnimationDuration:5.0];
    5. theLayer.bounds = theView.bounds;
    6. [CATransaction commit];
    „Meine Komplikation hatte eine Komplikation.“
  • Danke das sieht gut aus. Er macht auch alles, nur leider nicht animiert? (Muss man bounds im Layer nicht als dynamische property definieren? <- hab ich auch schon probiert)

    In meinem ViewController ist diese Methode zum Starten:

    Quellcode

    1. - (IBAction)startClicked:(id)sender {
    2. UIView *theView = self.theImage;
    3. CGRect theBounds = theView.bounds;
    4. CGPoint theCenter = CGPointMake(CGRectGetMidX(theBounds), CGRectGetMidY(theBounds));
    5. CALayer *theLayer = [CircleMaskLayer layer];
    6. theView.layer.mask = theLayer;
    7. theLayer.bounds = CGRectZero;
    8. theLayer.position = theCenter;
    9. [CATransaction begin];
    10. [CATransaction setAnimationDuration:5.0];
    11. theLayer.bounds = theView.bounds;
    12. [CATransaction commit];
    13. }
    Alles anzeigen