Category Archives: iOS

An improved ScrollView control for Xamarin Forms by me, myself and I…

Alright now when it comes to the default Xamarin Forms ScrollView, its pretty much generic and limited with the simple common attributes and behaviours, and it does not deliver any specific “cool” features with it.

What’s so cool about it?

So I thought of creating my own Custom ScrollView for Xamarin Forms using Custom Renderers, which would include the following awesome features,

Bouncy Effect – Yeah you gotta admit, the bounce effect of a native scrollview is pretty fun to play with, in a User’s perspective. So I thought of enabling this feature in my custom ScrollView even when the Child Element doesn’t exceeds the ScrollView boundaries… 😉
(PS: this effect is interpreted in native Android and iOS differently)

Disabling and Enabling Horizontal and Vertical Scroll Indicators – Now sometimes these scroll bar indicators are useful but there are times which we want to hide them, as it might look ugly on the UI in certain cases. So yeah let’s have some control over it shall we? 😀

Background Image – Of course who wouldn’t like a background Image on a Scroll view eh! 😉 Well to be specific we are going to add a Fixed Background Image for the ScrollView. And note that this background Image would be fixed, and will not be scrolling with the Content of the ScrollView. (I will do another post to enable that feature).

Yes behold, me, myself and I presenting the “BloopyScrollView” why the name “BloopyScrollView”? I don’t even know. lol 😛

Implementation

Alright let’s go ahead and create our Custom ScrollView Control in the PCL project. Along with the following properties, so that we could have direct control over the above said behaviours.

Alright now expect this to be longer, since I have added the properties as Bindable Properties, so you could use them in any MVVM scenario with ease. 😀

namespace WhateverYourNamespace
{
    public class BloopyScrollView : ScrollView
    {
        public static readonly BindableProperty IsHorizontalScrollbarEnabledProperty =
        BindableProperty.Create(
            nameof(IsHorizontalScrollbarEnabled),
            typeof(bool),
            typeof(BloopyScrollView),
            false,
            BindingMode.Default,
            null);
        /// <summary>
        /// Gets or sets the Horizontal scrollbar visibility
        /// </summary>
        public bool IsHorizontalScrollbarEnabled
        {
            get { return (bool)GetValue(IsHorizontalScrollbarEnabledProperty); }
            set { SetValue(IsHorizontalScrollbarEnabledProperty, value); }
        }


        public static readonly BindableProperty IsVerticalScrollbarEnabledProperty =
        BindableProperty.Create(
            nameof(IsVerticalScrollbarEnabled),
            typeof(bool),
            typeof(BloopyScrollView),
            false,
            BindingMode.Default,
            null);
        /// <summary>
        /// Gets or sets the Vertical scrollbar visibility
        /// </summary>
        public bool IsVerticalScrollbarEnabled
        {
            get { return (bool)GetValue(IsVerticalScrollbarEnabledProperty); }
            set { SetValue(IsVerticalScrollbarEnabledProperty, value); }
        }


        public static readonly BindableProperty IsNativeBouncyEffectEnabledProperty =
        BindableProperty.Create(
            nameof(IsNativeBouncyEffectEnabled),
            typeof(bool),
            typeof(BloopyScrollView),
            true,
            BindingMode.Default,
            null);
        /// <summary>
        /// Gets or sets the Native Bouncy effect status
        /// </summary>
        public bool IsNativeBouncyEffectEnabled
        {
            get { return (bool)GetValue(IsNativeBouncyEffectEnabledProperty); }
            set { SetValue(IsNativeBouncyEffectEnabledProperty, value); }
        }


        public static readonly BindableProperty BackgroundImageProperty =
        BindableProperty.Create(
            nameof(BackgroundImage),
            typeof(ImageSource),
            typeof(BloopyScrollView),
            null,
            BindingMode.Default,
            null);
        /// <summary>
        /// Gets or sets the Background Image of the ScrollView
        /// </summary>
        public ImageSource BackgroundImage
        {
            get { return (ImageSource)GetValue(BackgroundImageProperty); }
            set { SetValue(BackgroundImageProperty, value); }
        }
    }
}

 

There we go IsHorizontalScrollbarEnabled, IsVerticalScrollbarEnabled to disable/enable Horizonal and Vertical Scrollbars.

IsNativeBouncyEffectEnabled to control the Native Bouncy effect.

BackgroundImage to set the ImageSource for the ScrollView’s background Image. And make sure to provide a proper image for this hence we will be resizing the given image in our native renderer level to fit to the background of the ScrollView.(You will see in the next steps below)

Alright let’s head over to creating the Custom Renderers associated with our BloopyScrollView.

Something to keep in mind…

So if you’re a frequent reader of my blog, you may remember sometime ago I created an Extention class for handling Xamarin Forms Images in Native code level: https://theconfuzedsourcecode.wordpress.com/2016/12/12/an-awesome-image-helper-to-convert-xamarin-forms-imagesource-to-ios-uiimage-or-android-bitmap/

Why I’m bringing this up, is because we are going to be needing it for this project. You ask why? Because we need to convert the above BackgroundImage, which is of type Xamarin Forms ImageSource.

So we need to convert that ImageSource to native UIImage or Bitmap image respectively in our Custom renderer levels. 😉

So go ahead and grab that code real quick and add it to your Native Projects. 😀

iOS Implementation

Now let’s create the Custom Renderer for the Control in Xamarin.iOS project.

[assembly: ExportRenderer(typeof(BloopyScrollView), typeof(BloopyScrollViewRenderer))]
namespace WhateverYourNamespace.iOS
{
    public class BloopyScrollViewRenderer : ScrollViewRenderer
    {
        private UIImage _uiImageImageBackground;

        protected override async void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);

            this.ShowsVerticalScrollIndicator = ((BloopyScrollView)e.NewElement).IsVerticalScrollbarEnabled;
            this.ShowsHorizontalScrollIndicator = ((BloopyScrollView)e.NewElement).IsHorizontalScrollbarEnabled;

            if (e.NewElement != null)
            {
                if (((BloopyScrollView)e.NewElement).IsNativeBouncyEffectEnabled)
                {
                    this.Bounces = true;
                    this.AlwaysBounceVertical = true;
                }

                if (((BloopyScrollView)e.NewElement).BackgroundImage != null)
                {
                    // retrieving the UIImage Image from the ImageSource by converting
                    _uiImageImageBackground = await IosImageHelper.GetUIImageFromImageSourceAsync(((BloopyScrollView)e.NewElement).BackgroundImage);
                }

                ((BloopyScrollView)e.NewElement).PropertyChanged += OnPropertyChanged;
            }
        }

        private void OnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
        {
            if (propertyChangedEventArgs.PropertyName == BloopyScrollView.HeightProperty.PropertyName)
            {
                // check if the Width and Height are assigned
                if (((BloopyScrollView)sender).Width > 0 & ((BloopyScrollView)sender).Height > 0)
                {
                    // resize the UIImage to fit the current UIScrollView's width and height
                    _uiImageImageBackground = ResizeUIImage(_uiImageImageBackground, (float)((BloopyScrollView)sender).Width, (float)((BloopyScrollView)sender).Height);

                    // Set the background Image
                    this.BackgroundColor = UIColor.FromPatternImage(_uiImageImageBackground);
                }
            }
        }

        // We need to override this to have the background image to be fixed
        public override void Draw(CGRect rect)
        {
            base.Draw(rect);
        }

        // Resize the UIImage
        public UIImage ResizeUIImage(UIImage sourceImage, float widthToScale, float heightToScale)
        {
            var sourceSize = sourceImage.Size;
            var maxResizeFactor = Math.Max(widthToScale / sourceSize.Width, heightToScale / sourceSize.Height);
            if (maxResizeFactor > 1) return sourceImage;
            var width = maxResizeFactor * sourceSize.Width;
            var height = maxResizeFactor * sourceSize.Height;
            UIGraphics.BeginImageContext(new CGSize(width, height));
            sourceImage.Draw(new CGRect(0, 0, width, height));
            var resultImage = UIGraphics.GetImageFromCurrentImageContext();
            UIGraphics.EndImageContext();
            return resultImage;
        }
    }
}

 

Inside the method we are assigning the relevant properties of our BloopyScrollView to the native control properties.

The UIScrollView which is associated with the Xamarin Forms ScrollView has the following native properties:

  • ShowsVerticalScrollIndicator: Make the vertical scrollbar visible or hidden
  • ShowsHorizontalScrollIndicator: Make the horizontal scrollbar visible or hidden
  • Bounces: Always enable the native bounce effect on iOS UIScrollView
  • BackgroundColor: Allows to set the background color for the UIScrollView or set an Image as a pattern

Also you may have noted that we are converting our Image Source BackgroundImage to a UIImage using our extension.

And then when the Height and Width are set to the Control, we are resizing the Image to fit those properties and setting that as the Background of the UIScrollView through the UIColor.FromPatternImage() which allows us to set the image as a pattern throughout the canvas of the UIScrollView.

the strange tale of getting the UIScrollView’s Fixed background in Xamarin… :O

Notice that we are overriding the Draw(CGRect rect) method, this is to have the UIScroll Background Image to be fixed within the boundaries, and not to be spanned across the Content area.

Because usually if we set the BackgroundColor property, it will span across the Content area, but strangely if we override the Draw() method, BackgroundColor would only be contained within UIScrollView’s boundaries, without spanning across the Content area. This is something I figured out while playing around with the above implementation. 😀

Alright let’s jump into Android… 😀

Android Implementation

Now let’s create the Custom Renderer for the Control in Xamarin.Android project.

[assembly: ExportRenderer(typeof(BloopyScrollView), typeof(BloopyScrollViewRenderer))]
namespace WhateverYourNamespace.Droid
{
    public class BloopyScrollViewRenderer : ScrollViewRenderer
    {
        private Bitmap _bitmapImageBackground;

        protected override async void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);

            this.VerticalScrollBarEnabled = ((BloopyScrollView)e.NewElement).IsVerticalScrollbarEnabled;
            this.HorizontalScrollBarEnabled = ((BloopyScrollView)e.NewElement).IsHorizontalScrollbarEnabled;

            if (((BloopyScrollView)e.NewElement).IsNativeBouncyEffectEnabled)
            {
                this.OverScrollMode = OverScrollMode.Always;
            }

            if (((BloopyScrollView) e.NewElement).BackgroundImage != null)
            {
                // retrieving the Bitmap Image from the ImageSource by converting
                _bitmapImageBackground = await AndroidImageHelper.GetBitmapFromImageSourceAsync(((BloopyScrollView)e.NewElement).BackgroundImage, this.Context);

                // resize the Bitmap to fit the current ScrollView's width and height
                var _resizedBitmapImageBackground = new BitmapDrawable(ResizeBitmap(_bitmapImageBackground, this.Width, this.Height));

                // Set the background Image
                this.Background = _resizedBitmapImageBackground;
            }
        }

        // Resize the Bitmap
        private Bitmap ResizeBitmap(Bitmap originalImage, int widthToScae, int heightToScale)
        {
            Bitmap resizedBitmap = Bitmap.CreateBitmap(widthToScae, heightToScale, Bitmap.Config.Argb8888);

            float originalWidth = originalImage.Width;
            float originalHeight = originalImage.Height;

            Canvas canvas = new Canvas(resizedBitmap);

            float scale = this.Width / originalWidth;

            float xTranslation = 0.0f;
            float yTranslation = (this.Height - originalHeight * scale) / 2.0f;

            Matrix transformation = new Matrix();
            transformation.PostTranslate(xTranslation, yTranslation);
            transformation.PreScale(scale, scale);

            Paint paint = new Paint();
            paint.FilterBitmap = true;

            canvas.DrawBitmap(originalImage, transformation, paint);

            return resizedBitmap;
        }
    }
}

 

The Android ScrollView which is associated with the Xamarin Forms ScrollView has the following native properties:

  • VerticalScrollBarEnabled: Make the vertical scrollbar visible or hidden
  • HorizontalScrollBarEnabled: Make the horizontal scrollbar visible or hidden
  • OverScrollMode: Always enable the native bounce effect on Android ScrollView
  • Background: Allows to set the background drawable for the ScrollView

As you may have noticed we are converting our Xamarin Forms Image Source BackgroundImage to a Bitmap image using our extension.

Then we are resizing out Bitmap image according to the Width and Height of the ScrollView to fit to the full background to be wrapped around a BitmapDrawable and set to the Background of ScrollView.

There you go! 😀

Let’s use it… 😉

Alright now that’s done, let’s consume this in our PCL project.

<StackLayout Padding="10,0,10,0">

	<Label Text="Welcome to Xamarin Forms!"
		   VerticalOptions="Center"
		   HorizontalOptions="Center" />

	<local:BloopyScrollView 
	IsNativeBouncyEffectEnabled="True"
	IsVerticalScrollbarEnabled="False"
	IsHorizontalScrollbarEnabled="False">
	<local:BloopyScrollView.BackgroundImage>
	  <FileImageSource File="xamarinBackgroundImage.png"/>
	</local:BloopyScrollView.BackgroundImage>
	
			<Label
			  FontSize="22"
			  HeightRequest="400"
			  Text=
			  "Whatever your text content to be displayed." />
			  
	</local:BloopyScrollView>

</StackLayout>

 

As you can see I have inserted my BloopyScrollView in a StackLayout and as the content of the ScrollView I have added Label. Well you can add any content you want or set any Height or Width as you wish.

Notice that I have set IsNativeBouncyEffectEnabled to be True as I want to see the native Bouncy effect. Then I have disabled the Vertical and Horizontal Scrollbars from the properties we added earlier. Then finally I have added the BackgroundImage and set the FileImageSource to the ImageSource type, where as I have placed the image in the native Resource folder, as you would do with any defualt Xamarin Forms Image. 😉

Now let’s see the results… 😀

bloopscrollview-on-ios-lowq  bloopscrollview-on-android-lowq

Yaay! 😀

As we expected the Vertical and Horizontal Scrollbars are disabled and our ScrollView has full native bouncy effect accordingly.

Also you can see the Background Image nicely resized itself and fit to the background of the BloopyScrollView. 😀

Happy dance! lol

Recap Stuff…

Now there’s some stuff I wanted to recap, that is you may have noticed that when I was resizing the Image, I needed the Control’s Height and Width, and where I have acquired those properties are in two different places on each Android and iOS renderers.

To be specific I have accessed the Control’s Width and Height on Android right from the OnElementChanged method, but on iOS renderer I have accessed those values from the  OnPropertyChanged method’s Height property event. 

This is because of the differences of the Rendering cycling of Android and iOS, whereas on Android right at the firing of the Custom Renderer it assigns itself Width and Height. But on iOS we have to access them indirectly by waiting till those properties are set, by listening to the OnPropertyChanged event.

Get it on Github! 😀 XFImprovedScrollView

Cheers everyone!

Pass this on to another developer to make them smile! 😀
– Udara Alwis

An awesome Image Helper to convert Xamarin Forms ImageSource to iOS UIImage or Android Bitmap…

The default Xamarin Forms ImageSource is good, but it doesn’t provide all the properties of an Image, not as much as native Image types of Android or iOS. This is why sometimes we need to drill down to the native level of Image handling sometimes, specially when you’re dealing with Custom Renderers, or complex Image manipulation stuff in Xamarin.

So yeah it’s no surprise you will run into the need of converting the default Xamarin Forms ImageSource to native Image type in iOS and Android, respectively UIImage or Bitmap types.

Well I know I did. lol 😛

How ? 😮

So how could you do this ? Well, something intermediate for both Xamarin Forms ImageSource and the native Image types is the byte[] array. 🙂 But I’m gonna take a pass on it, since it’s too much of trouble and process, which could lead to bad memory consumption. 😦 Instead, why don’t we deal with this straight away. 😀

This is how I did it.. 😉

Now when it comes to Xamarin Forms almost everything is handled by drilling down to the native levels of the platform. Likewise ImageSource  during the runtime is handled through three types of Native Handlers that are as follows,

  • ImageLoaderSourceHandler
  • FileImageSourceHandler
  • StreamImagesourceHandler

Now for each Native environment, these handlers implements a LoadImageAsync() method, which loads the type of Native Type image for a given ImageSource.

This is usually done under the hood, but we need to access this same functionality on the go for our own requirements, so let’s do it by our own implementation.

Let’s create our Android Image Helper…

So we are going to create a Public class with static methods that could be used as extension methods in our Native Project levels. So go ahead and create the AndroidImageHelper class in your Xamarin.Android project level.

sameple

 

public class AndroidImageHelper
{
	private static IImageSourceHandler GetHandler(ImageSource source)
	{
		IImageSourceHandler returnValue = null;
		if (source is UriImageSource)
		{
			returnValue = new ImageLoaderSourceHandler();
		}
		else if (source is FileImageSource)
		{
			returnValue = new FileImageSourceHandler();
		}
		else if (source is StreamImageSource)
		{
			returnValue = new StreamImagesourceHandler();
		}
		return returnValue;
	}

	/// <summary>
	/// For converting Xamarin Forms ImageSource object to Native Image type
	/// </summary>
	/// <param name="source"></param>
	/// <param name="context"></param>
	/// <returns></returns>
	public static async Task<Bitmap> GetBitmapFromImageSourceAsync(ImageSource source, Context context)
	{
		var handler = GetHandler(source);
		var returnValue = (Bitmap)null;

		returnValue = await handler.LoadImageAsync(source, context);

		return returnValue;
	}
}

 

Alright there we go, as you would have expected we are using the native level Handlers of the ImageSource and retrieving the native image type as I explained earlier through the LoadImageAsync() method. Of course you need to pass a reference of your current Context since Android requires the context reference to almost every execution related to the UI stuff.

First we are getting the GetHandler type by the ImageSource, then we are calling the method above to retrieve the Bitmap image and returns back to the caller.

Let’s create our iOS Image Helper…

So just like on Android let’s do the same on iOS and create the public class IosImageHelper in your Xamarin Forms iOS project level.

sameple

public class IosImageHelper
{
	private static IImageSourceHandler GetHandler(ImageSource source)
	{
		IImageSourceHandler returnValue = null;
		if (source is UriImageSource)
		{
			returnValue = new ImageLoaderSourceHandler();
		}
		else if (source is FileImageSource)
		{
			returnValue = new FileImageSourceHandler();
		}
		else if (source is StreamImageSource)
		{
			returnValue = new StreamImagesourceHandler();
		}
		return returnValue;
	}

	/// <summary>
	/// For converting Xamarin Forms ImageSource object to Native Image type
	/// </summary>
	/// <param name="source"></param>
	/// <returns></returns>
	public static async Task<UIImage> GetUIImageFromImageSourceAsync(ImageSource source)
	{
		var handler = GetHandler(source);
		var returnValue = (UIImage)null;

		returnValue = await handler.LoadImageAsync(source);

		return returnValue;
	}

}

 

So here also we are using the same implementation as we used on Android, instead the LoadImageAsync() returns an UIImage.

Now let’s use it… 😉

Alright let’s see how to use these extensions in our code. 🙂

// Useage in iOS

UIImage _uiImageconverted = await IosImageHelper.GetUIImageFromImageSourceAsync(yourImageSourceObject);

// Useage in Android

Bitmap _bitmapImageconverted = await AndroidImageHelper.GetBitmapFromImageSourceAsync(yourImageSourceObject, this.Context);

 

There you have it, now you have your Xamarin Forms ImageSource converted to the given Native Image type, either iOS UIImage or Android Bitmap Image type. 😀

Enjoy! 😀

Cheers everyone!

Want to play a Vimeo Video in your Xamarin iOS app ? ;)

Remember my previous article on Let’s add a Video Stream Player to your Xamarin iOS App… ? 😀 Do you remember? If not check it out! It’s pretty cool! 😛

Anyways have you ever wanted to play a Vimeo video in your app? 😉 Question is probably yes and if you were redirected from Google, then you are already looking for it. lol 😀

The first time my boss asked me to do this, I was like.. huh? O.o Vimeo videos are played by streaming directly from their servers, how am I suppose to implement that in a mobile app, unless they have any 3rd party library, or adopt a bad practice such as implementing a web view to display the video with an embedded frame in it.

Yes it is a common requirement to attach an online video to your mobile app, such as from streaming giants as Youtube, Vimeo and etc. And for most of them have many third party libraries to consume their services such as streaming those videos, but only for native Mobile development.

But… what about Cross-Platform? ummm… Xamarin?  😦

Well it’s not impossible, there’s always a way! 😉

So today I’m gonna show you how you could play a Vimeo video in your Xamarin App.

First of all, if you haven’t implemented the Video player for your Xamarin app, then you may do as I did,  Let’s add a Video Stream Player to your Xamarin iOS App (but that’s for Xamarin iOS) and you could find a tutorial for Xamarin Android right here,Video player implementation for Xamarin Android.

Little something about Vimeo Videos…

When you consider a Vimeo video, it surely has the capability for streaming…

And also you could retrieve a static endpoint of the actual Video Source with extension.

but in order to retrieve you need to be the administrator of the account that posted this video. So this URL endpoint is what we are going to be using for our Video Player.

In my situation I had to play the Vimeo video which was posted by an account which I had the administrator access. But I couldn’t find if there’s any other ways to retrieve the static endpoint url for the video without having admin access to the Video you need to play.
So keep in mind it is crucial you have the admin access for the Vimeo account which had posted the video.

So how?

First log into your Vimeo account. Go to the Video you want to be played in your Mobile App. Click on the “Settings” button at the bottom of the video, in order to access Settings.

vimeo1

Once you’re in the Settings section of that video, click on the “Video File” tab.

vimeo2

Which will take you to the properties of the actual Video file of your Vimeo Video. Now pay attention to the bottom of the page here, where you’ll notice the “Access your Video files” section.

vimeo3

Yep right there is your savior, which will provide you with the endpoint URL with the extensions for your video, specially in different kinds of quality, HD or SD or even Live Streaming link.

So for our requirement we are going to be using the High Definition or the Standard Definition, based on your choice. Go ahead and copy the URL and use it as the Video source for your Video Player implementation in Xamarin. 🙂

vimeo4

Well that’s it! Simple as that! 😉

Hope this helped someone not to waste hours and hours by trying to implement WebView Embedded player for playing a simple Vimeo Video. 🙂

Cheers! 😀

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! 😀