What kind of abnormality appears under what circumstances?

A few months ago, I tried to encapsulate a wheel imitating the effect of QQ drawer. Compared with the current common drawer frame, it has obvious advantages, and more people are using it slowly. Now it is basically stable. If you are interested you can open 🔗 one line of code to integrate 0 coupled side slide drawer for a look. This problem is found on this basis (search baidu, Google did not find the corresponding solution), the anomaly is shown in the figure:

Some people say, oh, I don’t use your frame, it’s not my business, don’t look. 😭 I still suggest that you take a look, encounter this kind of Internet can not find the answer to the problem, we should how to solve him.

How to solve the problem

1. Locate the problem

In this case, of course, the first is where the positioning problem appears. If the problem cannot be located, then even Google does not know from which aspect Google.

  • First I took a close look at the code I had written to see if it was because I had done something stupid during the animation.
  • Then comment out the key suspicious areas of the code that you think might be causing the situation and see if it improves.

Code do not have what problem, found by a series of screening, and this will only under iOS11 and zoom, when in order to confirm your thoughts, I built a test project, only to interface to zoom in, respectively under iOS10 and iOS11 test (in order to prove this is apple’s own problem), the test program is very simple, The touchBeagn test results are as follows:

2, think of your own solutions + Google \ Baidu

When we know this problem is about what scene appears, we can first think about whether there is a good solution, and then look for the relevant solution on the Internet. Unless you already have experience or are very confident, even if you do know how to solve the problem, I actually recommend that you search for other people’s solutions on the Internet to make it clearer.

Then I couldn’t think of a good solution. Google Baidu didn’t find the corresponding case for an afternoon. There were so few cases like this that I even searched iOS11 Navigation and iOS11 tabbarController on StackFlow. I’ve been through all the search questions and none of them are relevant. Eventually I gave up and decided to try and solve it myself.

3. Do it yourself

Speaking of solving this problem on your own, what would you do? Tell me my way

3.1 Master some basic knowledge

Since it’s only in iOS11, the first thing I want to know is what’s going on with the navigation bar in iOS11, so I went online and read some good articles about the iOS11 update to understand what’s going on with the navigation bar in iOS11? (although there is no answer to our question, but we are very necessary to understand the basic things to solve the problem, which will make you take a lot of detours) specific adjustments to do here will not say, search a lot of ~

3.2 Locate the problem and try again

After mastering some basic knowledge, I began to try to find a solution. First, I analyzed the interface level. The interface level is shown in the following figure, with the view selected by my mouse in light blue:

3.2 Carefully identify the problem!

Sure enough, the evil way is always treacherous, we still seriously to solve it, we first compare iOS11, under normal circumstances the height of the navigation bar subview and in the height of the navigation bar after scaling, and then compare the layout of the navigation bar subview in iOS10 after scaling, And then decide exactly what to change. First of all, let’s study the hierarchy of the navigation bar subview in iOS11:

Under normal circumstances, what we see behind the 20 pixels of the status bar is the _UIBarBackgroud layer, which is very important.

The layout of the main interface will be abnormal after zooming:

So we find that _UIBarBackgroud starts at 0 and is only 44 in height, which is obviously different from the normal situation, so we can’t see _UIBarBackgroud from the position of the status bar, so the interface display is abnormal

Although we can estimate the impact of this problem, but we are more safe to confirm that iOS10 after scaling the height of the layer is really 64, after all, iOS10 is normal, it has a relatively authoritative explanation.

Hey, apple dad, you have a lot of problems with iOS11

3.3 After positioning, start to solve it!

At this point, our goal is very clear, we just need to find a way to adjust the height of _UIBarBackgroud to the starting position, but ~

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    if(@available(iOS 11, *)) {// Xcode9 Xcode9 UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
        CGFloat statusH = CGRectGetHeight(statusBar.frame);
        for (UIView *view inThe self. The navigationBar. Subviews) {/ / by traversal access to _UIBarBackground layer, modify its frameif ([NSStringFromClass([view class]) isEqualToString:@"_UIBarBackground"]) { CGRect frame = view.frame; frame.size.height = 44 + statusH; frame.origin.y = -statusH; view.frame = frame; }}}}Copy the code

It’s done, everyone is happy to run our test program, it is still an egg. It didn’t work, so… It helped me to recall the problem of browsing stackflow at the beginning. I clearly remembered that the height of the customized navigation bar could not be changed, and the solution mentioned that constraints should be used to change it, so I chose to change it with constraints. I added the code of constraints to the above code. Of course, we won’t be able to use the framework for navigation any more, we’ll have to rely on apple’s code.

NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeHeight RelatedBy: NSLayoutRelationEqual toItem: nil attribute: NSLayoutAttributeNotAnAttribute multiplier: 0.0 constant: 44 + statusH]; [view addConstraint:heightConstraint];Copy the code

Then. Run. Not only did they find no use for eggs, they gave me a warning about this restriction:

/ / this has four levels of priority, here don't do was introduced in detail, can search on the net heightConstraint. Priority = UILayoutPriorityDefaultHigh;Copy the code

Then the ⚠️ warning is gone, but still no eggs… What’s going on? I did everything I was told to do and made sure the code worked. You can’t even change the height? So I went crazy! I’ve pasted this code inside viewWillLayoutSubviews, ViewWillAppear, ViewDidAppear, ViewDidLoad. After running.. Amazing, TM is normal?? A hundred more excuse me?? Let me show you how I feel

So I started doing the hard work of removing unnecessary code and running it as I went along, eventually preserving some of the code inside the Two methods in the NavigationController class so that it was all right. The code is as follows:

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];
//    return;
    if(@available(iOS 11, *)) {// Xcode9 Xcode9 UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
        CGFloat statusH = CGRectGetHeight(statusBar.frame);
        for (UIView *view in self.navigationBar.subviews) {
            if ([NSStringFromClass([view class]) isEqualToString:@"_UIBarBackground"]) { NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute Multiplier: 0.0 constant: 44 + statusH]; heightConstraint.priority = UILayoutPriorityDefaultHigh; [view addConstraint:heightConstraint]; } } } } - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews];if(@available(iOS 11, *)) {// Xcode9 Xcode9 UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
        CGFloat statusH = CGRectGetHeight(statusBar.frame);
        for (UIView *view inThe self. The navigationBar. Subviews) {/ / by traversal access to _UIBarBackground layerif ([NSStringFromClass([view class]) isEqualToString:@"_UIBarBackground"]) { CGRect frame = view.frame; frame.size.height = 44 + statusH; frame.origin.y = -statusH; view.frame = frame; }}}}Copy the code

Add constraints to viewWillLayoutSubviews and viewDidLayoutSubviews respectively and change the frame. Note: swapping methods or writing code together doesn’t work, it only works! Why? I don’t know. I tried it out.

3.4 Result after solution!

3.5 Other Problems

In addition, we found that the tabbar height of iPhoneX would also decrease when the interface was shrunk, so we adjusted the tabbar height using the same idea. In the custom tabbarController, the code is as follows:

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    if(! iPhoneX)return;
    CGRect frame = self.tabBar.frame;
    CGFloat h = 83 - frame.size.height;
    frame.size.height += h;
    frame.origin.y -= h;
    self.tabBar.frame = frame;
}
Copy the code

4. How do we solve this problem using our framework?

4 this section is to my classmates care about most of the issue, after all the previous yapping useless talk a lot of no dice. Because our demo is a little different from the newly built test project, I integrated the framework in the demo project slightly, and the solution is as follows:

  • The solution to the 20-pixel black bar above the NavigationBar is in the viewDidAppear method of the NavigationController, If the entire navigation bar color slants black will try tabbarController. The backgroundColor = [UIColor whiteColor]; Set the background to white.
  • IPhoneX tabbar height change problem, TabbarController class viewDidAppear, viewDidLayoutSubviews these two methods.

Finally, a solution is provided to solve the problem of the 20 pixel black bar on the navigationbar when zooming. This is found by my accidental test, and it is also the most simple one. NavigationBar BackgroundImage = navigationBar BackgroundImage

UINavigationBar *naviBar = [UINavigationBar appearance];
[naviBar setBackgroundImage:[UIImage imageNamed:@"nav_bg"] forBarMetrics:UIBarMetricsDefault];
Copy the code

The navigation bar of Demo is white, and nav_bg is also a white figure. Once the background image is set, zooming should not be a problem. You u can run my demo and try both. Of course the last one is the easiest.

conclusion

From the above case, we know that to solve a problem, if there are two cases of normal and abnormal, it is best to compare the differences between the two. For example, in normal development, the previous version is normal and the new version is abnormal. In troubleshooting, we can also compare the two to obtain the solution, and shield some suspicious code and run it to see if it is abnormal caused by the suspicious code. All these are good ways to help us locate the problem.

Of course, most developers do, and I’m here to talk about it. The e main reason is that there are too few people to meet the problems mentioned in this article. After reading something, people may say, Oh my God, it is useless, but I may never have this situation in my life. Ha ha

And then finally, if you want to ask me, why do I have to do it in this method and not in this method? So I will tell you: I blind JB try, try out 😂…… So try more, try not to get pregnant.

One last wave of ads, if your project requires a drawer slide feature, welcome to my wheels

A line of code to achieve 0 coupling side slide drawer

After all, for a responsible man like me, who wrote an article to solve an issue of some children’s shoes, you are still worth a look at 😂. Ps: : In fact, there is no relationship with the responsible egg, because every issue is an opportunity for me to improve, so you help me to improve, I help you to ease, mutual cooperation 🤝 each take what he needs 😄 this is the truth of the survival of this society.