Search code examples
iosobjective-ciphoneuitableviewiphone-x

iPhone X - How are we supposed to handle the space above table section headers? It's showing through the content


I have a tableview with multiple sections and section headers for each section. As you know, section header moves with the tableview. So if there are more than one sections, the current section's header sticks to the top of the tableview while the content of that section scrolls under the header.

I am trying to figure out on how it's supposed to get adapted for the iPhone X as the space above the header is showing through the content as you notice in this screenshot. I looked at the Apple view on how to adapt for the iPhone X notch but all their examples had a search bar view on top so they never really faced this issue.

enter image description here


Solution

  • Here's what I ended up doing.

    I added a new UIView (notchFIxView) with UIVisualEffectView inside. I placed it at the very top of the view controller. This is the topmost view outside all the tableview. I pinned the top, left and right constraints to the superview (NOT the safe area).

    I pinned the bottom of this view to the top of the Safe Area.

    I added UIScrollViewDelegate protocol to the interface and following macros for iPhoneX detection:

    #define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
    #define SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width)
    #define SCREEN_HEIGHT ([[UIScreen mainScreen] bounds].size.height)
    #define SCREEN_MAX_LENGTH (MAX(SCREEN_WIDTH, SCREEN_HEIGHT))
    #define IS_IPHONE_X (IS_IPHONE && SCREEN_MAX_LENGTH == 812.0)
    

    I added a BOOL checkIfNotch; variable to my interface and initialize it in the viewDidLoad:

    checkIfNotch = IS_IPHONE_X;
    

    Then the final showing/hiding of the notchFIxView happens as follows:

    - (void)scrollViewDidScroll:(UIScrollView *)scrollView{
        if (checkIfNotch) {
            static CGFloat lastY = 0;
    
            CGFloat currentY = scrollView.contentOffset.y;
    
            if ((lastY <= tableheaderviewHeight) && (currentY > tableheaderviewHeight)) {
                NSLog(@" ******* Header view just disappeared");
    
                self.notchFIxView.hidden=NO;
                [UIView animateWithDuration:0.3 animations:^{
                    self.notchFIxView.alpha=1;
                } completion:^(BOOL finished) {
    
                }];
    
            }
    
            if ((lastY > tableheaderviewHeight) && (currentY <= tableheaderviewHeight)) {
                NSLog(@" ******* Header view just appeared");
    
                [UIView animateWithDuration:0.3 animations:^{
                    self.notchFIxView.alpha=0;
                } completion:^(BOOL finished) {
                    self.notchFIxView.hidden=YES;
                }];
            }
    
            lastY = currentY;
        }
    }
    

    After this, it looks much nicer:

    enter image description here