📜 ⬆️ ⬇️

Ångström Style System? The use of styles. S2

What is the Ångström Style System?


In a typical mobile application, the interface is one of the most complex and most important parts. What users see, what customers value in the first place, when accepting work.

Even if the design is drawn before development, in the process of creating the first version anyway there will be a huge amount of changes. Then repaint the button, move it, increase / decrease the font, because it does not fit, and so on. Each of these changes needs some work. Often there are several hundred or even thousands of such modifications if it is impossible to immediately find the right parameters.

In such a situation, it is very advantageous to separate the design settings from the interface itself and configure them independently. This problem should be solved by a style system, ideologically - like CSS for HTML.
')
In the article I will show how I try to organize styles in the application, and by what means I use for this.

The structure of the style system in the application


When I develop an application, I usually get two layers of style settings. The first layer contains the most basic:


These are the parameters that permeate the entire application. If suddenly the designer decided that he chose a bad font and needed to change it, then you need to change it right away everywhere. This layer is usually quite small and clear to everyone. You can give to edit / build it to the designers or even, in especially trusted cases, to the customer.

From these parameters, in a huge number of variations, a second layer of styles is created. There are already described specific screens, specific interface components. For example.


The files of the second layer are usually bulky, it is convenient to split them into several, according to the screens or sections of the application.

Advantages of styles in the application


Styles, especially organized in two layers, very well separate the interface settings from the code . It is easier to find in several style files where this font size setting is here than to search for hundreds of source codes or huge storyboards.

In case you learn how to download styles from a remote source (from a file in DropBox), then design customization is accelerated hundreds of times during remote development . It's one thing when a designer can sit down with a developer and try to quickly tune some parameter, and when is it impossible? Each iteration can take hours and days. In this case, I updated the file, restarted the application (or made a clever secret gesture), looked at the result.

In some situations, it is convenient to use skins. For book readers, for example, it is a necessity; it is convenient to read during the day with a light background, at night - with a dark one. Sometimes the customer wants it, sometimes the design is required for a “wow effect”. If you make two versions of the first layer of styles, you can switch them, leaving the second layer the same. As a result, skins are almost free .

When was the need for a style system?


The need for a style system appeared at once from two sides:


I prefer to test new ideas on my own projects, rather than on customer projects, so Angstrom was lucky and I created a style system for him. It used the JSON file to describe the styles, into which I added the possibility of including other files (including “from Dropbox”). The framework also implemented callbacks that reported that the style had changed. I connected the update styles to the shaking of the iPhone, it turned out interesting. Corrected the file in Sublime, saved, shook the iPhone, the styles were loaded and applied to the entire application.

Disadvantages of the existing system that “did not take off”?


In general, the idea was so successful that it quickly spread to all of our created applications. In some cases, this made it possible to significantly reduce development time (when the customer’s designer, for example, wanted to adjust the fonts or colors), sometimes the design changed from design to release completely several times, almost completely without the participation of the developer (or with minimal participation to customize thin moments).

But I didn't like a few moments.

First, JSON. It always happened that I accidentally forgot a comma or made another stupid mistake in the file, and all the styles broke. JSON does not check the names of the lost ones (these are just strings and it doesn’t matter what’s written there), typing is artificially introduced, which also prevents early detection of errors, and so on.

The same JSON made me encode data types right in the names. My colors ended in color, the points on the center or point, and so on. As a result, the names of the fields were much longer than required.

After the first attempts to use the style system, it turned out that the most convenient option is when a class hierarchy is created according to JSON, which completely repeats the hierarchy of objects in JSON. In the application, a strictly typed structure then appears, which can be conveniently referred to as ordinary code. In principle, it was possible to tie UI components to an update of styles, so that the style knew that it was applied to this button, and if it was updated (a new style was downloaded from Dropbox), then the button itself would update. But in fact, it turned out that such magic only interferes with living, it is better to prescribe the update rules explicitly.

Thirdly, I did not create a console utility that would generate style classes. And the styles themselves were recreated when the application was launched in the simulator. This turned out to be a significant disadvantage, both when connecting styles to the project, and during their subsequent update.

Objective-C also interfered a bit with the need to support older versions of iOS. The generated class code was large and unpleasant, I would very much like to optimize it.

S2 - a simpler and more efficient style system.


Understanding the shortcomings, I tried to improve the system so that it was better suited for solving problems, in all respects:


For example, I will give a (very small) fragment of the original KTV:

{ maxWidthForIPad: 600 darkTheme: false defaultFontName: HelveticaNeue-Light bolderFontName: HelveticaNeue boldFontName: HelveticaNeue-Medium defaultSymbolFontName: AngstromSymbols-Light bolderSymbolFontName: AngstromSymbols basicColors: { plateBackground: #edf5f4 separators: #00407020 } ilya: { aboutBackground: @basicColors.plateBackground listSeparator: @basicColors.separators } colors: { about: { background: @ilya.aboutBackgroundColor separator: @ilya.listSeparatorColor } } about: { margins: [0, 0, 0, 0] separatorSpacing: 10 background: @colors.about.backgroundColor separator: @colors.about.separatorColor } } 

And the corresponding fragment of the style file, which is obtained:

 let S2 = CONStyle() public struct CONStyle: S2Object { private static let _rootStyle = S2 public struct BasicColors: S2Object { let separators = UIColor(colorLiteralRed:Float(1.0), green:Float(1.0), blue:Float(1.0), alpha:Float(0.0)) let plateBackground = UIColor(colorLiteralRed:Float(0.929411764705882), green:Float(0.929411764705882), blue:Float(0.929411764705882), alpha:Float(1.0)) } let basicColors = BasicColors() public struct Ilya: S2Object { let aboutBackground = _rootStyle.basicColors.plateBackground let listSeparator = _rootStyle.basicColors.separators } let ilya = Ilya() public struct Colors: S2Object { public struct About: S2Object { let background = _rootStyle.ilya.aboutBackgroundColor let separator = _rootStyle.ilya.listSeparatorColor } let about = About() } public struct About: S2Object { let margins = UIEdgeInsets(top:0.0, left:0.0, bottom:0.0, right:0.0) let separatorSpacing = Int(10) let background = _rootStyle.colors.about.backgroundColor let separator = _rootStyle.colors.about.separatorColor } } 

Of course, using Swift would be inconvenient for fully Objective-C projects. This will drag you into the Swift-runtime project, which can significantly increase the size of the application. But, firstly, it is not very difficult to write a generator of purely Objective-C code, and secondly, everything now goes to the massive use of Swift in applications, so that the generated S2 code will be "in the subject."

Source: https://habr.com/ru/post/278787/


All Articles