应用内集成插件设置项- iPhone XS
这个步骤其实没有什么特别值得说的,因为这完全就是正向的内容,我相信只要学过OC和iOS的开发的,对他们来说都是非常熟悉且简单的东西。我是没有学过iOS开发甚至是OC语言的,那么当我有这个需求的时候,我做了些什么呢?
- 研究了半天,噢要在tableview上做文章,之后打开bilibili,搜索iOS开发,强行逼自己看了一天的tableview教程视频。
- 有了最最最基本的知识后,还差点东西,因为让你用xcode做一个tableview界面出来,简单啊,拖个tableview出来,就那几个方法,写一写就好了。但这里是逆向,是改别人的界面,你拿什么拖?hook哪个类?什么方法?
那么根据tableview的基本写法,要确定的有如下几个基本方法:
- 有几组- (long long)numberOfSectionsInTableView:(UITableView *)tableView
- 每组有多少行- (long long)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
- 每行要显示的内容是什么- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
- cell的点击事件- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(id)indexPath
上面这几个是一般是必须要hook的方法,那么还剩下一个问题,hook哪个类? 这个问题比较容易,因为正向开发者们会在什么类里面编写上面这四个方法?
- 当然是遵守UITableViewDataSource协议的类里面
这就可以通过lookin工具,在界面的tableview中打开控制台,输入dataSource,查看其数据源在哪个类中即可
在今日头条7.0.9版本中,”我的“界面的数据源类为TTProfileViewController
那么代码为:
@interface TTProfileFunctionCell : UITableViewCell
@end
@class TTProfileFunctionCell;
在最后一行增加一组,该组只包含一行内容
%hook TTProfileViewController
// //有几组
– (long long)numberOfSectionsInTableView:(UITableView *)tableView
{
return %orig+1; //在原来的基础上增加一组
}
//每组有多少行
– (long long)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(section == [self numberOfSectionsInTableView:tableView] – 1)
return 1; //组号是从0开始计数的,第十组的组号当然是九
else
return %orig;
}
根据正向的知识,创建cell一般是这样的:
static NSString *ID = @"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if(!cell)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
但最好不要直接用UITableViewCell来创建,而是用和原生一样的cell类来创建,好处就是兼容性强,不容易崩溃,更加美观。这里的tableviewcell叫做TTProfileFunctionCell(看最上面的截图)
//每行要显示的内容是什么
– (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([indexPath section] != [self numberOfSectionsInTableView:tableView] – 1)
return %orig;
else
{
static NSString *ID = @"qscell";
TTProfileFunctionCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if(!cell)
cell = [[%c(TTProfileFunctionCell) alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
UIView *tempView = [[UIView alloc] init];
tempView.backgroundColor = [UIColor whiteColor];
[cell setBackgroundView:tempView];
cell.textLabel.text = @"清爽今日头条";
if([appVersion isEqualToString:@"7.0.9"])
cell.textLabel.font = [UIFont systemFontOfSize:16];
else
cell.textLabel.font = [UIFont boldSystemFontOfSize:16]; //新版头条的功能选项就是加粗的
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
}
点击cell,cell要响应你的点击,需要hook点击事件的代理方法。这里我自己以纯代码的方式写了一个ViewController,当点击这个cell的时候,转移至这个view
//点击cell的事件
– (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(id)indexPath
{
if ([indexPath section] != [self numberOfSectionsInTableView:tableView] – 1)
{
%orig;
return;
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
ViewController *vc = [[ViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
}
– (double)tableView:(id)arg1 heightForRowAtIndexPath:(id)arg2
{
if ([arg2 section] != [self numberOfSectionsInTableView:arg1] – 1)
return %orig;
return 44; //旧版头条不需要返回高度,新版由于默认高度问题,必须给一个高度,否则不显示
}
%end