How to correctly write an interface and write it properly
The writing interface can be said to be a basic skill for every mobile app developer, and it is also a hurdle that qualified mobile app developers cannot go around. However, just as not every developer can become a qualified developer, I found that few developers in different teams can compile qualified UI code. What's strange is that, in many developer forums, we can see that mobile developers are more interested in a widget or animation, But we rarely see articles that deeply analyze the UI mechanism and guide UI development.
Because the interface involves too many aspects, this article cannot be very detailed, one by one, so this article first based on the points, in-depth analysis of iOS UI system is not valued but very important mechanisms, this article helps readers understand the iOS UI system as a whole, expand to the discussion of the UI logic design and architecture design modes by Dot and band; finally, read the article and think about it, design and develop efficient, easy-to-use, and smooth UI modules.
This section is as follows:
There is no inevitable relationship between each chapter. Readers can choose to read the chapters they are interested in.
1. basics and Nature
The biggest difference between terminal App development and backend development is that most of the logic of terminal development is to provide users with interfaces for human-computer interaction, the so-called User Interface ). Therefore, all UI architectures focus on three major modules: interface layout management, rendering, animation, and event response;
1.1 layout management
That is, in the specified coordinate system, the positions are arranged in the container according to a certain hierarchical sequence. A ui system must have a coordinate-based layout management system, whether it is Windows, Sysbian, Andorid, or iOS. A good layout management mechanism directly affects the difficulty of implementing the interface logic;
The UI Coordinate System of the App we are currently familiar with is two-dimensional. The 3D game we are currently playing is limited by two-dimensional display screens, so it is essentially only a three-dimensional ing projection on two-dimensional. We have been developing towards a higher dimension: holographic images, Hololens, and so on. We can imagine that in the future, the layout management of our interface may be based on real 3D coordinates.
1.2 animation and rendering
The UI is called User Interface because the UI provides information for users through visual display. This information needs to be displayed through a series of complex calculations, and finally the LCD is displayed on the display. This series of processes are rendering and animation;
Is the process of rendering the application interface to display:
Source: WWDC2014 #419 Advanced Graphics and Animations for iOS Apps
We recommend that you carefully view the rendering process and interface optimization;
Recommended materials:
- WWDC2014 #419 Advanced Graphics and Animations for iOS Apps
- Objc. io article: # Objc Issue 3: Views-Getting Pixels onto the Screen
1.3 Event Response
In addition to display information, the UI also needs to receive and respond to user clicks, gestures, shakes, and other events. After a series of operations, the UI updates the display information and displays it to users; correct and timely response to user operations and feedback are a guarantee for a good user experience. One of the main reasons why Android devices generally feel like they are getting stuck on iOS devices is that the iOS system gives the highest priority to respond to user events in the main thread.
1.4 UI System Architecture
From the overall understanding of the above three aspects, you will have a systematic understanding of the UI architecture. The UI System Architecture in iOS is as follows:
Source: WWDC2014 #419 Advanced Graphics and Animations for iOS Apps
2. View
UIView is the most basic control in UIKit. Just as NSObject is basically the base class of all classes in the Cocoa library, UIView is also the base class of all interface controls in UIKit. As long as you want, you can even build your App with only UIView (however, iOS9 is constrained and you must set the keyWindow rootViewControler ).
Generally, mastering commonly used UIView subclass controls (such as UIButton, UIImageView, and UILabel) is sufficient to meet 90% of the interface coding requirements. However, if you want to write efficient and beautiful interface code, you still need to have a better understanding. Now that you want to go deeper, this article assumes that you have a preliminary understanding of UIView and have written at least a few complete pages. Based on this setting, This article focuses on the following points:
1) UIView and CALayer: Discuss the CALayer behind the UIView and understand the relationship between CALayer and UIView and the rendering process;
2) Offscreen Render: describe what is Offscreen Render (off-screen rendering) and some methods to avoid off-screen rendering;
3) UIResponser: Discusses the parent class UIResponser of UIView and UIViewController, and analyzes the Event Response chain on iOS devices;
4) Design and Practice: Based on my development experience, describe the design practice rules in the UIView application;
Reference: View Programming Guide for iOS
2.1 UIView and CALayer
We should all know that every UIView contains a CALayer. It should have been used even if you haven't seen CALayer directly. For example, you can add a rounded corner to a View:view.layer.cornerRadius = 5.0f;
; Add a border:view.layer.borderWidth = 1.0f; view.layer.borderColor = [UIColor darkGrayColor].CGColor;
The layer used here is CALayer.
CALayer is a class in the QuartzCore library and is the most basic drawing unit on iOS. UIView is only an encapsulation of CALyer. More accurately, UIView is a lite package of CALyer, add the collection class for event processing. In the next section of event processing, we will discuss how to understand the simple encapsulation here. Why not use CALayer directly?
First, as described in the preceding section, CALayer is the most basic drawing unit. Each UIView has a CALayer variable (public var layer: CALayer { get }
), The rendering essence of UIView is the rendering of this layer. We can look at the class definitions. There are many attributes (variables) and methods that can find almost identical mappings in them, such as attribute variables.frame
,hidden
, Methodpublic func convertPoint(p: CGPoint, fromLayer l: CALayer?) -> CGPoint
But there are also more attribute methods that are not available in UIView. Here we will list them one by one. We can see that UIView exposes common interfaces (attributes and methods), making UIView easier to use.
Secondly, we know that the Cocoa Touch on iOS platform is derived from the Cocoa on OS X platform. It adds Gesture Recognition and animation features suitable for mobile phone devices based on Cocoa; however, at the underlying implementation level, Cocoa Touch and Cocoa share a set of underlying libraries, including QuartCore. framework; however, QuartCore. framework was designed for OS X at the beginning, so some of these features are not suitable for mobile device development, such as the most important coordinate system. Therefore, it is not difficult to understand why UIView/NSView is encapsulated on CALayer.
The preceding figure shows the main relationship between UIView and CALayer.
2.2 Offscreen Render
When writing UIScrollView and its sub-classes (UITableView and UICollectionView) at the initial stage of unknown development, you will surely encounter a situation where the scrolling is not smooth and often gets stuck. You should study the code carefully, I found that all your logic code is put into an asynchronous thread, and the main thread is doing rendering Interface Activity. Why is it stuck? Then you want the veteran to seek help. The veteran will let you remove the rounded corners, translucent shadows, and so on, and the App will go back to silky smoothness. You don't know why, ask the veteran, he may explain it to you in detail, and then you nod your head with half-resolution, with a piece of confusion in your mind. In good cases, you may vaguely remember the word Offscreen Render ). So what is Offscreen Render? Why does Offscreen Render cause freezing?
The rendering flowchart is mentioned in section 1.2 of Chapter 1. Let's take a deeper look at the most basic rendering channel process:
Source: WWDC2014 #419 Advanced Graphics and Animations for iOS Apps
Note: The GPU rendering mechanism of iOS is Tile-Based, while Tile-Based GPU is also the mainstream for mobile devices;
Let's take a look at the rendering channel process for Offscreen Render:
Source: WWDC2014 #419 Advanced Graphics and Animations for iOS Apps
Generally, OpenGL submits the animation submitted to the Render Server for direct rendering and display (Basic Tile-Based rendering process ), however, for rendering of some complex image animations, The Overlay display cannot be directly rendered. Instead, the Overlay display must be rendered based on the Command Buffer sub-channel and then combined. During this combination, some rendering Channels won't be directly displayed; compared with the basic rendering channel process and the Masking rendering channel flowchart, we can see that the Masking rendering requires more rendering channels and merging steps; the channels that are not directly displayed on the screen (such as Pass 1 and Pass 2) are Offscreen Rendering Pass.
The Offscreen Render is choppy. We can see from the perspective that Offscreen Render requires more rendering channels, and switching between different rendering channels takes some time, during which the GPU will be idle, when the number of channels reaches a certain level, the performance will also be greatly affected;
So what will happen to Offscreen Render?
1) drawRect2) layer. shouldRasterize = true; 3) has a mask or shadow (layer. masksToBounds, layer. shadow *); 4) Text (UILabel, CATextLayer, Core Text, etc )...
Note: layer. cornerRadius, layer. borderWidth, and layer. borderColor do not Offscreen Render, because they do not need to be added to Mask.
For more information about Offscreen Render and animation optimization, watch WWDC carefully.
Refer:
- WWDC2011 #121 Understanding UIKit Rendering
- WWDC2014 #419 Advanced Graphics and Animations for iOS Apps
2.3 Design and Practice
In the above sections, we often discuss the concept of View that is not easy to understand during development. Next, I want to break away from the specific concept of View and talk about some of my practical experience in View design and development;
2.3.1 simplified and flat View hierarchy
Complex View hierarchy results not only affect rendering efficiency, but also result in code bloated, which may lead to unpredictable problems and difficult to locate. How to maintain a streamlined and flat View hierarchy? The principles are as follows:
1) Try to use native controls of the system;
For example, to implement a button for the up and down layout of an icon and title, many people use a view that contains a UIButton and a UILabel. In fact, the more recommended method is to adjust the contentInset/titleInset/imageInset parameters of UIButon to achieve this effect, which is very simple and has the display methods and features of the title on UIButton, for example, you can set a highlighted color;
Another example is a rolling interface with a complex layout structure. Some developers may think that using UITableView/UICollectionView is complicated, and some effects may not be achieved, they use their basic class UIScrollView to implement it. They build a set of wheels and the code may become very complicated. In fact, based on my experience, you can use UITableView or UICollectionView to override or adjust internal attributes. After all, UITableView/UICollectionView is a subclass of UIScrollView, and its functions are not reduced, but more powerful, we can also use the existing data source and delegate mechanisms to achieve design decoupling.
Other common examples include UINavigationBar, UITabBar, and UIToolBar;
2) reasonably Add/delete dynamic views;
Some views are dynamic, that is, occasionally displayed and occasionally hidden. This type of View can be added, deleted, or displayed or hidden. There is no standard answer. I personally recommend adding or deleting a solution, that is, adding the solution to the corresponding ContainerView when necessary and deleting it when not needed. In this way, it can be combined with lazy loading, and the interaction between two dynamic views can also be avoided, such as TableFooterView or incorrect loading of View. However, this is not the only method. If the View level of the dynamic View is relatively simple and animations are required for dynamic display, the display/hide method is also a good solution.
2.3.2 general controls;
Every programmer can build his own code library. Similarly, every mobile development programmer can build his own general control code library. Controls in this library can be self-written or excellent third-party open-source controls. Creating a control library not only avoids re-creation of the wheel, but also greatly improves our development efficiency. It is also more important to master Interface Design decoupling in application, transformation, and reconstruction, knowledge and experience in architecture.
The UI design, interaction, layout, and color of each App are often very different, but they are always different from the mobile App category, which determines that they will maintain consistency in the interaction of some general controls, this allows users to easily and quickly get started with mobile apps based on their experience. This is the mobility of apps. Therefore, the applicable scenarios of general controls are often "generic. For example, pull-down refresh, load more, Tab Bar, Tips prompt, loading error, and re-load. When using these controls in new apps or functional modules, you will think about how to make the controls more universal, that is, they do not affect the old logic and can be applied to new requirements, this is a good exercise for the architectural design of the interface.
2.3.3 reasonably use VC to replace the complex View combination interface;
During interface development, we often encounter complex interfaces, such as multi-page interfaces and multiple la s for displaying the homepage of multiple businesses, however, many developers have written a large View and complex logic code for the beginner's habit of "one screen is a VC, this piece of code is likely to become a restricted area where no one dares to move. A single VC can manage multiple vcpus. Therefore, using VC to replace View for complex interface combination can not only split complex interfaces into smaller granularities, but also divide logical code in a reasonable and synchronous manner, it is easy to maintain and reconstruct. Based on the VC Mechanism, it can also manage the dynamic loading of views and data.
The discussion about light VC in the next chapter is an extension of this section.
3. ViewController
The iOS interface mechanism has been discussed in the previous section about View. This section focuses on the design issues and basic specifications in the process of writing interfaces;
ViewController is a very important concept in iOS. It is the most common module for us to deal with in the development interface, and its role in an App, view Controller Programming Guide for iOS has a clear and accurate description:
1) View Management: Manages views;
2) Data discovery alling: manages Data;
3) User Interactions: responds to User interaction;
4) Resource Management: manages resources;
5) Adaptivity: adapt to changes in screen sizes and spaces;
As you can see, ViewController has too many things to do, which leads to problems such as code expansion and logic confusion. According to personal experience, there are more than 500 lines of valid code for a ViewController class, this ViewController will become difficult to maintain, but in fact, during the development process, we often encounter 1 K lines or even 2 ~ 3 K rows of ViewController class; When a ViewController class reaches 2 ~ 3 K lines means that other developers take over this module to modify things. They can no longer locate the code by scrolling, but can only search for things;
Therefore, during interface development, ViewController needs to pay special attention to the module design and split different modules according to logic, that is, decoupling, and prevent code expansion of the ViewController module. This is the concept of light VC;
3.1 light VC
Light VC is a term that has been very popular for the past two years. Now it seems to have become an industry standard or convention. As mentioned above, if there are more than 500 lines of valid code for a VC class, it indicates that the class becomes bloated and difficult to maintain. When there are 800 lines, you can only search for the code, reconstruction is imperative;
For light VC, the first chapter of objc. io # Issue 1: Lighter View Controllers, which demonstrates the importance of this concept. Mastering the concept of light VC is basically an essential skill for iOS developers to move from beginner to advanced. # Issue 1: Lighter View Controllers describes several common methods to build light VC:
1) Remove complex interfaces such as data sources from VC;
2) abstract the business logic code to the Model layer;
3) abstract complex views into independent classes;
4) use the Containment feature of VC to strip the interface module logically separated from a VC into multiple sub-VC;
To design a reasonable and easy-to-understand and maintain light VC structure, you need to master the knowledge of light VC and have some practical experience. In the following cases, you can consider designing a VC or re-constructing more types of light VC structures for more modules:
1) As mentioned above, the Code exceeds 500 rows;
2) View data sources in VC come from multiple different places;
3) There are multiple complex views in the VC, And it is complicated to display the data entity classes;
In short, when you feel that your VC has become bloated, you can try the practices of light VC to gain practical gains.
3.2 VC Design
VC focuses more on design and management than View focuses on layout and display. This section uses an example to briefly introduce the VC design in a complete App.
Let's take a look at a common UI Structure Design Example:
This figure should be very easy to understand: the bottom is a slide drawer control, which contains the TabBarController for App content display and the configured VC; the sub-Item VC of TabBarController contains the List VC of the corresponding business. Click List VC to enter the details View. Some details VC uses WebViewController for content display. It's very simple, isn't it? Next we will explain the design insights:
1)Root ViewControllerIs the root VC of the Window in the entire App, which is the same as the VC of the App, that is, the RootViewController of the Window is unique and always exists, to switch the scenario, use this Root VC to control the sub-VC switch (common in scenarios: the application that requires strong logon, that is, the login before use. After Successful Logon, switch from the logon interface to the main interface, then, both the logon VC and the main interface VC should be the sub-vc of the Root VC, which is controlled by the Root VC to switch ). This RootViewController is recommended as a UINavigationController to ensure sufficient scalability and provide richer interface interaction options. The life cycle of this Root VC is the same as that of the App. In this way, some sudden and flexible branch interfaces can be displayed on the Root VC, such as the Global Loading prompt and branch adjustment of OpenURL;
2)Main ViewController: The main interface is the root interface of the main business display interface. The VC and RootVC functions will easily overlap, but it should be noted that the VC does not exist all the time, but when switching to some specific branches, the VC will be removed from the Root VC. For example, in the preceding strong logon App, the logon interface and the main interface will need to be switched. In addition, the VC isolates the VC and Root VC of the main business display interface, facilitating the revision and Reconstruction of the overall interface style of the App. For example, if a combination of Slide drawers and TabBar is displayed, remove the slide drawer in the next version. You only need to use TabBar to replace the position of DrawerMenu VC in Main VC, the interface (such as Push) displayed by other branches in RootVC is not affected ).
3)TabBarItem ViewController: As the sub-Item vc of the TabBar Controller, it is usually designed as NavigationController to manage the VC stacks in each TabBarItem. Note: If you need to hide the TabBar when pushing to the level-2 interface (Detail VC), you only need to set the level-2 VChidesBottomBarWhenPushed = true
If you want to control the TabBar more flexibly, such as displaying the TabBar when entering the third-level page (this scenario should be rare), or your TabBar is custom, refer to an open-source control MZNavTab I wrote;
The UI structure shown in this section is a very general UI structure. More than 60% of apps on the market, except for games, share similar UI interactions (statistics come from personal mobile phones ), if your UI interaction is similar to this and your UI structure is messy, try this UI structure design.
4. MVC, MVP, MVVM
MVC:
MVP:
MVVM:
Figure Note: dotted Arrow: indicates the non-strong dependency between the two. For example, in the MVC diagram, View and Model are generally not directly related.
Dotted rectangle: indicates the implicit existence of the module in the corresponding architecture design. That is, this role does not exist in the general architecture, but is based on the iOS platform, which is an indispensable part;
This article does not describe the concepts of MVC, MVP, and MVVM general architecture design patterns here, the above three figures can clearly compare the differences between the three. It may be different from what you see on the Internet, because the above three figures are more based on the iOS platform.
4.1 MVC
The MVC design pattern diagram we first saw may be like this:
Reference from [MSDN # ASP. NET-Single-Page Applications: Build Modern, Responsive Web Apps with ASP. NET (https://msdn.microsoft.com/en-us/magazine/dn463786.aspx)
The MVC design pattern officially provided by Apple is as follows:
Which image is the real MVC? My answer is: yes.
MVC has been applied to various application development fields since it was proposed by the Xerox Parker lab: MVC can be used for Web apps, and MVC can also be used for iOS/Android/Windows client applications, the Web Front-end is also using MVC, and so on; these almost cover our common development fields, so MVC has actually surpassed his original design, MVC can be applied to all applications involving presentation, but different platforms are slightly different in design. MVP and MVVM are just derivative variants of MVC. Apart from the two, there are also HMVC and MVA which we have never seen before.
4.2 Model Layer
Before discussing MVP and MVVM, I want to clarify a frequently misunderstood concept: Model. Because the term "Model" is too generic, such as the data Model and database Model, this leads to a difference in understanding the concept of "Model". Simply put, the concept is compromised. Aside from others, let's look at common definitions:
Definition of Wikipedia:
The central component of MVC, the model, captures the behavior of the application in terms of its problem domain, independent of the user interface.[11] The model directly manages the data, logic and rules of the application.
Definitions in MSDN (https://msdn.microsoft.com/en-us/library/ff649643.aspx):
Model. The model manages the behavior and data of the application domain, responds to requests for information about its state (usually from the view), and responds to instructions to change state (usually from the controller).
The above two definitions are basically the same: Model, which manages the behavior and data of the application.
Let's take a look.Definition of Model-View-Controller in Apple Official Document:
Model ObjectsModel objects encapsulate the data specific to an application and define the logic and computation that manipulate and process that data. For example, a model object might represent a character in a game or a contact in an address book. A model object can have to-one and to-many relationships with other model objects, and so sometimes the model layer of an application effectively is one or more object graphs. Much of the data that is part of the persistent state of the application (whether that persistent state is stored in files or databases) should reside in the model objects after the data is loaded into the application. Because model objects represent knowledge and expertise related to a specific problem domain, they can be reused in similar problem domains. Ideally, a model object should have no explicit connection to the view objects that present its data and allow users to edit that data—it should not be concerned with user-interface and presentation issues.Communication: User actions in the view layer that create or modify data are communicated through a controller object and result in the creation or updating of a model object. When a model object changes (for example, new data is received over a network connection), it notifies a controller object, which updates the appropriate view objects.
Although Apple's official documentation defines the ModelObjectsBut it encapsulates data and manages logical computing related to data;
Therefore, we need to clarify the concept that in the MVC design mode, Model is a Layer, not just a Data Model class. Generally, the Model Layer includes the data Model and the logic computing related to managing the data, such as local data changes, data caching, and network request data. For this question, you can also refer to this article: about the organization and calling scheme of the view layer in iOS application architecture. However, it should be noted that this article is more inclined to consider the definition of the Model from the Model Object, because the Model example in it is to expand the business interface from the data Model; I am more inclined to think about the Model from the Model Layer, that is, the Model is not limited to the data Model, it can be Data Management (various managers), Request queue management, and so on.
4.3 MVP VS MVVM
The previous article "about the organization and calling scheme of the view Layer in iOS application architecture" on the Model Layer discussed MVC and MVVM in great detail, this is a very good article. We recommend that you read this article. Here we will talk about MVP and why I prefer to use MVP as the design framework in App architecture design.
Let's review the MVP and MVVM images presented at the beginning of this chapter. What is the difference between them?
Mvvm vm (View Model) to V (View), more than mvp p (Presenter) to V (View), additional data binding. That is
MVP: it is a variant of MVC. The definitions of Model and View are consistent with those of MVC. The difference is that MVC Controller manages the interaction between a group of models and views and is a manager; the Presenter is the connector between the Model and the View. It provides formatted Model data for the View of a specific module and reports the behavior of the View to the Model. Therefore, the Controller in MVC generally manages one or more models and one or more views, while the Presenter is a one-to-one M-P-V with finer granularity and better decoupling.
From the definition of MVP, you will find that MVP and MVVM are extremely similar. The roles played by Presenter and View Model are basically the same, except for the binding mechanism mentioned above. However, the binding mechanism has obvious advantages: automatic connection to views and models, and obvious disadvantages-higher Coupling Degree and more complex code logic; but what makes people lament the impermanence of fate is that MVVM is popular on the iOS platform with ReativeCocoa, and few MVPs are mentioned on the iOS platform, the Android platform has almost become a standard (Android5.0 introduces data binding support, and MVVM will have a new development on the Android platform ).
Why do I prefer MVP? However, compared with the convenience of MVVM two-way binding, I hope that my App design will be more flexible and scalable. There is no perfect architecture design model. It is only applicable to your App business scenarios and the design model of the team. For example, the data logic is not complex and focuses more on visual display applications. The original MVC is often the optimal solution. All The variants derived from MVC are nothing more than Solve The Problem.
4.4 Architecture Design Model Application
MVC, MVP, and MVVM are the patterns that guide us in architecture design, but they are not exactly the same. In practical applications, there will always be different understandings of these design patterns, make necessary adjustments according to the project requirements. More importantly, in our App architecture design, it is only necessary to handle the relationship between Model-View-Controller, the main challenge lies in the complex business logic and scenarios, which reflects the capabilities of an architect.
The discussion on the practices of MVC and MVVM in an article written by Tang Qiao not long ago should reflect the mainstream architecture ideas of mobile terminals.Network request layer, ViewModel layer, Service layer, Storage layer, and other classes
The extraction design determines the advantages and disadvantages of an App architecture design.
For architecture design, I am going to discuss it in depth in the next article based on my experience in iOS/Android, and provide my own design examples for your reference. Here we will first throw out several of the most frequently thought points in architecture design as the reference of the next article:
1) The architecture is for decoupling. The looser coupling represents the more layers, but human thinking is always more willing to accept straight-line thinking. How can this conflict be solved?
2) In an App, a unified (Consistent) architecture design makes the logic code more robust and facilitates communication between team members and project maintenance, but how can we solve the conflict between it and flexibility?
3) Does the architecture design only contain logical layers? Do I need to design data streams and multithreading?
4) several principles in the design pattern;
5. Summary
The above four chapters start with the overall UI, analyze several important mechanisms of UIView, and then discuss how to make good use of the important management roles in the UI of VC, finally, I will talk about the similarities and differences between MVC, MVVM, and MVP architecture design patterns and practical applications. I hope we can get rid of them after paying attention to the specific implementation, looking down at the core of our App development.
Refer: