Tag Archives: iOS

Ze Flippable View in Xamarin.Forms with Native Animations…

Let’s blend some Native Animation goodness to our Flippin’ Flipity Flippable View in Xamarin.Forms…

So I hop yol’ remember my previous post, It’s a Flippin’ Flipity Flippable View in Xamarin.Forms! where I showcased my awesome control built right from Xamarin.Forms without any native code implementation. 😉

  

But you may have noticed a slight issue in the Flip Animation, specially on Android and iOS as well (slightly though), where Flip animation moves the View out of it’s bounds.

^As you can see above, in the animation screenshots… 😮

Some improvement needed…

If you look closely, during the flip rotation, the View sort of scales up itself and moves out of the bounds of itself and scales back and revert back to the normal bounds.

This was kind of annoying me from a personal perspective, so that’s why I thought of finding a solution by trying to render the whole animation natively for Android and iOS separately. 😀

Behold ze Native Animation…

So basically the whole logic of the FlipViewControl is going to be the same, only the animation part would be executed natively. Let’s discuss how we could implement a native animation for each Android and iOS below. 😀

As of Android…

As of Android, the reason why the View scales out of bounds during the flip animation is because that is the default behavior of Flip Animation in Android. Since Xamarin.Forms Aniamtions binds to the native default behavior you could definitely expect it to behave that way. There’s an aspect called Camera View distance perspective for any given view, by default during any animation the Camera View aspect doesn’t change, thus causing the overblown effect of the Flip Animation.

So by implementing a native animation what we could achieve is to control the Camera View Distance value for each animation frame manually, also something to keep in mind this needs to be done according to the Screen density. I found this solution thanks to this forum post:  https://forums.xamarin.com/discussion/49978/changing-default-perspective-after-rotation

As of iOS…

Here for the iOS its not much of an issue, but you do see a bit of the View scaling out of the boundary. So let’s dive into the iOS native flip animation.

We’ll be using a CATransform3D to maintain the transformation of the View’s Layer and execute the animation using UIView.Animate(), we will be using two CATransform3D objects to make sure the View doesn’t scale beyond the boundaries during the animation. This whole awesome solution I found via a random snippet search https://gist.github.com/aloisdeniel/3c8b82ca4babb1d79b29

Time for some coding…

Let’s get started off with the subclassed custom control, naming it XNFlipView and the implementation is actually same as our previous XFFlipView control implementation, but the only difference is there’s no Xamarin.Forms Animation implementation, or handling of the IsFlipped property in the PCL code, since it will be handled in the Renderer level.

public class XNFlipView : ContentView
{
	public XNFlipView()
	{
		...
	}

	public static readonly BindableProperty FrontViewProperty
	...

	public static readonly BindableProperty BackViewProperty
	...
	
	// Everything else is same as XFFlipView implementation

	public static readonly BindableProperty IsFlippedProperty =
	BindableProperty.Create(
		nameof(IsFlipped),
		typeof(bool),
		typeof(XNFlipView),
		false,
		BindingMode.Default,
		null);

	/// <summary>
	/// Gets or Sets whether the view is already flipped
	/// ex : 
	/// </summary>
	public bool IsFlipped
	{
		get { return(bool)this.GetValue(IsFlippedProperty);}
		set { this.SetValue(IsFlippedProperty, value); }
	}
	
	...
}

 

You can take a look at the full class implementation in the github repo file: XFFlipViewControl/XNFlipView.cs

Native Renderers implementation…

Since the animations are going to be handled natively, we need to create the Custom Renderers for our XNFlipView for Android and iOS separately, so let’s get started…

Android Custom Renderer

Alright then let’s go ahead and create the XNFlipViewRenderer  extending from ViewRenderer, as of Xamarin.Forms 2.5 and later we have to pass the Context in the Custom Renderer’s constructor, so let’s begin with that.

public class XNFlipViewRenderer : ViewRenderer
{
	private float _cameraDistance;

	private readonly ObjectAnimator _animateYAxis0To90;
	private readonly ObjectAnimator _animateYAxis90To180;

	public XNFlipViewRenderer(Context context) : base(context)
	{
		...
		//Animation Initialization
		...
	}

	protected override void 
		OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.View> e)
	{
		base.OnElementChanged(e);

		if (((XNFlipView)e.NewElement) != null)
		{
			// Calculating Camera Distance 
                        //to be used at Animation Runtime
			// https://forums.xamarin.com/discussion/49978/changing-default-perspective-after-rotation
			var distance = 8000;
			_cameraDistance = Context.Resources.DisplayMetrics.Density * distance;
		}
	}

	protected override void 
		OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
	{
		base.OnElementPropertyChanged(sender, e);

		if (e.PropertyName == XNFlipView.IsFlippedProperty.PropertyName)
		{
			if (!((XNFlipView)sender).IsFlipped)
			{
				this.RotationY = 0;
			}

			AnimateFlipHorizontally();
		}
	}

	private void AnimateFlipHorizontally()
	{
		SetCameraDistance(_cameraDistance);

		_animateYAxis0To90.Start();
	}
}

 

Now as you can see above in the constructor we’re initializing the ObjectAnimator objects _animateYAxis0To90 and _animateYAxis90To180 which will be executing the native Flip Animation.

Then in the Renderer’s OnElementChanged we’re calculating the Camera distance value to be used during the Animations execution as we explained before in the concept.

Also you can see how we’re listening to the XNFlipView.IsFlipped value change and executing Animations.

Next let’s take a look into the Animation execution implementation which goes inside the Constructor as you can see in the previous code snippet…

// Initiating the first half of the animation
_animateYAxis0To90 = ObjectAnimator.OfFloat(this, "RotationY", 0.0f, -90f);
_animateYAxis0To90.SetDuration(500);
_animateYAxis0To90.Update += (sender, args) =>
{
	// On every animation Frame we have to update the Camera Distance since Xamarin overrides it somewhere
	SetCameraDistance(_cameraDistance);
};
_animateYAxis0To90.AnimationEnd += (sender, args) =>
{
	if (((XNFlipView)Element).IsFlipped)
	{
		// Change the visible content
		((XNFlipView)Element).FrontView.IsVisible = false;
		((XNFlipView)Element).BackView.IsVisible = true;
	}
	else
	{
		// Change the visible content
		((XNFlipView)Element).BackView.IsVisible = false;
		((XNFlipView)Element).FrontView.IsVisible = true;
	}

	this.RotationY = -270;

	_animateYAxis90To180.Start();
};

// Initiating the second half of the animation
_animateYAxis90To180 = ObjectAnimator.OfFloat(this, "RotationY", -270f, -360f);
_animateYAxis90To180.SetDuration(500);
_animateYAxis90To180.Update += (sender1, args1) =>
{
	// On every animation Frame we have to update the Camera Distance since Xamarin overrides it somewhere
	SetCameraDistance(_cameraDistance);
};

 

As you can see we’re instantiating the animation objects accordingly to the degree angle of the Y Axis they’re suppose to animate the view. Also something very important is that in each animation frame we’re also updating the Camera View Distance, as we discussed earlier this to prevent the View from scaling beyond it’s boundaries. That SetCameraDistance() call takes of it with the previous calculated value. 😉

You can also change the speed of the animation by changing the SetDuration() parameters, which currently I’ve set to 1 second.

You could take a look at the full implementation of the android custom renderer in the github file: XFFlipViewControl.Android/XNFlipViewRenderer.cs

iOS Custom Renderer

Alright then let’s move to the iOS Custom Renderer…

public class XNFlipViewRenderer : ViewRenderer

   protected override void
       OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
   {
       base.OnElementPropertyChanged(sender, e);

       if (e.PropertyName == XNFlipView.IsFlippedProperty.PropertyName)
       {
           if (((XNFlipView)sender).IsFlipped)
           {
             AnimateFlipHorizontally(NativeView, false, 0.5, () =>
             {
                 // Change the visible content
                 ((XNFlipView)sender).FrontView.IsVisible = false;
                 ((XNFlipView)sender).BackView.IsVisible = true;

                 AnimateFlipHorizontally
                           (NativeView, true, 0.5, null);
             });
           }
           else
           {
             AnimateFlipHorizontally(NativeView, false, 0.5, () =>
             {
                 // Change the visible content
                 ((XNFlipView)sender).FrontView.IsVisible = true;
                 ((XNFlipView)sender).BackView.IsVisible = false;

                 AnimateFlipHorizontally
                             (NativeView, true, 0.5, null);
             });
           }
       }
   }
   
   public void AnimateFlipHorizontally(...)
   {
       ...
   }

 

So here in iOS Renderer, it seems a bit straight forward as we’re simply listening to the IsFlipped property change and directly executing the animation.

Next let’s see the Animation implementation…

//https://gist.github.com/aloisdeniel/3c8b82ca4babb1d79b29
public void AnimateFlipHorizontally
	(UIView view, bool isIn, 
		double duration = 0.3, Action onFinished = null)
{
	var m34 = (nfloat)(-1 * 0.001);

	var minTransform = CATransform3D.Identity;
	minTransform.m34 = m34;
	minTransform = minTransform.
		Rotate((nfloat)((isIn ? 1 : -1) * Math.PI * 0.5),
			(nfloat)0.0f, (nfloat)1.0f, (nfloat)0.0f);
	var maxTransform = CATransform3D.Identity;
	maxTransform.m34 = m34;

	view.Layer.Transform = isIn ? minTransform : maxTransform;
	UIView.Animate(duration, 0, UIViewAnimationOptions.CurveEaseInOut,
		() => {
			view.Layer.AnchorPoint = new CGPoint((nfloat)0.5, (nfloat)0.5f);
			view.Layer.Transform = isIn ? maxTransform : minTransform;
		},
		onFinished
	);
}

 

So that’s basically the animation implementation code, which I have extracted from the given gist link at the top, which I have explained in the concept description as well.

You can change the speed of the flip animation by changing the duration.

You could take a look at the full implementation of the android custom renderer in the github file: XFFlipViewControl.iOS/XNFlipViewRenderer.cs

Try it out eh! 😀

Well its use is exactly same as our previous XFFlipView Control. As of an example you could take a look here in my github file: XNFlipViewDemoPage.xaml

So now to execute the awesome Flip Animation, simply change the value of the IsFlipped as follows.

XNFlipViewControl1.IsFlipped = !XNFlipViewControl1.IsFlipped;

 

As you can see in code behind, we’re changing the value of the control’s IsFlipped property, Simples eh! 😀 This is fully bindable as well, so you can directly bind this to a ViewModel property as well.

...
<xfFlipViewControl:XNFlipView 
     x:Name="XNFlipViewControl1" 
          IsFlipped="{Binding IsViewFlipped}">
...

</xfFlipViewControl:XNFlipView>

 

So you can directly use this in your beautifully crafted MVVM Xamarin.Forms app as well. 😀

Some Live Action…

Here we go baby! iOS and Android running side by side…

 

 

Woot!

Look at that the Flip Animation maintains the Bounds of the View nicely during the animation in both Android and iOS! 😉

This whole awesome project i hosted up in my Github repo : https://github.com/UdaraAlwis/XFFlipViewControl 

Cheers! 😀 Keep on going my fellow devs!

Spread the love…

It’s a Flippin’ Flipity Flippable View in Xamarin.Forms!

Something that Flips! Flipity Flippy Flippin’ Flip View right out of Xamarin.Forms yol! 😀

Sometime back while I was trying to push the limits of Xamarin.Forms Views, I came across this requirement of Flipping a View with a cool animation. So let me share the story of it right here as usual…

I wanted to create a control that would have a Front View and a Back View, whilst being able to switch between those two Views in with a cool Flip animation!

Behold ze me effortz… 😀

 

TADAAA! 😀 How cool it is eh! 😉

And its all pure Xamarin.Forms, without a single line of native code… Say whuut! 😀 lol

So yeah let’s see how I did it.

The Golden Recipe…

So the solution here is to simply use a View which can hold two layouts (where we will be placing out child elements in) on top of each other, and rotate the View with the easy use of  Xamarin.Forms Animations, whitest swapping the two layouts on top of each other accordingly.

Ok so let me elaborate step by step.

  • Prepare a MainLayout View to hold two child Layouts (FrontView and BackView) in it
  • Add the FrontView and BackView on top of each other inside the MainLayout  View
  • Rotate the MainLayout 90 degrees using Xamarin.Forms Animations API
  • Swap the FrontView and BackView 
  • Then Rotate the MainLayout another 90 degrees
  • And Repeat the same…

That’s it!

The Golden Control…

Alright let’s start of with creating a custom control, which we shall call the golden XFFlipView which would derive from a ContentView. Then myself be using a RelativeLayout as the Parent Layout View of this control,

I’m using bindable FrontViewProperty and BackViewProperty inside the XFFlipView control to hold the reference of the two child Layout Views that we are going to be using as FrontView and BackView of this Flippin’ Flippity Flippy thing! 😀

Additionally we are going to use a bindable boolean, IsFlippedProperty to handle the flipping of this flip view 😉

Well why all the “bindable properties” you might ask? Oh come on, why not silly! So we can monitor the changes of those properties at run time and react accordingly, such as the IsFlipped property, whereas whenever the value changes we shall be activating the Flip View animation functionality.

public class XFFlipView : ContentView
{
	private readonly RelativeLayout _contentHolder;
	
	public XFFlipView()
	{
		_contentHolder = new RelativeLayout();
		Content = _contentHolder;
	}

	public static readonly BindableProperty FrontViewProperty =
	BindableProperty.Create(...);

	public static readonly BindableProperty BackViewProperty =
	BindableProperty.Create(...);

	public static readonly BindableProperty IsFlippedProperty =
	BindableProperty.Create(...);

	private static void IsFlippedPropertyChanged(BindableObject bindable, object oldValue, object newValue)
	{
		if ((bool)newValue)
		{
			((XFFlipView)bindable).FlipFromFrontToBack();
		}
		else
		{
			((XFFlipView)bindable).FlipFromBackToFront();
		}
	}
	
	/// <summary>
	/// Performs the flip
	/// </summary>
	private async void FlipFromFrontToBack()
	{
		...
	}

	/// <summary>
	/// Performs the flip
	/// </summary>
	private async void FlipFromBackToFront()
	{
		...
	}
}

 

There you have it as we just discussed earlier. Ops I may have forgotten about those two methods at the bottom, so those are the methods we are going to use the actual Flip Animation logic, as you can see they’re are being called every time the IsFlipped property is changed.

Oh for them lazy fellas, here grab the full implementation above on my github: XFFlipView.cs

Ze Animationalization…

Alright time for the reveal of the animation thingy, which has been completely done through the easy to use Xamarin.Forms Animations API. Surprise!!?? 😛

...
private async void FlipFromFrontToBack()
{
	await FrontToBackRotate();

	// Change the visible content
	this.FrontView.IsVisible = false;
	this.BackView.IsVisible = true;

	await BackToFrontRotate();
}
...

So basically that’s the implementation of the above said mystery two methods, as you can clearly see, inside there I’m calling another method called FrontToBackRotate() which is the actual method that performs the animation. And right after that we are swapping the Visibility of the FrontView and BackView. Then continue with the rest of animation in BackToFrontRotate() call, just like how we discussed at the beginning.

Let’s see the actual animation implementation, shall we…

#region Animation Stuff

private async Task<bool> FrontToBackRotate()
{
	ViewExtensions.CancelAnimations(this);

	this.RotationY = 360;

	await this.RotateYTo(270, 500, Easing.Linear);

	return true;
}

private async Task<bool> BackToFrontRotate()
{
	ViewExtensions.CancelAnimations(this);

	this.RotationY = 90;

	await this.RotateYTo(0, 500, Easing.Linear);

	return true;
}

#endregion

 

Oh look at that simplicity eh! Thank you Xamarin.Forms animation! 😀 lol

So what happen over there is first we cancel any pending animation and the do initial Y axis rotate property of the parent View and then actually call on the RotateYTo() of Xamarin.Forms Animations, causing it the parent Layout to rotate around the Y Axis with the given value of degrees.

Then when the parent View is flipping from Back To Front View, the same process’s opposite will be executed. 😀 Simples!

Try it out eh! 😀

Since its full on Xamarin.Forms without a single line of native Xamarin code, you could straightaway use this in your XAML or C# code behind anywhere in your PCL.

<xfFlipViewControl:XFFlipView 
        x:Name="XFFlipViewControl1">

    <xfFlipViewControl:XFFlipView.FrontView>
        <Frame
            Margin="10"
            Padding="0"
            BackgroundColor="#0080ff"
            CornerRadius="10"
            HasShadow="True">
            <Grid>
                <Label
                 Grid.Row="0"
                 FontAttributes="Bold"
                 FontSize="Large"
                 HorizontalTextAlignment="Center"
                 Text="this is front view"
                 TextColor="White"
                 VerticalTextAlignment="Center" />
            </Grid>
        </Frame>
    </xfFlipViewControl:XFFlipView.FrontView>

    <xfFlipViewControl:XFFlipView.BackView>
        <Frame
            Margin="10"
            Padding="0"
            BackgroundColor="#ff0080"
            CornerRadius="10"
            HasShadow="True">
            <Grid>
                <Label
                 Grid.Row="0"
                 FontAttributes="Bold"
                 FontSize="Large"
                 HorizontalTextAlignment="Center"
                 Text="this is back view"
                 TextColor="White"
                 VerticalTextAlignment="Center" />
            </Grid>
        </Frame>
    </xfFlipViewControl:XFFlipView.BackView>

</xfFlipViewControl:XFFlipView>

 

Woot! Such simplicity! 😀 So you can see how I have directly used our awesome XFFlipView control right inside XAML and defined the Front and Back Views. Also I have used a Frame View to make it look cooler 😉 lol

So now to execute the awesome Flip Animation, simply change the value of the IsFlipped as follows.

XFFlipViewControl1.IsFlipped = !XFFlipViewControl1.IsFlipped;

 

As you can see in code behind, we’re changing the value of the control’s IsFlipped property, Simples eh! 😀 This is fully bindable as well, so you can directly bind this to a ViewModel property as well.

...
<xfFlipViewControl:XFFlipView 
     x:Name="XFFlipViewControl1" 
          IsFlipped="{Binding IsViewFlipped}">
...

</xfFlipViewControl:XFFlipView>

 

So you can directly use this in your beautifully crafted MVVM Xamarin.Forms app as well. 😀

Some Live Action…

Here we go baby! iOS and Android running side by side…

  

Oh hold on… there’s more coolness… 😀

 

Ohhh! Eye Candy! 😀

And the craziest thing about it is that, all of this awesomeness is right from Xamarin.Forms, without a single line of native Xamarin code. 😉

Woot!

This whole awesome project i hosted up in my Github repo : https://github.com/UdaraAlwis/XFFlipViewControl 

Oh BTW, you might ask me why on Android during the Animation, the view seem to be expanding out of the view? Yes its basically how the Android native flip animation executes, since Xamarin.Forms directly maps its Animation rendering calls down to native level. But we could easily tweak it up by implementing our own native renderer for the Animation, which we will be looking into in the next post. 🙂

Cheers! 😀 Keep on going my fellow devs!

Spread the love…

Let’s add a Video Stream Player to your Xamarin iOS App…

So you wanna add an Online Video Player for your Xamarin iOS app ? How hard could it be, just add a WebView and screw up the whole thing right ? 😉 lol
Stream an online video? from Youtube? Vimeo? or wherever?

Yep one day I was given a task by my boss to implement a Video Player in one of our Xamarin iOS apps, that could play an online video…

So basically our app should be able to play an online video within the application frame. Add a Video Player control to the Xamarin iOS app but it should have all the controls with in the page itself, and more specifically this Video Player should be able to play Online Video, as in should be able to stream an Online Video over the internet. :O

Solution ?

After going through the Xamarin documentation, to my surprise I found out about this control that Xamarin provides called MPMoviePlayerController, which is like a built in controller for playing Videos, but in their documentation they had shown only an example of how to play a ‘locally stored video file’. Seriously? Who would wanna store a video file locally nowadays? 😛 lol

Anyhow, with a bit of uncertainty, I implemented this control, and after a bit of a struggle, I finally got it to working! 😀

So as usual, here I am sharing my experience with you guys… Hold on tight, it’s about to get bumpy! 😉

How to implement…

So basically we need to create an instance of the MPMoviePlayerController as follows, to be able to access it from any other methods in our ViewController, so that we could control the actions of the MPMoviePlayerController.

public class BlahBlahViewController : UIViewController
{
	MPMoviePlayerController moviePlayer;

	public BlahBlahViewController()
	{

	}
}

 

Next let’s go ahead with the implementation of the MPMoviePlayerController

// first define the Online Video URL you want to play 
var urltoplay = new NSUrl("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4");
moviePlayer = new MPMoviePlayerController();
// set the URL to the Video Player
moviePlayer.ContentUrl = urltoplay;
moviePlayer.View.Frame = new CGRect(55, 170, 310f, 200f);
// Set this property True if you want the video to be auto played on page load
moviePlayer.ShouldAutoplay = false;
// If you want to keep the Video player on-ready-to-play state, then enable this
// This will keep the video content loaded from the URL, untill you play it.
moviePlayer.PrepareToPlay();
// Enable the embeded video controls of the Video Player, this has several types of Embedded controls for you to choose
moviePlayer.ControlStyle = MPMovieControlStyle.Embedded;

View.AddSubview(moviePlayer.View);

 

As you can see above, this MPMoviePlayerController a lot of flexible customization and features for us to implement. Notice that PrepareToPlay() method will set the Video Player in a ready state to play the video on click. (It’s actually a nice option).
Also keep a note that you could choose any type of ControlStyle as you like as it provides a several options for the embedded controls of the Video Player.

Keep in Mind…

When you provide the Online Video URL to the control, make sure that URL has a video file extension for it. Otherwise this will not work, hence it requires the file extension for the video to be played. This control does not support direct Youtube or Vimeo video playing with their web browser link, you need to provide the online FTP location of the video to be played. 🙂

A little Cherry on top…

Now to put some cherry on top of the basic implementation I added some extra functionality by adding few custom buttons to control the Video Player implementation.

var playButton = UIButton.FromType(UIButtonType.RoundedRect);
playButton.Frame = new CGRect(10, 380, View.Bounds.Width - 20, 44);
playButton.SetTitle("Play Video", UIControlState.Normal);
playButton.BackgroundColor = UIColor.White;
playButton.AutoresizingMask = UIViewAutoresizing.FlexibleWidth;
playButton.TouchUpInside += delegate
{
	moviePlayer.Play();
};
View.AddSubview(playButton);

var playFullScreenButton = UIButton.FromType(UIButtonType.RoundedRect);
playFullScreenButton.Frame = new CGRect(10, 420, View.Bounds.Width - 20, 44);
playFullScreenButton.SetTitle("Play Full Screen Video", UIControlState.Normal);
playFullScreenButton.BackgroundColor = UIColor.White;
playFullScreenButton.AutoresizingMask = UIViewAutoresizing.FlexibleWidth;
playFullScreenButton.TouchUpInside += delegate
{
	moviePlayer.Play();
	// To play full screen
	moviePlayer.SetFullscreen(true, true);
};
View.AddSubview(playFullScreenButton);

var stopButton = UIButton.FromType(UIButtonType.RoundedRect);
stopButton.Frame = new CGRect(10, 460, View.Bounds.Width - 20, 44);
stopButton.SetTitle("Stop Video", UIControlState.Normal);
stopButton.BackgroundColor = UIColor.White;
stopButton.AutoresizingMask = UIViewAutoresizing.FlexibleWidth;
stopButton.TouchUpInside += delegate
{
	moviePlayer.Stop();
};
View.AddSubview(stopButton);

var pauseButton = UIButton.FromType(UIButtonType.RoundedRect);
pauseButton.Frame = new CGRect(10, 500, View.Bounds.Width - 20, 44);
pauseButton.SetTitle("Pause Video", UIControlState.Normal);
pauseButton.BackgroundColor = UIColor.White;
pauseButton.AutoresizingMask = UIViewAutoresizing.FlexibleWidth;
pauseButton.TouchUpInside += delegate
{
	moviePlayer.Pause();
};
View.AddSubview(pauseButton);

 

There you have it, a four button implementation for controlling the Video playing of MPMoviePlayerController.

As you may have noticed in the ‘Play Full Screen Video’ button action, I have called the method moviePlayer.SetFullscreen(true, true); which allows us to play the video in full screen mode. Once the click even fires, the Video controller will nicely stretch itself to the fullscreen of the app and play the video.

Alright, now let’s see how this actually looks after the implementation.

Here’s how it’ll look like… 😀

hustle hustle (1)

there you everyone, now go crazy with it. 😉

Here’s something extra…

Did you know you could detect the state changes in the MPMoviePlayerController and control its behavior ? Yes MPMoviePlayerController has a set of Observable notification methods that we could register and use for our own needs as follows.

// Register yourself for the observable notifcations
MPMoviePlayerController.Notifications.ObservePlaybackStateDidChange(MediaPLayer_OnPlaybackStateDidChange);
MPMoviePlayerController.Notifications.ObservePlaybackDidFinish(MediaPLayer_OnPlaybackComplete);

.....

// And do whatever you want based on the events

// For and example here I'm automatically setting the player to the full screen  when it starts Playing
private void MediaPLayer_OnPlaybackStateDidChange(object sender, NSNotificationEventArgs e)
{
	if (moviePlayer.PlaybackState == MPMoviePlaybackState.Playing)
	{
		moviePlayer.SetFullscreen(true, true);
	}
}

// Another example, automatically exiting the full screen when the Play back completes
private void MediaPLayer_OnPlaybackComplete(object sender, MPMoviePlayerFinishedEventArgs e)
{
	moviePlayer.SetFullscreen(false, true);
	moviePlayer.View.Hidden = true;
}

 

Yep there you go another set of awesome features we could play around in MPMoviePlayerController.

Parallels Picture

There’s a whole set of Observable events you could register yourself to based on your requirements and to play around with! 😉

Cheers!

Stay awesome! 😀