Apple’s new wearable is finally making it out to users, which means now is the time to start building apps for it! First, let’s take a look at the different pieces that make up a watch app.
Watch App: While you might think that this is where most of your app logic will live, watch apps actually offload all real work to their parent apps. The watch app itself effectively contains just the user interface and not any of the code behind it.
Parent App: This is the normal iOS app you’re already familiar with, and what users will download from the app store. Even if your app is meant to only target the Apple Watch you still need a parent app that lives on the user’s iOS device.
Watch Extension: Similar to other extensions on iOS, a watch extension is used to connect the watch app with its parent app, and also contains the code that drives the watch app’s user interface.
When defining your watch app’s interface there are three interactions you can take advantage of:
Normal: the main UI that users can interact with when the app is active
Glances: a non-interactive view of the app that can give users important information quickly. Tapping on a glance will result in launching the full app
Notifications: Watch apps leverage the normal iOS notification system by default, but apps can choose to provide a custom interface to use for displaying notifications
Only the normal interaction mode is required for a watch app, but you can choose to add customized glances and notifications to help enhance your user experience as appropriate. In this article I’ll focus on just the normal mode.
Some of the best ways to become a better software developer, in general, is to listen to other people’s experiences and learn from them. As a consultant, I’ve had the privilege of working with some of the brightest and talented software developers I have ever met. I enjoy working with people who are smarter than […]
This is going to be a rather long post about building the Swiper control for iOS. There is also a WP and an Android-renderer available but in this post I’ll focus on iOS.
The Swiper control is a image flipping control that displays images in a long line and allows for lazy-loading of new images.
All source code is available at GitHub (https://github.com/johankson/flipper) and the bits can also be downloaded through nuget (http://www.nuget.org/packages/Flipper.Forms/).
What’s the purpose with this blog post?
The purpose is to show you how the swiper control is built from an iOS perspective.
Introduction
This control is a standard Xamarin Forms control. That means that there are two major parts;
The shared code in the PCL
One renderer for each platform
In the shared code we declare our control in a platform agnostic way. I’ve chosen to name it Swiper.cs (upper blue arrow). Each platform then has a corresponding renderer if they do custom rendering that is. In this case the lower blue arror pointing at the file named SwiperRenderer.cs.
We’re going to look into details for each of these files in a little while. But first I think we should start by looking at how the control is used and what it looks like in action.
How is it used?
We’re going to start at the end where it gets used. In a XAML-page, the example is from the sample app included in the project.
The first thing you need to do is to declare a namespace so that we can reference the control.
The only mandatory property that you need to set is the Source property that is an ObservableCollection that contains a list of image URLs. The reason for it being observable is that the control needs to react to you adding (or removing) images to the list and update stuff based on that.
To help you with the lazy loading you can specify a command to be executed when the user is closing in to the end of the list. The name of this command is IsNearEnd. You can control the timing of this by setting the NearEndTreshold property to fire the command when the desired number of images are left.
The SelectedUrl and SelectedIndex can be set and read. Please note that the URL must exist in the already supplied list. I was thinking about adding a behavior that simply adds a new URL to the end of the list if the URL isn’t in the list.
So what does it look like?
This is 29 amazing seconds of random image flipping…
Ok, show me some code!
Let’s start with the platform agnostic part. I’ve chosen to inherit from the Xamarin Forms View class since it best fits my needs of behavior. I’m not going to show all the code here since it would just take up a lot of space. For the full sample, check out the source at Github.
The second thing you need to do is to define static BindableProperty objects for each property that you want to bindable and then map these to the actual member property of the class. In a nutshell, this is what my platform agnostic piece of the Swiper control do. It could do more. One example is to move the code that determines if we are getting close to the end of our image list. This code is now in each of the three renderers… Bad practice… Well, no ones perfect.
The renderer
Most of the code is within the renderer class in the iOS project. To allow for the Xamarin Forms framework to be aware of what renderer that goes with what control, you need to register them. In our case it looks like this:
It declares the fact that if the framework needs to render a control of the type of Swiper, please use the SwiperRenderer. In fact, you can create a renderer for any Xamarin forms control. For example overriding a Label by inheriting form a LabelRenderer and add custom logic to it. This line of code must be outside any namespace declaration.
The SwiperRenderer class inherits from ViewRenderer and here’s where the platform specific magic kicks in. Notice the UIView at the end of the generic declaration. This is a “native” (everything is native, but this is more native) iOS UIView that we are going to render our stuff on.
Some image swapping theory first
The way I created this control is not the best way, the first way or the worst way. It’s just one way of doing it. I did it to learn more about custom renderers.
What I did is that I took three UIImageView object called them left, middle and right. If we just look at the control, the middle image is the one you see. I then listen to touch events and track drag along the x axis, repositioning the images as the user moves his/hers finger. If the delta value of the drag is above a certain threshold when the user ends the draw the images are animated either left or right. As soon as the images are animated the position of the UIImageView objects are reset and the current index is updated and images are reset. You never see the “jump”.
The normal flow
Right after the renderer is created, the OnElementChanged(…) method is called. This is called once in the renderers lifetime (normally) and lets you create the native control and pass it back to Xamarin forms. It looks like this:
Here you can react to changes in properties. In the example above, if the Source property changes we need to reinitialize our images. In fact, we reinitalize them a lot.
And finally, the OnPan method we wired up to handle any drag events handle the interaction with the user. Check it out in the sample, it’s long but self explanatory.
Also, worth noting, there is no draw call since we don’t need to override it. iOS is very good at recognizing invalidation of the UI and redraws just fine without us bothering it. The Android version of this control however is mainly manual drawing. Mostly for fun…
What about caching
Well, there is still job to do here. At the moment, I use a simple Dictionary that has no concept of size management and storing to disk. It is destroyed as soon as the user navigates away from the swiper.
//Primitivecache–nolifetimemanagementorcleanup–alsostorestheimageinfullsize. //Thinkingaboutabstractingthecacheawayandinjectitinsteadtomakesureitcan be //replacedduringruntime. privateDictionary<string,byte[]>_cache=newDictionary<string,byte[]>();
How does the loading overlay work
Oh you noticed that, nice! When I said that I had three UIImageView objects… I lied, I have three AsyncUIImageView objects that inherit from UIImageView that simply adds an overlay if an image hasn’t loaded yet.
Any other special cases
I needed to set the alpha to 0 to make the “-1” picture invisible so you don’t see it when scrolling left of the first picture. Clearing the Image source didn’t work. Now that I think about it, that should work… I need to investigate that again.
Summary
This is just version 1 of the control. If you have suggestions, please add an issue to the Github project directly and feel free to steal any code you fancy.
Lay back, relax & gaze at the clouds as we take a walk through the Azure Mobile Services – Data API. We’ll look at modeling data to work in the cloud, pushing modifying data up, and bringing it back down. We’ll also consider some design considerations for using Azure Mobile Services with Xamarin and cross platform apps.
Recently, I have fallen in love with Xamarin Studio add-ins and in my last blog post I took a look at how to edit markdown files easily. I was at Google I/O last week with Jérémie Laval and Jon Dick and he was working on binding the new awesome support libraries from Google and Jérémie and I saw Jon do something interesting…. Obliterate Output Paths from inside of Xamarin Studio’s context menus.
Immediately, we wanted to know exactly what Jon just did and how do we get this?!?!? Jon told us that he often has to ensure that the bin/obj folders are deleted completely and it was tedious to go through and delete them, so he wrote an add-in to do it for him!
To add the add-in simply follow my previous posts instructions pull up the Xamarin Studio Add-in Manager. Then you will want to install Redth’s Addins under IDE Extensions.
Now, from any single project or at a solution level you will see a new “Obliterate Output Paths”. #MindBlowing Simple and elegant and I hope you enjoy.
Outside of a few small bugfixes and upgrading to the unified API a few months back I really haven’t needed to mess with it much, and have been successfully using it in many apps in the meantime. I’d always intended to make it available on NuGet, but I never got around to that…until now. You can now grab both the standard version and the MonoTouch.Dialog version on NuGet:
I kept them as separate binaries so that you don’t need to take a dependency on MonoTouch.Dialog if you aren’t actually using it. I also took this opportunity to rename the project and restructure things to make way for adding an Android version. The GitHub repository has been renamed to FloatLabeledEntry as well. Let me know if you’d prefer to see a Xamarin Component in addition to the NuGet package.
Using the library is just as easy as before:
var titleField = new FloatLabeledTextField(CGRect.Empty)
{
Placeholder = "Title",
FloatingLabelFont = UIFont.BoldSystemFontOfSize(12),
FloatingLabelTextColor = UIColor.Gray,
FloatingLabelActiveTextColor = UIColor.Blue
};
or if you’re using MonoTouch.Dialog:
new Section
{
new FloatLabeledEntryElement("Title")
}