高仿简书个人中心
概述
详细
一、准备工作
高仿简书个人中心上下 左右滑动页面,开始做之前,首先思路要清晰,逻辑比较繁琐。

首先看到简书个人中心页面时,我大致给他划分为4大部分:
1,首先是用户的头像
2,用户资料信息
3,三个标题(TitleView)
4,下面UITableView
因为此处有左右滑动和上下两种滑动,所以在上面的2,3,4 我们整体放在一个ScrollView上, 而1,用户头像的改变,根据ScrollView 的上下滑动 y 值对头像大小进行处理。
二、程序实现
项目中不需要配置任何东西,全都是逻辑方面的东西,只要思维逻辑清楚,我们就开始干,

在上面的项目图中可以清楚的看到,所有的View都是自定义实现的,控制控制器的大小,之前一阿里朋友告诉我,他们公司的硬性规定,无论页面实现什么功能,在控制器中的代码 不能超过300 行,能封装的尽量封装起来,不做繁琐的代码Copy。
首先看下如何自定义头像View
/** 初始化方法 * 头像图片 */ - (instancetype)initWithImage:(UIImage *)image; /** 更新头像大小 * 滚动视图 */ - (void)reloadSizeWithScrollView:(UIScrollView *)scrollView; /** * 点击头像回调 */ - (void)handleClickActionWithBlock:(ClickImageBlock)block;
头像大小的改变
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
if ([keyPath isEqualToString:ContentOffset] && object == self.scrollView) {
CGFloat offsetY = self.scrollView.contentOffset.y;
CGFloat scale = 1.0;
if (offsetY < 0) { // 放大
scale = MIN(1.5, 1 - offsetY / 300);//简书没有这个功能
} else if (offsetY > 0) { // 缩小
scale = MAX(0.40, 1 - offsetY / 300);
}
self.yourImages.transform = CGAffineTransformMakeScale(scale, scale);
CGRect frame = self.yourImages.frame;
frame.origin.y = 15;
self.yourImages.frame = frame;
}
}
自定义TitleView(要可以左右滑动,标题下方有标注)
- (void)titleButtonClicked:(UIButton *)button {
_selectedIndex = button.tag;
if (self.selectedButton) {
self.selectedButton.selected = YES;
}
button.selected = NO;
self.selectedButton = button;
if (self.buttonSelected) {
self.buttonSelected(button.tag);
}
NSString* title = self.gztitles[button.tag];
CGFloat sliderWidth = button.titleLabel.font.pointSize * title.length;
[self.sliderView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.width.mas_equalTo(sliderWidth);
make.height.mas_equalTo(2);
make.centerX.equalTo(button);
make.bottom.equalTo(self).offset(-2);
}];
[UIView animateWithDuration:0.25 animations:^{
[self layoutIfNeeded];
}];
}
- (void)setSelectedIndex:(NSInteger)selectedIndex {
_selectedIndex = selectedIndex;
UIButton* button = self.subviews[selectedIndex];
[self titleButtonClicked:button];
}
- (void)setGztitles:(NSArray *)gztitles {
[self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
_gztitles = gztitles;
CGFloat width = [UIScreen mainScreen].bounds.size.width / gztitles.count;
for ( int i = 0; i<gztitles.count; i++ ) {
UIButton* titleButton = [self titleButton:gztitles[i]];
titleButton.tag = i;
[self addSubview:titleButton];
[titleButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.bottom.equalTo(self);
make.left.equalTo(self).offset(width * i);
make.width.mas_equalTo(width);
}];
if (i != 0) {
titleButton.selected = YES;
} else {
self.selectedButton = titleButton;
}
}
UIButton *button = self.subviews[0];
NSString *title = gztitles[0];
CGFloat sliderWidth = button.titleLabel.font.pointSize * title.length;
[self addSubview:self.sliderView];
[self.sliderView mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.mas_equalTo(sliderWidth);
make.height.mas_equalTo(4);
make.centerX.equalTo(button);
make.bottom.equalTo(self).offset(-3);
}];
[self layoutIfNeeded];
}
- (UIButton *)titleButton:(NSString *)title {
UIButton* titleButton = [[UIButton alloc] init];
[titleButton addTarget:self action:@selector(titleButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
titleButton.titleLabel.font = [UIFont systemFontOfSize:15];
[titleButton setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
[titleButton setTitleColor:[UIColor grayColor] forState:UIControlStateSelected];
[titleButton setTitle:title forState:UIControlStateNormal];
return titleButton;
}
自定义的信息页面
- (void)layoutSubviews {
[super layoutSubviews];
[self addSubview:self.nameLabel];
[self addSubview:self.Address];
[self addSubview:self.infoLabel];
[self addSubview:self.editInfoButton];
}
简单的添加属性就好
UITableView的话也是简单的TableView
最后到我们的控制器页面,在这个页面我们只负责
UITableViewDelegate 的东西,数据我们都在自定义的页面处理,减少控制器页面的代码量,
在控制器中我们就是将自定义的View组合起来
首先是整体一个ScrollView 然后在其上面添加我们事先定义的所有控件。
GZContentScrollView *scrollView = [[GZContentScrollView alloc] init];
scrollView.delaysContentTouches = NO;
[self.view addSubview:scrollView];
self.scrollView = scrollView;
scrollView.pagingEnabled = YES;
scrollView.showsVerticalScrollIndicator = NO;
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.delegate = self;
scrollView.contentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width * 3, 0);
UIView *headView = [[UIView alloc] init];
headView.frame = CGRectMake(0, 0, 0, GZHeadViewHeight + GZTitleHeight);
GZTableView1 *gzTableView1 = [[GZTableView1 alloc] init];
gzTableView1.delegate = self;
gzTableView1.separatorStyle = UITableViewCellSeparatorStyleNone;
self.GZTableView1 = gzTableView1;
gzTableView1.tableHeaderView = headView;
[scrollView addSubview:gzTableView1];
[gzTableView1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(scrollView);
make.width.mas_equalTo([UIScreen mainScreen].bounds.size.width);
make.top.equalTo(self.view);
make.bottom.equalTo(self.view);
}];
GZTableView2 *gzTableView2= [[GZTableView2 alloc] init];
gzTableView2.delegate = self;
gzTableView2.separatorStyle = UITableViewCellSeparatorStyleNone;
self.GZTableView2 = gzTableView2;
gzTableView2.tableHeaderView = headView;
[scrollView addSubview:gzTableView2];
[gzTableView2 mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(scrollView).offset([UIScreen mainScreen].bounds.size.width);
make.width.equalTo(gzTableView1);
make.top.bottom.equalTo(gzTableView1);
}];
GZTableView3 *gzTableView3 = [[GZTableView3 alloc] init];
gzTableView3.delegate = self;
gzTableView3.separatorStyle = UITableViewCellSeparatorStyleNone;
self.GZTableView3 = gzTableView3;
gzTableView3.tableHeaderView = headView;
[scrollView addSubview:gzTableView3];
[gzTableView3 mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(scrollView).offset([UIScreen mainScreen].bounds.size.width * 2);
make.width.equalTo(gzTableView1);
make.top.bottom.equalTo(gzTableView1);
}];
}
头部视图添加
视图都添加完毕之后,要实现滑动事件,我们必须要进行下面的活动:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView == self.scrollView || !scrollView.window) {
return;
}
CGFloat offsetY = scrollView.contentOffset.y;
CGFloat originY = 0;
CGFloat otherOffsetY = 0;
判断ScrollView 是因为 我们这个页面有两种滑动事件
至此,简书个人中心页面的功能都已实现。
三、运行效果
运行效果如下图显示:

浙公网安备 33010602011771号