tutorial on the use of Uiviewcontroller classes in IOS app development _ios

Source: Internet
Author: User

One, Introduction
as the C,controller in the MVC design pattern has been the most important role in project development, it is a bridge between view and data, through its management, the data methodically displayed on our view layer. Uiviewcontroller in iOS is one of the most basic classes in the Uikit framework. From the first UI view to the complex complete project, it is inseparable from the uiviewcontroller as the basis. Based on Uiviewcontroller encapsulation and extension, it is also able to perform various complex interface logic excellently. The purpose of this discussion is to discuss the life cycle and attribute methods of Uiviewcontroller, which often get unexpected surprises on the most basic things.

Second, the life cycle of Uiviewcontroller
to understand Uiviewcontroller, you have to find out its life cycle first. In object-oriented language, is the object, must have the life cycle, Uiviewcontroller is no exception, life cycle Management controller scope and time, also manages the scope and time of its object. First, several of the functions associated with their life cycle in Uiviewcontroller are as follows:
//类的初始化方法
+ (void)initialize;
//对象初始化方法
- (instancetype)init;
//从归档初始化
- (instancetype)initWithCoder:(NSCoder *)coder;
//加载视图
-(void)loadView;
//将要加载视图
- (void)viewDidLoad;
//将要布局子视图
-(void)viewWillLayoutSubviews;
//已经布局子视图
-(void)viewDidLayoutSubviews;
//内存警告
- (void)didReceiveMemoryWarning;
//已经展示
-(void)viewDidAppear:(BOOL)animated;
//将要展示
-(void)viewWillAppear:(BOOL)animated;
//将要消失
-(void)viewWillDisappear:(BOOL)animated;
//已经消失
-(void)viewDidDisappear:(BOOL)animated;
//被释放
-(void)dealloc;
above so many functions, at first glance what a complex, in fact the relationship what is clear, in addition to initialize,init and Initwithcoder not exist in all objects of the declaration cycle, Other functions are called sequentially in the Uiviewcontroller declaration cycle. So what is the exact sequence of calls, the best way is to practice, through the number of printing, the results are as follows:

This is a viewcontroller complete declaration cycle, in fact there are a lot of places we need to pay attention to:
The 1:initialize function does not call every time the object is created, only when the object is first created, do some preparation of the class, To create the object of this class again, the Initalize method will not be invoked, and for subclasses of this class, if the Initialize method is implemented, the first time the subclass creates the object, it calls its own Initalize method, which is not invoked, if not implemented, Then its parent class will call its own initialize method again, and it will not be called again. So, if we have some global variables associated with this, we can initialize them here. The
2:init method is similar to the Initcoder method, except that the invoked environment is not the same, and if initialized with code, invoke init, initialize from nib file or archive, and invoke Initcoder. The
3:loadview method is the starting method to start loading the view, unless it is called manually, and no special case will be invoked only once in the Viewcontroller lifecycle. The
4:viewdidload method is our most commonly used method, and the initialization of the member objects and variables in the class is placed in this method, which is only called once when the class is created, regardless of the display or disappearance of the view.
5:viewwillappear: Called when the view will be displayed.
6:viewwilllayoutsubviews: Called after Viewwillappear, which will be laid out for the child view.
7:viewdidlayoutsubviews: The child view has been layout completed.
8:viewdidappare: Called when the view finishes displaying.
9:viewwilldisappear: Called when the view will disappear.
10:viewdiddisappear: Called when the view has disappeared. Called when the
11:dealloc:controller is released.
Note: After testing, the controller loaded from the nib file, as long as it is not released, calls the Layoutsubviews method every time viewwillappare. Sometimes the layoutsubviews is called once after viewdidappare, and the emphasis is on loading from the code only once, after the start of the call, so note that it is dangerous to write related layout code in Layoutsubviews.

Third, the transfer value trap of Uiviewcontroller instance loaded from storyboard
we know that when we load Viewcontroller from storyboard, the view we drag in controller can be initialized, and there's one thing we need to be aware of, if we need to send a value to the controller view. , the view has not been initialized to create the controller in the following way:
ViewController2 * viewController2 = [[UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"ViewController2"];
we can pull a label in the ViewController2 's storyboard and then associate the header file with the following print and find that when we get controller, the view object inside is not created:
ViewController2 * viewController2 = [[UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"ViewController2"];
    NSLog(@"%@",viewController2.label);
    [self presentViewController:viewController2 animated:YES completion:nil];
print as follows:

As you can imagine, if we need to make some property settings on the label at this time, we must fail. It has been suggested that after the creation, manually adjust the following Loadview method, we try, the results are as follows:

As you can see, when you call Loadview manually, the label is created, but there is a more serious problem with the system not calling the Viewdidload method, which is risky because most of our initialization code is in this method, So the manual call to Loadview is a bad way, Apple document declaration for the Loadview method, we never manually call directly, then how do we implement the creation of the member object after the value set, IOS9 added a method:
- (void)loadViewIfNeeded NS_AVAILABLE_IOS(9_0);
This method is useful, calling this method creates the view and does not ignore viewdidload calls.
In IOS9, Uiviewcontroller also adds an attribute of the following Boolean value, which can be used to determine whether the view of controller has been loaded complete:
@property(nullable, nonatomic, readonly, strong) UIView *viewIfLoaded NS_AVAILABLE_IOS(9_0);

Four, Uiviewcontroller and Stroyboard correlation Mutual method
for Viewconroller, we generally have two ways to create, one is in pure code, one is associated with storyboard, in Uiviewcontroller, there are many ways to facilitate our interaction with storyboard.
1, Viewcontroller directly in the storyboard to jump the value of the transfer
in the storyboard interface jump is very convenient, we pull in the storyboard two Viewcontroller, add a button above one, click the button hold control, the mouse to the second controller, The following jump options appear:

Once we have selected one, we will establish a jump connection between the two controller. When we run the click button, it automatically jumps from the first controller to the second controller. The following methods are available in Uiviewcontroller to control whether a jump is made:
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(nullable id)sender NS_AVAILABLE_IOS(6_0);
If this method returns no, automatic jump will not be done, will be rejected, it should be noted that this method will only be invoked when the automatic jump, we manually use the code to jump storyboard in the connection relationship is not invoked, we discussed later.
After performing the above method, if you return yes, the system will also perform the following method, as before the jump preparation, we can do some value in this method, this method whether we manually jump or storyboard in the automatic jump, will be executed:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(nullable id)sender NS_AVAILABLE_IOS(5_0);
The Sugur object encapsulates the associated Viewcontroller and can be obtained using Segue.destinationviewcontroller.
Segue in storyboard, in addition to the automatic forward jump, we can also make a reverse jump, similar to pop and dismiss method, this segue is called unwind Sugue. For example, we have a controller1 and a controllert2, to use unwind segue to return 1 from 2, we need to implement the following format in 2:
- (IBAction)unwindSegueToViewController:(UIStoryboardSegue *)segue {
    NSLog(@"unwindSegueToViewController");
}
The return value in this method must be ibaction, the argument must be Uistoryboardsegue, the method name we can define ourselves, and then the exit option in the ViewController1 in storyboard, We'll find one more way to do this:

We can connect it to a button in the ViewController2:

In this way, when we click on the button in ViewController2, we will return to our first ViewController1.
Of course, in the use of unwind segue method, there will be some callback to help us jump before the setting and transfer value, Uiviewcontroller the following method will be called before the jump, return no, you can not jump:
-(BOOL)canPerformUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(id)sender{
    NSLog(@"canPerformUnwindSegueAction");
    return YES;
}
then we will execute our custom Unwindsegue method, in which we can write nothing and the pattern will jump.
2, use the code to jump storyboard in the controller
In addition to Lalacheche in the storyboard, we can jump the controller, we can also use code to jump storyboard Segue connection relationship.
To establish a segue connection between the two controllers in the storyboard, we can take a name:

In the trigger Jump method, use the following method to jump, which is the parameter ID we get Segue ID:
The - (void)performSegueWithIdentifier:(NSString *)identifier sender:(nullable id)sender NS_AVAILABLE_IOS(5_0);
following three properties we can get controller's nib filename, its storyboard and its bundle:
@property(nullable, nonatomic, readonly, copy) NSString *nibName; 
@property(nullable, nonatomic, readonly, strong) NSBundle *nibBundle;
@property(nullable, nonatomic, readonly, strong) UIStoryboard *storyboard NS_AVAILABLE_IOS(5_0);

v. Some affiliation between the Uiviewcontroller
This part of the content and methods may not be used in our contact, but in some cases, the use of these methods can greatly facilitate some of the logic.
1, Parentviewcontroller
The Uiviewcontroller encapsulates an array that can store its child viewcontroller, and the example used in the system is the navigation and Tabbar controller, which we use to directly access the controller of these parents:
@property(nullable,nonatomic,weak,readonly) UIViewController *parentViewController;
2, modal jump in the subordinate controller
When we do the controller jump, as long as the controller is not released, we can find it, using the following two methods:
//其所present的contller,比如,A和B两个controller,A跳转到B,那么A的presentedViewController就是B
@property(nullable, nonatomic,readonly) UIViewController *presentedViewController  NS_AVAILABLE_IOS(5_0);
//和上面的方法刚好相反,比如,A和B两个controller,A跳转到B,那么B的presentingViewController就是A
@property(nullable, nonatomic,readonly) UIViewController *presentingViewController NS_AVAILABLE_IOS(5_0);
Understand the above method we can know, for the reverse value of such a problem, we do not need agents, block, notice, such as the complex means, only need to get jump to its controller, directly set. For example, we need to change the color of the first interface after the second interface disappears, and only the following code is required in the second controller:
    self.presentingViewController.view.backgroundColor = [UIColor colorWithRed:arc4random()%255/255.0 green:arc4random()%255/255.0 blue:arc4random()%255/255.0 alpha:1];
    [self dismissViewControllerAnimated:YES completion:nil];

Six, Uiviewcontroller mode jump and animation effects
In pure Uiviewcontroller, we use the most of the following two methods, one forward jump, one backward return:
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^ __nullable)(void))completion NS_AVAILABLE_IOS(5_0);
- (void)dismissViewControllerAnimated: (BOOL)flag completion: (void (^ __nullable)(void))completion NS_AVAILABLE_IOS(5_0);
From the method, we can see that there is animated this parameter to choose whether there are animation effects, the default animation effect is like a drawer from the bottom of the phone screen up, of course, this effect we can set, Uiviewcontroller like the next attribute to set the animation effects:
@property(nonatomic,assign) UIModalTransitionStyle modalTransitionStyle NS_AVAILABLE_IOS(3_0);
Notice that this is going to be set to the controller you want to jump to, which is enumerated as follows:
typedef NS_ENUM(NSInteger, UIModalTransitionStyle) {
    UIModalTransitionStyleCoverVertical = 0,//默认的,从下向上覆盖
    UIModalTransitionStyleFlipHorizontal ,//水平翻转
    UIModalTransitionStyleCrossDissolve,//溶解
    UIModalTransitionStylePartialCurl ,从下向上翻页
};
In addition to the effect of the jump, there is also a property to set the pop-up controler fill effect, but this property is only valid on the pad, on the iphone is not valid, are filled to the entire screen:
@property (nonatomic,assign) uimodalpresentationstyle Modalpresentationstyle Ns_available_ios (3_2);
enumerated below
typedef ns_enum (Nsinteger, Uimodalpresentationstyle) {
Uimodalpresentationfullscreen = 0,//fills the entire screen
uimodalpresentationpagesheet,//left the status bar
uimodalpresentationformsheet,//four weeks left a darkened void
Uimodalpresentationcurrentcontext,//and the controller that jumps to it remains consistent
Uimodalpresentationcustom Ns_enum_available_ios (7_0),//Custom
Uimodalpresentationoverfullscreen Ns_enum_available_ios (8_0),
Uimodalpresentationovercurrentcontext Ns_enum_available_ios (8_0),
Uimodalpresentationpopover Ns_enum_available_ios (8_0) __tvos_prohibited,
Uimodalpresentationnone Ns_enum_available_ios (7_0) =-1,
};

Vii. Viewcontroller Display (off) other Viewcontroller
before 5.0, the corresponding method is to use the Model View Controller series method. After 5.0 the concept of Presented,prensentingviewcontroller was added, Modalviewcontroller corresponds to the Presentedviewcontroller after 5.0

FCDemoViewController *controller= [[FCDemoViewController alloc]initWithNibName:@"FCDemoViewController" bundle:nil]; 
controller.modalTransitionStyle=UIModalTransitionStyleFlipHorizontal; 
[self presentModalViewController:controller animated:YES]; 
NSLog(@"%@",self.modalViewController); 
//5.0  
[self presentViewController:controller animated:YES completion:nil]; 
NSLog(@"%@",self.presentedViewController); 
NSLog(@"%@",self.presentingViewController);  
The attribute Modalpresentationstyle has several display forms under the ipad, corresponding to different display areas. The attribute Modelltransitionstyle determines the transition form.
Close also has the corresponding method: Dismissmodalviewcontrolleranimated or iOS5.0 after the dismissviewcontrolleranimated:completion:
5.0 other changes after:
Controller can customize the collection of controller so that each controller can be a container controller.
Definespresentationcontext determines whether the current display of other controller controller provides context to Presentedviewcontroller (Modalviewcontroller If not, the value of the controller at the top level is found.
Detailed action to view the class reference.
Apple officially recommends using the Protocol to allow Controller to communicate with each other. The first way to declare a protocol and implement the Protocol in the main controller, when displaying other controller, Set the delegate=self for it. This allows the callback Presentingviewcontroller to be transferred back and forth directly to the delegate method in other controller. In this way, the reusability can be greatly enhanced. Also, the displayed controller do not have to fully know all the information and attributes that display its controller.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.