I was wondering what my options are when it comes to doing advanced styling in iOS applications. I'm referring to things such as custom navigation bars (no gloss, my own images, etc.), custom tab bars, custom search boxes, button colors and shapes, etc. At some root level, provided I have PNG files for everything, is all of this possible?
I'm assuming that, at least for things like navigation bars and tab bars, doing flat styles may require me to simulate the standard actions using my own custom buttons and whatnot.
Has anybody tried to do things like this? The application I've been assigned to develop is very custom-style heavy and I don't have much room to move on this.
Posts
@William
The quick answer is, yes. You can customize the appearance of whatever you would like. While it requires a decent amount of code, there are some generally accepted practices that can help reduce this.
There are a few ways to approach this, but the way I have done it relies heavily on the AppearanceManager (may only be available in certain iOS version, I'm not sure). The AppearanceManager allows you to style certain elements of the iOS UI at a "root" level. You can start here for a quick how to:
http://docs.xamarin.com/guides/ios/user_interface/introduction_to_the_appearance_api
Something to keep in mind, is that not everything is included in the appearance API, so some things will have to be styled in-line with the rest of the code (not at a root level really) unless maybe you subclass things, etc. Some examples I think are table cells. You will need to create a custom cell with your images, styles and then use that or style the cell each time when you need to.
You can also look at the Themes section of the Component store and see if any of those are an option for you. Some of them allow for a trial, so you could get the feel for what is possible.
http://components.xamarin.com
One way of doing it that I really liked can be found in the Xamarin example project Field Service. There, they created a static class called Theme, which uses the
Lazy<T>
pattern to load images from the bundle. Then where they want to "theme" something like a nav bar, you can do something likeMost of the backgrounds, etc for elements can be changed using a "resizable image" and this Theme class has a few examples of that. You can also subclass a UINavigationBar (and anything else) and customize it how you want and then moving forward use that as your base class instead of just the plain UINavigationbar class. This is your option if don't have access to the Appearance API.
Hope this helps, good luck!
That's what I like to hear! Thank you, that answer is very helpful. I guess I'll have to dig around some examples, I'll definitely check out the Field Service one you suggested. I did see the Appearance API, but I was a bit discouraged when it looked like I can't do things like remove the shiny overlay and change the height of the navigation bar (which is one of the requirements in the style for the app I've been assigned). I don't really mind making subclasses for special UI elements either, as long as it's in C#.
You wouldn't happen to know any themes for Xamarin that are free, would you? I'd love to see the source code for something like the three $70.00 ones listed on the site, just so I can see how exactly they're applying these styles.
Anyway, now that I've seen those themes I at least know that what I want to do should be possible. I was just afraid that I would have to dive into Objective-C for this to work. Thanks for your help!
I have not been able to find a source for any theme components. However, do look into the Theme.cs file in the Field Service application, becuase I think its a good starting point to see what you can do. I imagine the components do something similar and at some point are wrapping the Appearance API with easier to use methods. Its a powerful API with things like:
Field Service Theme.cs : https://github.com/xamarin/prebuilt-apps/blob/master/FieldService/FieldService.iOS/Utilities/Theme.cs
Resizing the controls and bars will probably mean you will need to subclass your controllers to customize those attributes e.g.
You will then have more control over all aspects of what makes up the UIView of the Navigation controller (Frame, color, size, etc.)
I guess now my only question would be how to explicitly set the navigation bar controller of a view controller to use my new UINavigationToolbar subclass. It looks like the NavigationController property of the UIViewController class is not settable, so I'm not exactly sure how that would be done.
If at all possible, I would like to avoid using the visual Xcode editor for my UI controllers and just code everything in C#. I appreciate your help by the way, this is all pretty intimidating but I feel like I'm starting to get the hang of all this.
I was think you would so something like this:
You should be able to customize the UIView that is displayed in the NavigationBar. e.g.
Sorry, what class would your second code block go inside? I'm a little confused as to how exactly your custom UINavigationController (which I'm assuming is BaseNavigationController) is being added to the main page.
Sorry for the confusion, the block of code would go in the constructor of BaseNavigationController, where I put the comments to customize here.
You could rename that BaseNavigationController to something more suiting like LargerNavigationController or something that doesnt make it sound like an abstract class meant for inheriting, thats up to you.
Than in your main page you can do something like:
Now use mainNav just like you would with any other UINavigationController. If this doesnt help, could you be a little more specific with your questions? All I am showing you is basic inheritance so that you can customize the UINavigationController class in one place.
The flow is:
Make the constructor signature the same as the base class
Customize any of of the properties you want inside that sub-class.
That all does make sense to me, though for some reason I must be doing something wrong. I'm sure it's a simple mistake, but check it out:
I have three classes:
• LoginViewController: The main "screen" that my app enters, currently a blank iPhone UIViewController with nothing really changed
• NavBarController.cs: Inherits UINavigationController
• NavBar.cs: Inherits UINavigationBar
The .xib file of the LoginViewController, as viewed in Xcode, is blank and it looks like this:

My NavBar.cs class is more or less blank apart from the inheritance:
Ideally I would like to do the custom styling in here like you had mentioned, but in any case, my NavBarController.cs class is as follows:
So from what I understand, I have my own child navigation bar class (NavBar), of which a reference is being stored in my custom controller (NavBarController), and that nav bar view is added to the controller in both those constructors (after changing the background color to green for testing).
However, when I run my program, it looks like this:
No green bar. I've tried a view things, like changing BarStyle instead, and all kinds of stuff. I even removed the last line in those constructors expecting the NavBarController to be blank, and it still looks exactly the same.
Am I missing something really simple?
Okay I think I've made a little bit of progress. Delving away from the extended UINavigationBar class, I just changed the NavigationBar's TintColor property from within the constructor of my custom NavBarController class and it seemed to work.
However, I would very much prefer to build my own subclass of UINavigationBar and replace the NavigationBar with an instance of my custom class. However, I just simply can't find a way to do this.
Sorry about all these questions, but I know as soon as I learn these sorts of basic things I can really build this app pretty quickly.
@WilliamThomas
I'm a bit late here, but UIAppearance should sort out 90% of what you need. Don't subclass UINavigationController - it's not recommended (by Apple), from memory, and it's easier to do with UIAppearance.
From what I know, you can't change the height of a UINavigationBar. You may need to use something else. Try loading an image which is larger in, see what happens.
If you look on the Xamarin Seminars page http://xamarin.com/seminars I did one on UIAppearance which might help, and these blog posts:
http://fastchicken.co.nz/2012/05/20/earnest-debrief-visual-styles-in-ios-apps-uiappearence-custom-sections-in-monotouch-dialog/
Earnest is all done with UIAppearance
UIImage.LoadFrom...().CreateResizableImage is also awesome for things like buttons where you dont know the size up front. eg:
(this has a big non-scalable area at the top, and 5 pixels around the sides)
here's shots of the app I just finished, which might give you an idea of how much you do with very little work (about 10 lines of UIAppearance code
)
https://www.dropbox.com/sh/x1o6581trz8b656/gBmIF6UJfx
(yell if that link doesn't work)
That's some terrific info, @nicwise, thank you very much. I didn't realize quite how much power the UIAppearance API had. I'll be sure to read those posts and check out your seminar on the topic and hopefully get the ball rolling on this app.
If I get really stuck on something, would you mind if I shot you a message on here?
@williamthomas within reason[1], sure - just ask it here somewhere, and add @nicwise and I get an email
[1] I dont work for Xamarin, so I tend to do this stuff in my free time. Or when I'm procrastinating work. I'll be at Evolve next-next week tho.... Also, I'm in GMT+1 (UK)
Of course, I'll make sure not to bug you
I greatly appreciate your help, and yours too @John!
@williamthomas - Bugging me is ok - expecting an answer in a specific time isn't ;-)
Happy to help tho - I enjoy doing mobile stuff and generally love sharing knowledge about it.
@nicwise Of course! I actually do have a question though, whenever you may be able to take a look at it. I'm achieving quite a bit so far by using the UIAppearance API; I have to say, it's pretty fantastic.
One thing I can't currently figure out is how to modify the metrics of the selection indicator of tab bar items. I've gotten the hang of using background images to style them, which is quite nice. However, check out the following image:
I want to make the lighter blue section (the "selected" tab image) on the bottom completely flush with the rest of the tab bar, instead of having that small amount of padding around the edges. Is this possible using the UIAppearance API?
@WilliamThomas
I just did this:
And the images I've attached. This ends up with this:
http://fastchicken.co.nz/uploads/old/2012/04/2-footercomparison.jpg
Note that the smaller attachment is a specific size - 1/4 of the bar - as I had 4 items. I could have done it with a resizable image I think. The Selected one is the small one
Okay, I see. So from tinkering around, it looks like the default "draw zone" of the selection indicator on the tab bar contains that small amount of padding, and loading a resizable background image into that will cause that padding to remain.
But if the image is not resizable (like in your example), and it's the exact height and width that the selector should be, it all works. It's a little bit of a hack but I can't complain.
Anyway, thank you very much for that. I'm getting a much better understanding of this API the more I tinker with it, and my app is looking prettier by the second. I'm still a little bit confused about when and when not to use resizable images, but I'm sure I'll get the hang of it as I do more and more testing.
Again, thank you, your assistance is very much appreciated!
@WilliamThomas - not problem, CocoaTouch is quite huge, so it takes a bit to get used to all the new stuff and how it works
@WilliamThomas
Hi,
Im trying to remove the border or background image or bg color of a navigation bar as shown in the pic. Im using Xamarin forms iOS. I added a custom nav class and rendered in iOS then added the below code.
Ive tried setting background color to white but its always displays in black color. Could you point where Im possibly going wrong.