网上很多Blog记录了通过改变UIScrollView的contentInset实现取消Header悬停的方法,事实证明,这种方法只适用于简单情况,而且由于它会对UIScrollView造成侵入,恢复contentInset的默认状态决不是一件容易的事情。
下面提供一种方法,可以在悬停和非悬停之间随意切换。
大概的思路是实现悬停和非悬停两种不同的Header, 在UITableView的代理方法中根据条件返回需要的Header。
非悬停的Header中的代码如下:
- (void)setFrame:(CGRect)frame {
[super setFrame:[self.tableView rectForHeaderInSection:self.section]];
}
设置Header的frame为改变之后的frame, 当Header到达顶部的时候,Header就会跟着单元内容一起滚动,不再悬停
Header对应的UITableView和Section可以通过类别提供,代码如下:
@interface UITableViewHeaderFooterView (Attribute)
@property (weak, nonatomic) UITableView *tableView;
@property (assign, nonatomic) NSUInteger section;
@end
@implementation UITableViewHeaderFooterView (Attribute)
- (void)setTableView:(UITableView *)tableView {
SEL selector = @selector(tableView);
[self willChangeValueForKey:NSStringFromSelector(selector)];
objc_setAssociatedObject(self, selector, tableView, OBJC_ASSOCIATION_ASSIGN);
[self didChangeValueForKey:NSStringFromSelector(selector)];
}
- (UITableView *)tableView {
return objc_getAssociatedObject(self, _cmd);
}
- (void)setSection:(NSUInteger)section {
SEL selector = @selector(section);
[self willChangeValueForKey:NSStringFromSelector(selector)];
objc_setAssociatedObject(self, selector, @(section), OBJC_ASSOCIATION_ASSIGN);
[self didChangeValueForKey:NSStringFromSelector(selector)];
}
- (NSUInteger)section {
return [objc_getAssociatedObject(self, _cmd) unsignedIntegerValue];
}
@end
UITableView的代理方法代码如下:
- (nullable UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
Class headerClass = self.switchView.isOn ? NonHoveringHeaderView.class : HoveringHeaderView.class;
UITableViewHeaderFooterView *header = [tableView dequeueReusableHeaderFooterViewWithIdentifier:NSStringFromClass(headerClass)];
header.tableView = tableView;
header.section = section;
header.textLabel.text = @"测试";
return header;
}
self.switchView.isOn表示决定悬停还是非悬停的条件
另外,当条件改变时别忘了调用UITableView的reloadData方法。
网友评论