Search code examples
macoscore-animationosx-snow-leopardmacruby

Using macruby, how do I set up a completion block for a Core Animation transaction?


I'm using MacRuby to do Core Animation programming. I've tried all I can think of and searched all over (and maybe it can't be done in 'pure' macruby) but I can't figure out how to specify a block of MacRuby code as a completion block to be called when an animation transaction is finished. I know there are other ways to do what I want but this seems to be the cleanest for me and the way things are moving in Cocoa. Anyway, this is what I've got:

CATransaction.begin  # start the transaction
#
# ...set up animation (works fine!)
#
CATransaction.setCompletionBlock(...)          <---- Here's the problem
CATransaction.commit  # end the transaction

Without the 'setCompletionBlock' line the animation runs fine. The parameter to this setter method is defined (in Objective-C) as:

void (^)(void))block

And is described as:

"a block object called when animations for this transaction group are > completed. The block object takes no parameters and returns no value."

I've tried different things (but I'm just guessing at this point):

CATransaction.setCompletionBlock({ some code })

CATransaction.setCompletionBlock(Proc.new { some code })

CATransaction.setCompletionBlock(lambda { some code })

CATransaction.setCompletionBlock(method(:aMethod))
...
def aMethod
  ...
end

Am I way off? Do I have to make an Objective-C wrapper of some sort to do it? Or can't it be done?

Thanks in advance


Solution

  • Ok, after quite a roundabout trip searching through scattered MacRuby notes I found out how to do this. Of course it's one of my early attempted solutions; the trick was installing the (MacRuby) BridgeSupport Preview which is separate from the MacRuby install and was something I hadn't known about nor needed until now. Getting that put down here will hopefully save someone the aggravation of searching for an answer that isn't obviously connected to the problem. Here's a "complete" listing of my original example (above) with the missing piece added:

    CATransaction.begin  # start the transaction
    #
    # ...set up animation (works fine!)
    #
    CATransaction.setCompletionBlock( Proc.new { puts "I'm done!" })      <-------
    CATransaction.commit  # end the transaction
    

    where the 'puts' statement can be replaced with desired code to be carried out on the completion of the animation.

    The more general answer for specifying a block to a Cocoa method is to use:

    Proc.new { ...code block... }

    in the method invocation (as above). Arguments can also be supplied, if they are specified in the method documentation, by using the normal ruby block definition syntax.

    The MacRuby BridgeSupport Preview can be downloaded from here (as can the MacRuby current and nightly releases).