Article source: https://zhuanlan.zhihu.com/p/20783322

When developing iOS apps, how should we build the interface? The question is still debated. There are two main arguments:

  • Use xiB /storyboard to build the interface graphically, or use code.
  • Interface layout, whether to use traditional frame layout or AutoLayout to set constraints.

The above two arguments are independent of each other. Using code, you can choose either frame layout or AutoLayout. Using XIB /storyboard, you can also choose frame layout or AutoLayout.

But I find that a lot of people don’t understand this independent relationship. They think that AutoLayout should only be used in XIB/storyboards, and that the code should be used with a primitive frame layout. So there is a similar question, iPhone comes in all sizes, should iOS development not use code to write interface?

Frame layout is still AutoLayout

The debate has since died down and a consensus has emerged that AutoLayout should be preferred for iPhone screens of various sizes. AutoLayout also has disadvantages, such as:

  • There are no placeholders, causing some interfaces to use invisible Views as placeholders.
  • Some very common interface layouts, such as equal spacing, are difficult to express with AutoLayout.
  • There are many constraints to configure, and constraints can be cumbersome to set.
  • The real position needs to be solved according to constraints, which is time-consuming compared with frame layout and may cause performance problems in some cases. Like a complex TableViewCell.

When you analyze something, you should also analyze its advantages and disadvantages. As long as the advantages outweigh the disadvantages, something is valuable. AutoLayout has its drawbacks and needs attention in some cases, but overall AutoLayout is valuable.

For iOS development today, the interface layout should be based on AutoLayout, aided by the traditional frame layout. Even if you use a traditional frame layout, there are actually a lot of libraries out there that don’t count frames by hand. I wrote a LayoutKit library for frame layout.

xib

So when I said graphically, I wrote xiB /storyboard, so I put xiB and storyboard together. In fact, among those who support the graphical approach, there is also an internal debate:

  • Use separate XIBs, or use storyboards.

The tool that we used to create interfaces graphically with mouse drags was originally called Interface Builder. Before Xcode 4.0, Interface Builder was standalone software. Xcode 4.0 is a big release with a redesigned Interface and Interface Builder integrated directly into Xcode. Many developers today may not be aware of Interface Builder.

Before Xcode 3.0, Interface Builder created files in binary format NIB, which stands for NeXT Interface Builder. After his departure from Apple, Jobs created his NeXT company, NeXT, which was later acquired by Apple. Many of the entire systems, tools, libraries that iOS or OS X is developing today came from NeXT. Binary formats are inconvenient for version control, and after Xcode 3.0, Interface Builder used a new file format, XIB. Xib may stand for XML Interface Builder, or it may stand for OS X Interface Builder. Xib uses XML, which is converted to NIB at project compilation time.

Usually said to use XIB splicing interface. The xiB here usually does not refer to the xiB file format, but to the use of the Interface Builder tool, depending on the context. The XIB can actually configure any NSObject object, but we use it most of the time to create interfaces.

This history of Interface Builder can be found in the story behind Mac OS X (5).

storyboard

A storyboard, you can think of it as a set of XIBs, and each XIB corresponds to a scene. The storyboard sets the relationships between scenes. The relationships of the scenes are represented as lines in the storyboard interface, so that you can intuitively see their jumps, nesting, and so on.

A storyboard is a set of XIBs, so all the shortcomings of xiBs, storyboards also exist. Storyboards also have additional disadvantages compared to XIBs.

  • Storyboards display multiple scenes at the same time, which is slow to open.
  • Computers with small screens (like the 13-inch MacBook Pro) can be crowded to edit.
  • Storyboards often clash when merging with multiple editors.

In actual projects that use storyboards, storyboards are often split into multiple storyboards, with each member of the project team responsible for one, so as to avoid editing storyboards at the same time.

In storyboards you can set relationships between scenes, but it’s still weak. In practical engineering, interface switching is often not linear, but jumps according to conditions. One condition goes to one interface, another condition goes to another interface, so the storyboard still needs code to work with it.

It also supports Universal versions for iPhone and iPad. The interface layout may vary from device to device. For example, if the iPad has a larger screen, an interface can be split left and right, ViewController1 and ViewController2 side by side. The iPhone’s smaller screen is designed to show ViewController1 first and ViewController2 after a tap. In this case, the nesting relationship is completely different, and storyboards are not suitable.

Storyboard displays multiple scenes simultaneously, which is both its strength and its weakness.

Xib /storyboard and so on, again using code

I’ve tried multiple XIBs, I’ve tried storyboards, I’ve tried code. In the end, I came up with a solution: code first, xiB second, but no storyboard. A lot of people may not agree, but before you rush to refute, let me tell you my reasons first. I’m not trying to convince anyone.

I have three basic ideas about programming, including interface programming.

  • Programming should aim for batch problem solving.
  • Programming, should pursue reuse.
  • Programming should be easy to modify.

Aim for batch and reusable solutions so that you can get things done faster, slower at first, but faster and faster.

As a project goes on, requirements are bound to change. Swear as much as you want, demand will change. Some people try to predict accurately and start by estimating future needs. I believe that there are people who can predict the future, but they are geniuses, and mere mortals like me cannot learn. So what I’m looking for is not accurate prediction, but to make it easier to modify changes when they come. This difference in thinking leads to a difference in behavior. For example, I don’t spend too much time defining requirements, but just have a general direction and then refactor and adjust accordingly.

This graphical approach to xiB /storyboard often contradicts these three basic ideas.

Xib /storyboard cannot solve problems in batches. For example, if I have N screens and I need to change font colors, I need to change font colors N times.

Xib/Storyboard interfaces are hard to reuse. Things with larger granularity are harder to reuse, and things with smaller granularity are easier to reuse. A button, a view, a basic layout, is easy to reuse, whereas xiB /storyboard interfaces are hard to reuse, and storyboards are harder to reuse than XIBs.

Some might argue that the interface itself cannot be reused. But with code, basic interface elements such as hues, fonts, lines, shadows, buttons, etc., can be reused, as can interface constraints. But with XIB /storyboard, all the interface elements need to be reset one by one, so they are basically not reusable.

As a side note, when programming, experienced people tend to break up the code into smaller pieces and put it back together. It’s like having a little building block, and then splicing it up into bigger building blocks, layer by layer. To some novices, this code can be difficult to understand. Newbies tend to start out as one big, unbreakable chunk, thinking it’s better that way. Novices often make bad changes to good code without even knowing it.

As for easy modification, this is a bit repetitive with batch solving problems. If the modification needs to be changed N times, itself is not easy to modify. Even if the same interface is configured with xiB /storyboard constraints, those constraints are hard to change. If you have three buttons, you configure the constraints, but you have to insert a button in the middle, and you have to change it to four buttons, and it takes a while. In addition, when I take over xiB/Storyboard files of others and modify them, it is difficult to figure out their constraints. When I take over, I often delete all the constraints and reconfigure them myself.

Xib/Storyboard is a quick and easy way to validate ideas and make prototypes that are basically immutable. But for a project that requires constant maintenance and changes, it’s actually not faster than code.

So I don’t really like xib/ storyboards to build interfaces, I like to use code. Sometimes xiBs are used to assist. But I only use the XIB to set the style of the controls, such as font, color, text, etc., and then use the code to set the AutoLayout constraints.

graphical

Some people blindly recommend graphics over code because they think it’s easy. But what exactly is simple? Many people think that simplicity is intuitive, without thinking, a look will be. Simple, I think, means consistent behavior with few or no exceptions. Simple things can be unintuitive and may need to be learned, but once learned, a whole host of problems can be tackled indiscriminately.

So graphical things don’t have to be simple, and code doesn’t have to be complex.

I’m not against graphics, I just think that dragging constraints over XIB interfaces with the mouse is silly, slow, and inflexible. I even think XIB went astray in the AutoLayout era by dragging constraints with the mouse.

The first thing many people think when they hear about graphical tools is that they don’t need to write code. Some tools generate a lot of configuration files just to keep people from writing code. They seem to think that writing code is backward and primitive.

In iOS interface development, writing code is not a problem at all. The main problem is that the time between writing code and actually being able to preview it is too long. Rather than rejecting the code, we should focus on shortening the feedback process to preview.

For programmers, code is the most intuitive, flexible, and controllable.

The way I want to do it, I’m still writing the interface in code, but I can see it in real time. Just like with web pages and Markdown, you can see the effect as soon as you save the code. I really hope that Swift language playground can be applied to practical projects. Or some Swift files can be switched between compilation and interpretation. In normal development, the interpretation is executed, and the code changes can be seen in real time. When it was finally released, it was compiled to make the program run faster.

The goal is not to eliminate code, the real goal is to shorten the feedback process from modifications to previews. Allowing our eyes to see change in real time, not just through imagination.

AutoLayout layout library

Writing constraints in code is cumbersome, and there are many AutoLayout layout libraries.

For Objective-C, you can use navigation. For Swift, use Cartography or SnapKit.

I have used all these libraries and they are all excellent. However, these libraries are not easy to use. Their apis only configure constraints between one or two views at a time, making it difficult to see the relationship between views as a whole from the code itself.

The layout library I’m using now is written in Swift myself. If you’re interested, check out AutoLayoutKit here.

Size Class

Nowadays, when it comes to interface adaptation in iOS development, AutoLayout and Size Class are always mentioned together. It seems that the two are inseparable. In fact, AutoLayout and Size Class are two completely different things.

The Size Class is simply divided into several types based on the Size of the view. We then set the constraints separately in the XIB /storyboard depending on the type. For example, if you adapt iPhone and iPad at the same time, set a constraint for the Size Class type of iPhone, and then set a set of constraints for iPad. Of course, the same constraint can be set once, but different constraints need to be set twice. In fact, the classification of Size Class is rough and incomplete. For example, iPhone 6 Plus, which is between the Size of a phone and a tablet, is prone to problems.

Size Class doesn’t make much sense to someone like me who uses code layout. I’ve already used the code, and I can always get the exact size of the view when I’m laying it out, so there’s no need to categorize the size of the view.

Some people have mentioned the benefits of xiB /storyboard, which is also often said that with AutoLayout and Size Class, you can adapt to iPhone and iPad without writing a line of code. As I mentioned above, not writing code is not a benefit. Interface logic is not written in the code, is in the configuration, there must be somewhere to write. It’s just written in the configuration, you can’t see it, the complexity is there all the time. Setting the constraint a few times is not something to be proud of.