前言
很久不见,各位伙伴们,不要问我干嘛去了,我是不会告诉你们的😃,自己琢磨,废话不多说,直接切正题,应小码哥学员的要求,写了一个框架,一行代码快速集成tableView上头部视图缩放图片
,并且不会占用tableView的头部视图,无侵入性,全用runtime实现的。
如果喜欢我的文章,可以关注我微博:袁峥Seemygo
Demo简介:
- 效果图

框架使用教程:
1.将YZHeaderScaleImage导入项目或者使用cocoapods导入
2.导入#import "UIScrollView+HeaderScaleImage.h"
3.使用tableView或者scrollView
4.设置了tableView头部视图,`一定记得清空头部视图背景颜色`
- (void)viewDidLoad {
[super viewDidLoad];
// 设置tableView头部缩放图片 *一行代码就集成了*
self.tableView.yz_headerScaleImage = [UIImage imageNamed:@"header"];
// 设置tableView头部视图,必须设置头部视图背景颜色为clearColor,否则会被挡住
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 200)];
// 清空头部视图背景颜色
headerView.backgroundColor = [UIColor clearColor];
self.tableView.tableHeaderView = headerView;
}
源码
点击这下载源代码
网友评论
1.集成您这个延展会挡住 MJ 上拉刷新
2.集成您这个延展后当 push 到下一个控制器,在返回时点击任意界面会出现莫名的崩溃问题,今天测试了一天都没有找到崩溃原因,最后删除了您这个延展才不崩溃了,设置断点与打印崩溃日志也没有找出原因,还请大神给讲解下原因。
+ (void)yz_swizzleClassSelector:(SEL)origSelector swizzleSelector:(SEL)swizzleSelector{
// 添加原有方法实现为当前方法实现
BOOL isAdd = class_addMethod(self, origSelector, method_getImplementation(swizzleMethod), method_getTypeEncoding(swizzleMethod));
if (!isAdd) { // 添加方法失败,原有方法存在,直接替换
method_exchangeImplementations(origMethod, swizzleMethod);
}
这里是不是缺少了一个else {
//虽然添加成功,但是SEL*swizzle指向的也是swizzleMethod,需要让SEL*swizzle指向origMethod
class_replaceMethod(self, swizzleSelector, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
}
}
如果不需要,可以解释以下为什么吗。如果添加成功不需要将Swizzling的SEL指针指向origin的IMP吗
发生在iOS8系统上。希望早点修复
[UITableView _systemGestureStateChanged:]: message sent to deallocated instance 0x17385200
2.后来发现任何的collectionview被释放之后,点击屏幕也会crash,报
[UICollectionView _systemGestureStateChanged:]: message sent to deallocated instance 0x17385200
3.把目光放在UIScrollView上,查找UIScrollView的分类,是否有问题
4.找到 UIScrollView+HeaderScaleImage.h 注释了其中一部分代码,并把所有的引用都注释掉,依然有这个问题。
5.开始将目光放在_systemGestureStateChanged上,还有僵尸对象上,用instrument调试,依然无解。
6.六个小时过去了。
7.睡了一觉,然后又把目光放在UIScrollView上,将UIScrollView+HeaderScaleImage.h 中的代码全部注释掉了。
8.正常。感觉世界都亮了。
9.一步一步注释,排除,最后发现这个里面重写了uiscrollview的dealloc方法,导致scrollview在释放的时候无法清除自己的观察者身份,导致系统发通知的时候仍然能发到它身上。ios 9 没问题,ios8上就会直接crash。
10.将最后那个dealloc中的代码另外立出来,在controller的dealloc中主动调用这个方法,整个app没几个页面用这个,所以也并没有增加太多的工作量。
11.大哥啊..坑死了·.·|| 赶快更新一下或者说明一下,你这个会导致全局出错,不是局部。
这是什么问题?
[UIScrollView _systemGestureStateChanged:]: message sent to deallocated instance 0x170a6000
[UITableView _systemGestureStateChanged:]: message sent to deallocated instance 0x17385200
猜测:UIScrollView分类里的代码导致的,希望给出解决办法。看到消息请回复一下,非常感谢。
- (void)setYz_TableHeaderView:(UIView *)tableHeaderView
{
// 不是UITableView,就不需要做下面的事情
if (![self isMemberOfClass:[UITableView class]]) return;
// 设置tableView头部视图
[self setYz_TableHeaderView:tableHeaderView];
// 设置头部视图的位置
UITableView *tableView = (UITableView *)self;
self.yz_headerScaleImageHeight = tableView.tableHeaderView.frame.size.height;
}
峥哥,这个代码为什么打断点进不去,自己调自己不会出现循环引用吗?求解释。谢谢
```
//
// ViewController.m
// testHeader
//
// Created by 陈博文 on 16/7/30.
// Copyright © 2016年 陈博文. All rights reserved.
//
#import "ViewController.h"
#import "UIScrollView+HeaderScaleImage.h"
#import <MJRefresh.h>
@interface ViewController ()
/** tableView*/
@property (nonatomic ,weak) UITableView *tableView;
@EnD
@Implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UITableView *tableView = [[UITableView alloc]init];
tableView.frame = self.view.bounds;
[self.view addSubview:tableView];
self.tableView = tableView;
// 设置tableView头部缩放图片 *一行代码就集成了*
self.tableView.yz_headerScaleImage = [UIImage imageNamed:@"header"];
// 设置tableView头部视图,必须设置头部视图背景颜色为clearColor,否则会被挡住
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 200)];
// 清空头部视图背景颜色
headerView.backgroundColor = [UIColor clearColor];
self.tableView.tableHeaderView = headerView;
self.tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadData)];
}
- (void)loadData{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self.tableView.mj_header endRefreshing];
});
}
```