swift - iOS Animate Mask Over UIImage -


i using swift 1.2 , goal animate image mask on static uiimage. have implemented swift version of masking image found in objective-c.

func maskimage(image: uiimage, mask: uiimage) -> uiimage! {      let maskref = mask.cgimage;      let mask = cgimagemaskcreate(         cgimagegetwidth(maskref),         cgimagegetheight(maskref),         cgimagegetbitspercomponent(maskref),         cgimagegetbitsperpixel(maskref),         cgimagegetbytesperrow(maskref),         cgimagegetdataprovider(maskref), nil, false);      let masked = cgimagecreatewithmask(image.cgimage, mask);     let retimage = uiimage(cgimage: masked);     return retimage; } 

it works great! however, putting in motion challenge.

is there way either iteratively apply mask different horizontal offset or better way approach problem entirely - perhaps calayer implementation?

thanks help!

edit: based on posted answer, added this:

    let image = uiimage(named: "clouds");      let imageview = uiimageview(image: image);     let layer = calayer();     layer.contents = uiimage(named: "alpha-mask")?.cgimage;     layer.bounds = cgrectmake(0, 0, image.size.width, image.size.height);      // other folks learning, did not work     //let animation = cabasicanimation(keypath: "bounds.origin.x");      // work     let animation = cabasicanimation(keypath: "position.x");      animation.duration = 2;     animation.delegate = self;     animation.fillmode = kcafillmodeforwards;     animation.repeatcount = 0;     animation.fromvalue = 0.0;     animation.tovalue = image.size.width;     animation.timingfunction = camediatimingfunction(name: kcamediatimingfunctionlinear);     animation.removedoncompletion = false;      layer.addanimation(animation, forkey: "transform");      imageview.layer.mask = layer;      self.addsubview(imageview); 

i able see alpha mask properly, animation not work. ideas?

edit: modified code above , works! needed make keypath position.x. see above

you indeed want use calayer - or rather, cashapelayer.

you can create cashapelayer , install as mask on layer.

you can create caanimation animates changes shape layer's path, or can animate changes layer's strokestart and/or strokeend properties.

if animate path, 1 rule want follow make sure starting , ending path have same number , type of control points. otherwise animation "undefined", , results can strange.

i have development blog post outlines how it's done:

http://wareto.com/using-core-animation-groups-to-create-animation-sequences-2

it's using caanimationgroups, includes working example of animating changes cashapelayer that's used mask of image view's layer.

below gif of mask animation creates - "clock wipe" shows , hides image view:

enter image description here

unfortunately it's written in objective-c, core animation calls identical in swift. let me know if have problems figuring out how adapt it.

the meat of animation code method:

- (ibaction)domaskanimation:(id)sender; {    waretologolarge.hidden = false;//show image view    //create shape layer use mask waretologolarge image view   cashapelayer *masklayer = [cashapelayer layer];    cgfloat maskheight = waretologolarge.layer.bounds.size.height;   cgfloat maskwidth = waretologolarge.layer.bounds.size.width;    cgpoint centerpoint;   centerpoint = cgpointmake( maskwidth/2, maskheight/2);    //make radius of our arc large enough reach corners of image view.   cgfloat radius = sqrtf(maskwidth * maskwidth + maskheight * maskheight)/2;    //don't fill path, stroke in black.   masklayer.fillcolor = [[uicolor clearcolor] cgcolor];   masklayer.strokecolor = [[uicolor blackcolor] cgcolor];    masklayer.linewidth = radius; //make line thick enough fill circle we're drawing    cgmutablepathref arcpath = cgpathcreatemutable();    //move starting point of arc there no initial line connecting arc   cgpathmovetopoint(arcpath, nil, centerpoint.x, centerpoint.y-radius/2);    //create arc @ 1/2 our circle radius, line thickess of full circle radius   cgpathaddarc(arcpath,                nil,                centerpoint.x,                centerpoint.y,                radius/2,                3*m_pi/2,                -m_pi/2,                yes);    masklayer.path = arcpath;    //start empty mask path (draw 0% of arc)   masklayer.strokeend = 0.0;    cfrelease(arcpath);    //install mask layer out image view's layer.   waretologolarge.layer.mask = masklayer;    //set our mask layer's frame parent layer's bounds.   waretologolarge.layer.mask.frame = waretologolarge.layer.bounds;    //create animation increases stroke length 1, reverses zero.   cabasicanimation *swipe = [cabasicanimation animationwithkeypath:@"strokeend"];   swipe.duration = 2;   swipe.delegate = self;   [swipe setvalue: theblock forkey: kanimationcompletionblock];    swipe.timingfunction = [camediatimingfunction      functionwithname:kcamediatimingfunctionlinear];   swipe.fillmode = kcafillmodeforwards;   swipe.removedoncompletion = no;   swipe.autoreverses = yes;    swipe.tovalue = [nsnumber numberwithfloat: 1.0];    [masklayer addanimation: swipe forkey: @"strokeend"]; } 

i have blog entry is in swift shows how create , animate pie chart using cashapelayer. project animates shape, not mask, real difference whether install shape layer regular content layer or mask on layer backing layer of image view.

you can check out project @ link:

http://wareto.com/swift-piecharts


Comments

Popular posts from this blog

jquery - How do you format the date used in the popover widget title of FullCalendar? -

asp.net mvc - SSO between MVCForum and Umbraco7 -

Python Tkinter keyboard using bind -