简体   繁体   中英

Can UITableView Section Headers be Changed when They are 'Floating'?

On iOS devices the section headers in UITableView's have a nice behavior where they stick or 'float' to the top of the screen as you scroll through a section. The section headers in my particular case are loaded from other XIB files.

Is it possible to change the section headers depending on whether or not they are currently floating? Specifically I'd like to add a small shadow to appear under the header only while it's stuck to the top of the view.

Thanks!

Here's the function I created to update whether each header has a shadow or not. All the section headers in this case are a UIView subclass ListHeader . They're retained and returned by the viewForHeaderInSection function.

- (void) updateHeaderShadows {
    int i=0;
    int sectionHeight = 0;
    int totalHeight = 0;
    UIView * sectionHeader;
    while (i<[self numberOfSectionsInTableView:self.tableView]) {
        sectionHeight = [self.tableView rectForSection:i].size.height;
        sectionHeader = [self tableView:self.tableView viewForHeaderInSection:i];
        if ([sectionHeader respondsToSelector:@selector(shadow)]) {
             if (sectionHeader.frame.origin.y == totalHeight || sectionHeader.frame.origin.y == totalHeight + sectionHeight - sectionHeader.frame.size.height) {
                 [((ListHeader *) sectionHeader).shadow setHidden:YES];
             } else {
                 [((ListHeader *) sectionHeader).shadow setHidden:NO];
             }
        }
        totalHeight += sectionHeight;
        i++;
    }
}

I haven't tested it yet, but I don't see any reason why it wouldn't be possible. Just make sure you set the right bounds (because your shadow needs to be on top of your view, not above it).

You can use the following approach:

  1. Use scrollView:didScroll: to get notified about scroll-events.
  2. In this method, check whether you need to add your shadow-view to your (floating) header-view.
  3. If so, add it. (just [view addSubview:shadowView] .) Something like CGRectMake(0.f, yourDefaultHeaderHeight, 320.f, yourShadowHeight) should be the frame of your shadowView .
  4. Now, update the bounds of view , so it can show your shadowView : CGRectMake(0.f, 0.f - yourShadowHeight, 320.f, yourDefaultHeaderHeight + 2 * yourShadowHeight) .
  5. When you find out that your header isn't floating anymore (by using scrollView:didScroll: ), remove the shadow-view.

Your headerView s bounds should be 0.f - yourShadowHeight because if you use just 0.f , it'll blur (I don't know why ...).

@Anthony Mattox answer for Swift

protocol SectionHeaderWithShadowProtocol where Self: UIView {
    var shadow: Bool { get set }
}

class SectionHeaderView: UITableViewHeaderFooterView, SectionHeaderWithShadowProtocol {
    @IBOutlet weak var shadowView: UIView!
    var shadow: Bool = false {
        didSet {
            shadowView.isHidden = shadow
        }
    }
}


func scrollViewDidScroll(_ scrollView: UIScrollView) {
    updateHeaderShadows()
}

func updateHeaderShadows() {
    var i = 0
    var sectionHeight: CGFloat = 0
    var totalHeight: CGFloat = 0
    while i < numberOfSections() {
        sectionHeight = tableView.rect(forSection: i).size.height
        if let sectionHeader = tableView.headerView(forSection: i) as? SectionHeaderWithShadowProtocol {
            if sectionHeader.frame.origin.y == totalHeight || sectionHeader.frame.origin.y == totalHeight + sectionHeight - sectionHeader.frame.size.height {
                sectionHeader.shadow = false
            } else {
                sectionHeader.shadow = true
            }
        }
        totalHeight += sectionHeight
        i += 1
    }
}

You would have to have your own UIView in the header. Then you would need a reference to it. Then hook into scrollViewWillBeginDragging: with your UIScrollViewDelegate. In that function, add the shadow to the custom view.

Hook into scrollViewDidEndDragging:willDecelerate: and remove the shadow in this function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM