I have learned that in iOS 5, properties that are marked with UI_APPEARANCE_SELECTOR can be styled using appearance. Eg [[UINavigationBar appearance] setTintColor:....]. However, I seem not to be able to style all elements. UIButton, for instance, has no properties marked UI_APPEARANCE_SELECTOR, hence I am not able to use the above technique to style it.
My question is: How do I best style elements globally (all appearances in the application), when I cannot use appearance?
Right now I have defined some colors, fonts, shadow offsets etc. that I use many different places in my code. This allows me to change the look and behaviour of a lot of elements, but it still doesn't allow me to style all instances of a certain object with only one line of code.
Edit
In lack of better solutions I have created a number of categories with simple methods as the following:
+ (UIButton *)customLabelWithFrame:(CGRect)frame andText:(NSString *)text;
Also I have found that - in combination with the described categories - stretchable images are nice and useful.
With the above I am able to style in a global-ish manner, however I am not satisfied with the result and I still hope to find a better solution
What about standard subclassing or factory classes, as you mentioned yourself!?
For buttons I'm using factory classes myself.
I think a really nice solution could be the Android way of designing interfaces. Android relies on XML files to define the user interface. As a matter of fact, I'm working on a library that aims to give the projects I'm working on much the same capabilities. It's still a work in progress / experiment and as such really messy code (you have been warned!), but it might give you some ideas.
An example project can be downloaded here: http://dl.dropbox.com/u/6487838/WSLayoutManager.zip
Experiment a bit with the XML files by adding controls. Create custom control classes and instantiate them from the XML file, etc... It's fun stuff :)
Related
Coming from the .NET world, I was used to naming my UI elements with the type prefix. Examples:
btnSend
lblName
etc...
The advantage is that in intellisense/autocomplete, the moment I start typing "btn..." I get to see the list of all my buttons.
However, I find that in Swift, the most common approach is to name UI elements with a type suffix instead:
sendButton
nameLabel
usersTableView
etc...
The problem is that I can't remember the names of all my buttons. When I start typing "butto...", I was hoping to see a list of all my buttons, but instead I'm seeing all the framework classes first, and I have to scroll down to see my stuff.
So, my question: is there a convention for naming UI elements? Does Apple recommend naming a button as sendButton instead of btnSend (or buttonSend)? Is there a setting in XCode that will allow me to see items I defined first in the autocomplete list?
You can use any style as long as you are consistent with it throughout your application but still, if you want to go through the design guidelines you can check swift-style-guide by raywenderlich and api-design-guidelines from Apple.
What's the best way to perform simple default styling?
I'm not interested in styling every single UI element in the interface builder and the UIAppearance proxy seems to be very limited. I am looking for solutions to default styling UI elements with low coupling.
note that i am using swift 3 / xcode 8
UIAppearance is the default styling mechanism in UIKit. It doesn't seem very limited to me, yet it indeed has some downsides. You should give it a try if you haven't yet.
If you're interested in a non-UIAppearance-based approach, it's possible to craft even more powerful custom styling mechanism. For example, I've been able to attach and compose styles in the following manner:
final class CaptionLabel: UILabel, CaptionFontStyle, MultilineLabelStyle
See Style.swift and RootStyle.swift in the StyleSheet library for implementation details (it's really simple and there is an example project as well).
What are some best practices of theming/skinning an iOS app?
Examples:
Using custom images as screen backgrounds.
Modifying the look of UITableView tables.
Buttons with a custom look.
Links to good tutorials are a plus.
You can create a protocol that defines methods to return theme-specific colors, images, etc. All classes that conform to this protocol have to implement these methods.
#protocol MyCustomThemes <NSObject>
-(UIFont*)writingAreaFont;
-(UIColor*)dataCellLabelColor;
-(UIImage*)dataCellBackgroundImage;
#end
I can suggest that:
Make theme class
Make function to return background image(s)
Make function to return data cell.
make any required function in the theme class.
the init function should have one parameter to plist file that contains the assets(images) that will be needed for your class to work properly. it should be a plist file that contains a dictionary for a predefined keys.
I hope that helps.
You might take a look at NUI, which lets you modify the theme/skin of an app very easily, and save that theme for other apps, too.
For example, if you wanted to use a custom image for the background of all of your UIViews, you would just put the following in the NUI style sheet:
ViewBackgroundImage String MyImage.png
NUI supports styling for UITableViews and UIButtons, too (as mentioned in your other examples).
You might want to check out Freestyle. It's built on Pixate, and styles your app with structured Sass. You can do as little as change the variable values to make a new theme, or extend and customize it via CSS or Sass.
Old question, but still - if you're looking for best practices, then UIAppearance is probably it.
However, if you're looking for a more powerful way to style your app (and create themes) - also have a look at InterfaCSS. InterfaCSS uses stylesheets inspired by CSS (and Less/Sass) that support a rich selector syntax and lets you use standard UIKit property names.
I know this may be late but I've stumbled upon a theme framework called Pixate. Pixate allows you to theme all your components using css. It's native meaning no web views and what not AND its fairly easy to implement in an existing project. Check it out.
I'm starting with android, and the app I'm developing is gonna need custom widgets look (glossy buttons, animated backgrounds etc.),
I've googled for any external libraries to achieve this and did not find anything.
let me guess, the only way to this is by painly extending base view classes and overriding onDraw etc. ?
You need to explore View Styles. You can customize almost any view element. You might not need any external library that extends and designs custom buttons.
More ref:
http://blog.androgames.net/40/custom-button-style-and-theme/
http://www.androidworks.com/changing-the-android-edittext-ui-widget
I like this library quite a lot: https://github.com/cyrilmottier/GreenDroid
It includes:
Action bar
Quick action
AsyncImageView
and a lot of other things
It's easy to use and nice for quick developments.
I'm learning to use GWT 2.0 and I'm trying to convert the StockWatcher demo to use the UiBinder. the demo uses stocksFlexTable.getRowFormatter().addStyleName(0, "watchListHeader"); to add styles, but when I add <ui:style> to my XML and move my CSS I can't seem to figure out how to make the style work because there is no stocksFlexTable.getRowFormatter().addStyle(). Does <ui:style> just not work with FlexTables?
I tried to deal with it as well with no success. I believe though that dynamic widgets such as FlexTable are not fully supported for obvious reasons - i.e. you can't preset the style for the nth row when you don't really know how many rows the table will hold. Also, providing some arbitrary way to do it for the first only, or odd rows etc. would require more expressive power than what the GWT developers seem keen to offer (they try to stick close to XHTML) and i believe they state at the wiki at somepoint that declarative syntax is by no means a templating language. Anyway, you can always experiment with #UiFactory and #UiField(provided=true) to try and stick close to GWT recommendations. But still, you ll have to set any such values programmatically.
I had success by removing the section completely and moving all of the css for the FlexTable into the application css file.