背景
因业务发展需要,在新版本的Match问答中,我们决定加入更多的社交元素,方便大家互相勾搭和交流,更多地展现自己的学习日常和个性,在原有版本的基础上计入了动态和个人主页两个模块,其中个人主页又分为第一人称视图和第三人称视图。本文是我在春节假期期间实现这两个模块的一点小心得。
期间参考了大量开源项目的已有代码,进行了借鉴和向Swift 4.2的改写,在此表示感谢,开源项目不完整列表见文末附录。
用户自己的个人主页视图
布局
个人主页视图借鉴了最右这款非常受欢迎的应用,只不过上方的布局稍有不同。其实不止是最右,抖音、微博、知乎等App都有着非常类似的个人主页。
Match与最右的个人主页对比
整个个人主页可分为两部分,第一部分是上方的头像、昵称、性别、个性签名、背景图片的区域;第二部分是下方的配置项,定制化的TableView。
头像外面加了一圈白色的圆,可以更突出头像部分,实现也比较简单,显式指定头像所属imageView的layer的borderWidth和borderColor即可,当然前提是已经将头像裁剪为圆形。
Tableview的分割线起始位置的定制:
|
|
比起其他应用,我还有一个功能没实现,那就是下拉的时候背景图片的放大。研究过OC代码后,发现这个功能也不难,主要实现方式是didscroll代理方法中监听滑动的偏移量,作为控制image的zoom倍率依据。
头图下拉放大效果
更换背景和头像事件
更换头像和背景思路是类似的,都是给一个图片增加手势事件的识别,通常有两种实现方式。第一种是比较土味的方法,给图片覆盖上一层透明的button,将button设为与图片形状一样;第二种方式是给imageView加上UITapGestureRecognizer,比较简单就不再赘述。
添加或更改图片涉及到图片拉伸的问题,因此需要进行裁剪,头像的比例是1:1,而背景图片比较复杂,为了适应各种手机型号的屏幕,宽度拉到与屏幕等宽,高度和宽度维持一个固定的宽高比,当然这对用户应该是透明的,将裁剪方式的选择权还给用户。
图片裁剪页
他人个人主页的实现
布局
社交的重要一部分是去其他人的个人主页看看,其他人的个人主页和用户自己看自己的个人主页肯定是有区别的。用户自己的主页主要是一个去各种设置的中转站,用户看别人的主页主要是看他人的头像、签名、背景、收入、问答、动态等内容。
他人个人主页视图
上半部分和个人主页是一样的设计,下半部分有不同,是一个在其他应用中很受欢迎的左右滑动的Tab,暂且将其命名为swipe view。
实现的关键点与细节
为了让用户可以右滑退出这个页面,我将下方的swipe view的左边距设为了10px,这样方便用户用手势进行退出,保留着navigation ViewController的退出方式。
这个页面的难点是嵌套scrollview的冲突处理,整个页面是被一个scrollview包裹起来的,而swipe view中也是scrollview,这里设定了上方有view的时候,使得滑动相应外层滑动事件,而当swipe view滑动至顶部的时候,将swipe view头固定于信号栏下方,此时的滑动事件相应者为swipe view中的scrollview。
去除了业务逻辑的关键代码片段 (made with Carbonize)
固定住外层scrollview的主要实现方式是设置scrollview.contentOffset.y变量,当swipe view在scrollview中的坐标位置小于某个值的时候,设定scrollview.contentOffset.y为一个定值,这样就固定住了swipe view的表头部分。注意,开始的时候我设定的是isUserInteractionEnabled属性,这样swipe内的所有内容都不能交互了,比如正常的图片也不能点开看大图了。后面改成了isScrollEnabled,这样就不影响除了滑动外的其他操作了。
不足
其实现在实现这个功能还有点美中不足,那就是固定住scrollview是一个滑动操作,而要想接着对swipe view中的scrollview进行滑动,必须再滑动一次,也就是中间必须中断一次。目前还不知道如何将一次滑动操作发给两个响应者进行处理。
朋友圈的设计与实现
微信朋友圈的点赞、留言、回复功能是很多应用都需要的功能,在实现这个功能的时候,我参考了不少优秀的blog和开源代码,并最终选中了【附录4】的OC实现进行了向Swift 4.2的改写,后面根据自己的需求进行了一些定制,主要是点击点赞和评论用户名跳转到他的个人主页。
朋友圈的两种实现方式
【附录6】里介绍了朋友圈有两种主要实现方式,第一种是将每条动态作为TableView的一个cell,然后cell内部的点赞、评论又作为一个TableView,其中点赞作为Header view,每条评论作为二级cell。布局依赖Masonry,是自动布局autolayout技术,并且依赖第三方缓存cell高度进行优化,这种实现方式作者认为代价比较高。主要是页面结构复杂,依赖第三方库Masonry,集成难度较大。
微信朋友圈的两种实现思路
方式二是一个tableView,cell用来展示评论数据,headerView用来展示头像、发布文字和时间等等,主要优化策略也是缓存cell高度,保证后续滑动tableview不会重复计算,提升流畅度,我改写的库也答题是这种思路。
点赞超链接的实现
点赞超链接主要是借助NSAttributedString/NSMutableAttributedString,让用户名高亮为蓝色,并附带上User_id的信息,统一跳转到上文实现的第三人称视图中。
一个优化过的点
朋友圈里有个点我觉得对于用户体验的提升还蛮有优化意义的,那就是防止弹出的键盘遮挡住原动态和评论,下面给出参考的实现方式,主要思路是得到当前的cell,使其滑动。
使得tableview上滑的代码(made with Carbonize)
可优化的点
可优化的点还有很多,作者也列出了一些供大家参考。
- cell复用机制+sectionView复用机制
- 将cell的高度和cell里控件的frame存在model里
- 减少cell内部控件的层级,层级不易太深
- 缩略图和大图URL(拿起大刀让后台兄弟去完成,因为后台不提供缩略图功能,朋友圈很容易内存警告)
- 图片圆角cornerRadius,缓存圆角等等
- 高度缓存(cell评论区高度+section区头高度)
- 异步加载渲染(图片+文本+view)(利用SDWebImage异步下载图片,文本和view没完成异步处理)
参考&致谢
原文作者: Chih-Hao
原文链接: http://zhihaozhang.github.io/2019/02/19/wechatMoment/
发表日期: February 19th 2019, 10:37:12 am
版权声明: 本文采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可
-
Next Post《Swift必备Tips》读书笔记
-
Previous PostGoogle Flutter Live 18笔记与观后感