Hide the navigation bar and recreate the full-screen pop gesture design.

Source: Internet
Author: User

Hide the navigation bar and recreate the full-screen pop gesture design.

?? In actual development, when pushing to the next controller, you need to hide the tabBar at the bottom of the controller and the navigationBar at the top, the tabBar at the bottom and the navigationBar at the top must be restored. How is this function implemented? First, let's take a look at the interface before hiding tabBar and navigationBar:

1. Hide the tabBar at the bottom

?? Hiding the tabBar at the bottom is the easiest way to implement the function. Generally, we define UINavigationController to facilitate management. We only need to rewrite the pushViewController (_:, animated :) method, SetHidesBottomBarWhenPushed is set to true:

/// Intercept the system's push method override func pushViewController (_ viewController: UIViewController, animated: Bool) {// hide the tabBar at the bottom if viewControllers if it is not the root controller. count> 0 {viewController. hidesBottomBarWhenPushed = true} // restore the system's push method super. pushViewController (viewController, animated: animated )}

?? SetAfter hidesBottomBarWhenPushed is set to true, do not forget to callPushViewController (_:, animated :) method to restore system operations. Otherwise, all push operations will be damaged. Run the program to check the Interception Effect:

2. Hide the navigationBar on the top

?? When the application is pushed to the logon controller, we not only want the tabBar at the bottom to be hidden, but also the navigationBar at the top to be hidden together. Hiding the top navigationBar has a special method, andHidesBottomBarWhenPushed has the same attributes. It also belongs to the UINavigationController class. However, unlike hiding tabBar, this time we should log on to the Controller and set it instead of setting it in the Custom UINavigationController.

?? Why do I not need to set it in the Custom UINavigationController this time? This is mainly because the two have different requirements. When pushing to a sub-controller, not only does the logon Controller Interface need to hide the tabBar at the bottom, but almost all non-root sub-controllers need to hide the tabBar at the bottom. Therefore, it is very convenient to set it in the Custom UINavigationController (one setting is available everywhere ). However, hiding the top navigationBar feature is not required by all non-root controllers. The principle we follow is,Anyone who needs to hide it will set it..

?? Some controllers need to hide navigationBar, while some controllers do not. Therefore, remember to restore the Controller after it is hidden. Therefore, we need to callSetNavigationBarHidden (_:, animated :) method:

/// When the Controller's view is about to appear, call override func viewWillAppear (_ animated: Bool) {super. viewWillAppear (animated) // when pushing to the logon controller, hide the navigationBar navigationController on the top ?. SetNavigationBarHidden (true, animated: true)} // when the Controller's view is about to disappear, call override func viewWillDisappear (_ animated: Bool) {super. viewWillAppear (animated) // when the logon controller disappears, you must restore the navigation bar. Otherwise, the navigation bar of the root controller does not exist ?. SetNavigationBarHidden (false, animated: true )}

??The viewWillAppear (_ :) method is called when the Controller's view is about to appear.The viewWillDisappear (_ :) method is called when the controller is about to disappear. Run the program and check whether the navigationBar on the top is hidden as expected:

3. Rebuilding full-screen pop gestures

?? As shown in the figure above, when the application is pushed to the logon controller, the navigationBar on the top is indeed hidden. However, as you can see in the above dynamic diagram, the pop gesture that comes with the system is gone! We can no longer return to the upper-level interface through the screen slide gesture like the second dynamic image above. This is mainly because, once the navigationBar at the top of the controller is hidden, the system automatically disables the slide gesture.

?? Now, we need to make it clear whether this slide gesture belongs to the navigation controller or the logon controller? In fact, it belongs to the navigation controller (you can create a project with a navigation controller and no navigation controller for verification) and enter the header file of the UINavigationController class, the following attribute is displayed:

@available(iOS 7.0, *)open var interactivePopGestureRecognizer: UIGestureRecognizer? { get }

?? ThisThe interactivePopGestureRecognizer attribute is the result of the management controller slide, but this gesture is disabled when we hide the navigation bar on the top. In addition, this gesture is private to the system, and we cannot directly add it to the view of the navigation controller to restore the slide return. Therefore, you can write a pan gesture and add it to the view of the navigation controller:

// Create a pan gesture let panGesture = UIPanGestureRecognizer (target: system target parameter, action: System selector parameter) // Add the pan gesture to the view of the navigation controller. addGestureRecognizer (panGesture)

?? Next, you only need to set the target and action parameters. We can write these two parameters as needed. However, do not forget that the system has its own slide-returned gesture, and this gesture must contain the target and action parameters. If we try to find them, the workload will be much smaller.

?? As we said above,The interactivePopGestureRecognizer attribute manages the navigation controller's slide return function, so the target and action parameters must be related to it. Enter the header file and you can see that it isUIGestureRecognizer type, so we have reason to believe that inThe UIGestureRecognizer class must have a property associated with the target and action parameters. HoweverThis attribute is not found in the header file of UIGestureRecognizer! Is it a private attribute that is not exposed? Run the following command to print all its attribute lists:

// Use the run-time print gesture to display all the attributes var outCount: UInt32 = 0 // The number of attributes. The default value is 0 // function: class_copyIvarList (_:_:) //-parameter cls: indicates the class to be checked (that is, you need to obtain the attribute list of the class and pass in the class itself) //-parameter outCount: length of the returned value array (that is, the number of all attributes of this class) //-return value UnsafeMutablePointer  : Is an array containing the Ivar type pointer of all instance variables declared by this class. let ivarList = class_copyIvarList (UIGestureRecognizer. self, & outCount )! // Get the pointer list of all the attributes of this class // traverse all the attribute pointers of UIGestureRecognizer for I in 0 ..  

?? There are many printed items, but there is no target or action. However, there is_ Targets attributes are relatively close, so they are quite suspicious:

?? Although, in terms of naming conventions for iOS developers, attributes_ Targets is really suspicious, but no one can guarantee that there will be no second goods. Maybe they will name their cats "two dogs? Therefore, the safest way is to perform secondary verification: <喎? kf ware vc " target="_blank" class="keylink"> Vcd48y29kzt48y29kzt4nc1_kdqonc1_vy29kzt48l2nvzgu + PHByZSBjbGFzcz0 = "brush: java;"> // Obtain the value of attribute _ targets. let value = interactivepopgsturerecognizer ?. Value (forKey: "_ targets") // print this value print (value)

?? From the printed results, we can see that our conjecture is correct,_ Targets is an array. It contains the target and action we are looking:

?? Because we already know the attributesThe value corresponding to _ targets is an array object. For more convenient viewing, you can convert it to an array of objects before printing:

// Use KVC to obtain the value of the attribute _ targets: guard let targets = interactivepopgsturerecognizer ?. Value (forKey: "_ targets")? [NSObject] else {return} // print the targets value print ("targets: \ (targets )")

?? Click print to view the attributes.The value corresponding to _ targets is an array with only one element, and this element is still a tuples:

?? Get parameters after everything is understoodTarget andThe work of action is extremely simple, so adding the panGesture gesture is a successful task:

// Use KVC to obtain the value of the attribute _ targets: guard let targets = interactivepopgsturerecognizer ?. Value (forKey: "_ targets")? [NSObject] else {return} // retrieve the unique element of targets, let element = targets [0] // use KVC to obtain the value of let target = element corresponding to the target parameter. value (forKey: "target") // encapsulate handleNavigationTransition: into actionlet action = Selector ("handleNavigationTransition :")) // pass the obtained target and packaged action as parameters, and create the panGesture gesture let panGesture = UIPanGestureRecognizer (target: target, action: action) // Add the panGesture gesture to the view of the navigation controller. addGestureRecognizer (panGesture)

?? Finally, run the program and you will see the regression of the long-overdue pop function!


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.