Reputation: 5547
I'm trying to convert the following C# code into F#:
UIView.Animate (2, 0, UIViewAnimationOptions.CurveEaseInOut,
() => {
imageView.Center =
new CGPoint (UIScreen.MainScreen.Bounds.Right - imageView.Frame.Width / 2, imageView.Center.Y);},
() => {
imageView.Center = pt; }
);
It calls UIView.Animate
and passes the duration, delay, animation options, and lambda expressions for the animation code and animation completion code.
I know that lambda expressions in F# use the fun
syntax. This is my attempt:
UIView.Animate(0,UIViewAnimationOptions.CurveEaseOut, fun ->
{
//first code section
},
fun ->
{
//second code section
}
)
but I don't think I'm doing this right as it throws a syntax error unexpected symbol -> in lambda expression
.
EDIT:
This is my code snippet, its a animation nested within another animation. The error I'm getting is The method or object Animate does not take 4 arguments, a method or overload was found taking two arguments
. I tried removing the commas between the fun
blocks, however then it complains about indentation.
UIView.Animate(0,UIViewAnimationOptions.CurveEaseOut, (fun () ->
x.View.LayoutIfNeeded()),
fun () -> (
let height : nfloat = Conversions.nfloat(220)
let animationDuration = (userInfo.[UIKeyboard.AnimationDurationUserInfoKey] :?> NSNumber).FloatValue
let animationOptions = (userInfo.[UIKeyboard.AnimationCurveUserInfoKey] :?> NSNumber).UintValue
let window = UIApplication.SharedApplication.KeyWindow
if window <> null then
if isKeyboardShowing then
Console.WriteLine("Completed")
let y = window.Frame.Height
UIView.Animate(new TimeInterval(animationDuration),UIViewAnimationOptions(animationOptions), fun () ->
bottomView.Frame <- CGRect(0,y,bottomView.Frame.Width,bottomView.Frame.Height)
fun () ->
Console.WriteLine("Completed")
)
))
Upvotes: 1
Views: 678
Reputation: 16194
You're just missing the argument part of your lambda:
fun () -> <function body goes here>
It looks like in your case you need a function that takes no args, so we just put ()
for unit
.
...Animate(0, UIViewAnimationOptions.CurveEaseOut, (fun () -> do something), (fun () -> do something))
Update It's hard to say because I can't reproduce your environment, but I've tried to reformat your code sample with my best guess:
UIView.Animate(
0,
0, // you might be missing an argument here?
UIViewAnimationOptions.CurveEaseOut,
(fun () -> x.View.LayoutIfNeeded()),
(fun () ->
let height : nfloat = Conversions.nfloat(220)
let animationDuration = (userInfo.[UIKeyboard.AnimationDurationUserInfoKey] :?> NSNumber).FloatValue
let animationOptions = (userInfo.[UIKeyboard.AnimationCurveUserInfoKey] :?> NSNumber).UintValue
let window = UIApplication.SharedApplication.KeyWindow
if window <> null and isKeyboardShowing then
Console.WriteLine("Completed")
let y = window.Frame.Height
UIView.Animate(
new TimeInterval(animationDuration),
UIViewAnimationOptions(animationOptions),
(fun () -> bottomView.Frame <- CGRect(0, y, bottomView.Frame.Width, bottomView.Frame.Height)),
(fun () -> Console.WriteLine("Completed")))))
This piece of code is growing unwieldy, so I'd recommend defining separate functions for the callbacks which should make it easier to read/format. Also, there really doesn't appear to be a 4-argument version of UIView.Animate
according to Xamarin docs. You might be missing a duration
or delay
argument?
Upvotes: 2
Reputation: 80734
Regarding the comma problem:
In F# syntax, the comma does not indicate the end of a lambda expression, so the following expression:
fun x -> a, fun y -> b
would be parsed as:
fun x -> (a, fun y -> b)
that is, it would be understood not as two lambdas separated by a comma, but as a single lambda that returns a tuple.
To make it two lambdas, use parentheses:
(fun x -> a), (fun y -> b)
Upvotes: 3