所闻所获6:meditashayne项目总结

  项目源码下载地址:

  https://github.com/ShayneYeorg/Meditashayne

1、首先一开始设计这个App的时候,我就希望它能比系统自带的备忘录更方便:比如备忘录需要手动去点击一下保存,我希望我的App可以省略掉点击保存这一步,只需要退出随笔的详情页面便可自动保存内容。

  那么退出详情页面有两种方式:左上角的“返回”以及UIViewController自带的左划退出。

  (1)、在处理完“返回”按钮之后,发现了第一个问题:自定义NavigationController上的BarButtonItem后,UIViewController自带的左划手势失效了。

  最后处理方法是在MDSNavigationController(自定义的NavigationController)里增加以下方法,并在viewDidLoad中调用,左划手势重新生效:

  (2)、考虑到刚进入随笔详情页面的时候,页面里还未有内容,这时就不应该存储没有内容的随笔,即是不能允许使用“返回”按钮或左划返回上一页面。

  然后使用了以下方法来灵活地开启或关闭当前控制器的左划功能

  (3)、然后发现把退出和保存两个功能捆绑在一起这种处理方式存在问题:

  如果我是不小心点到“新建”按钮进入新建随笔详情页面的,那么根据(2)我需要填写点内容才能退出,而退出的时候我填写的这些内容会被自动保存,可是我一开始是误点进来的,我并不想保存任何内容的,这就出现了矛盾。

  或者当我点击某篇随笔进入编辑随笔详情页面并做了改动之后,如果我想放弃这些改动,我发现此时就找不到方法来放弃了,直接退出会把我所做的改动保存起来,这也是一样的矛盾。

  即是说,当把退出和保存两个功能捆绑在一起之后,App便丧失了“退出但不保存”的功能。虽然可以通过退出的时候弹框提示是否要保存来处理,但是这样的话就会使得退出操作更繁琐,与设计这个功能时为了操作更简便的初衷相违背了。

  基于以上考虑,最终去除了“退出同时保存”的功能,使用了在NavigationController上的按钮来进行保存。

2、关于上拉加载更多控件,这个控件仿写公司项目使用的上拉加载更多控件的,使用的时候需要注意:在ScrollView或者TableView有数据之后,即是有了contentSize.height之后,需要再去调用一下控件的setState方法(直接或间接调用),方能让控件显示正确的状态。

3、在随笔列表页面,我希望App能全量展示所有的随笔内容,不希望点击某一条随笔进入随笔详情才看到所有内容。那么cell的高度便是不固定的了,需要用到动态高度的cell。

  (1)、为cell定义一个属性article,用来存放随笔模型,然后在setArticle方法内,使用以下方法来动态计算cell的高度,其中contentView是显示内容的TextView:

  之所以高度要加1是为了给下分割线空出空间。

  这个功能的参考文档:http://www.cocoachina.com/industry/20140604/8668.html

  (2)、然后发现,虽然cell能动态计算高度了,但是计算只是依据随笔内容的段落数。即是如果随笔内容是两段,而每一段文字的长度都超过了屏幕的宽度,那么cell计算出来的内容高度只是两行的高度。因为systemLayoutSizeFittingSize:方法并不知道TextView的宽度,也就无法知道在哪里需要换行。于是将计算cell高度的代码修改如下:

4、在进行3(2)的操作时,约束也要相应配合更改。我一开始给UITextView添加了宽度约束后,忘了将UITextView与右边的边距约束去掉,导致执行时出现了以下约束冲突的错误

2016-02-21 15:21:03.443 Meditashayne[4685:225763] Unable to simultaneously satisfy constraints.

                  Probably at least one of the constraints in the following list is one you don‘t want.

                  Try this:

                                    (1) look at each constraint and try to figure out which you don‘t expect;

                                    (2) find the code that added the unwanted constraint or constraints and fix it.

                  (Note: If you‘re seeing NSAutoresizingMaskLayoutConstraints that you don‘t understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)

(

    "<NSAutoresizingMaskLayoutConstraint:0x7fbf4b5b5ec0 h=-&- v=-&- MDSSearchView:0x7fbf4b5ec510.width == UIView:0x7fbf4b41cd10.width>",

    "<NSLayoutConstraint:0x7fbf4b5ee5a0 H:[UITextField:0x7fbf4b5ed780(264)]>",

    "<NSLayoutConstraint:0x7fbf4b5f1490 H:|-(8)-[UITextField:0x7fbf4b5ed780]   (Names: ‘|‘:UIView:0x7fbf4b5ed610 )>",

    "<NSLayoutConstraint:0x7fbf4b5f14e0 H:[UITextField:0x7fbf4b5ed780]-(8)-|   (Names: ‘|‘:UIView:0x7fbf4b5ed610 )>",

    "<NSLayoutConstraint:0x7fbf4b5cdb40 H:[UIView:0x7fbf4b5ed610]-(20)-|   (Names: ‘|‘:UIView:0x7fbf4b5ed4a0 )>",

    "<NSLayoutConstraint:0x7fbf4b5a62a0 H:|-(20)-[UIView:0x7fbf4b5ed610]   (Names: ‘|‘:UIView:0x7fbf4b5ed4a0 )>",

    "<NSLayoutConstraint:0x7fbf4b5fa280 H:[UIView:0x7fbf4b5ed4a0]-(0)-|   (Names: ‘|‘:MDSSearchView:0x7fbf4b5ec510 )>",

    "<NSLayoutConstraint:0x7fbf4b5ed140 H:|-(0)-[UIView:0x7fbf4b5ed4a0]   (Names: ‘|‘:MDSSearchView:0x7fbf4b5ec510 )>",

    "<NSLayoutConstraint:0x7fbf4b616a70 ‘UIView-Encapsulated-Layout-Width‘ H:[UIView:0x7fbf4b41cd10(375)]>"

)

Will attempt to recover by breaking constraint

<NSLayoutConstraint:0x7fbf4b5ee5a0 H:[UITextField:0x7fbf4b5ed780(264)]>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.

The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

  原因就在于UITextView设置了与superView的左右边距,又设置了宽度为264,导致了冲突。

5、在动态计算高度的cell里面,要把UITextView的Scrolling Enable设为NO,否则TextView的高度不会跟着内容变化,只会取一个最小的高度;同时也要把UITextView的user interaction enable也设为NO,否则TextView会拦截掉cell的点击事件,选中cell变成了编辑TextView。

6、在做完动态高度的cell之后,发现在真机上App打开后加载数据的时候非常慢。我一开始以为是Core Data的问题,于是自定义了一个加载的浮框控件,在打开App的时候,新开一条线程去Core Data取数据,主线程显示加载控件,样式如下:

  但是发现问题仍然存在,打开App之后仍然是会卡住一段时间,并且卡住的是主线程上的加载控件,甚至当时页面上只有1个cell,都整整卡住了8秒钟。那就很明显问题不在于Core Data了,而在于主线程上。

  于是我一步一步排查,首先发现耗时操作主要在于获取到数据后刷新TableView的reloadData方法上,再进一步排查发现耗时主要发生在这个方法里:

  reloadData方法会调用tableView:cellForRowAtIndexPath:方法,下一步就有可能会调用到上面的loadNibName:owner:options:方法,而主要的耗时就发生在这个方法里。于是着重研究这个xib文件,最后发现问题出在两个地方:

  (1)、xib里显示随笔标题的UILabel使用了“苹方”这种字体,而真机是iOS 8系统的,手机系统里匹配不到“苹方”字体,最终使用了系统默认的字体,这个匹配的过程造成了大部分的耗时,最终将UILabel的字体设为系统默认字体,解决了这部分耗时;

  (2)、xib里显示随笔内容的UITextView默认的text写了中文,导致了小部分的耗时,将默认text改成英文就解决了这部分耗时。

  然后发现仍然有改进的空间:

  现在cell的高度cellHeight是在cell设置随笔模型的setArticle:方法里去计算的,每次调用setArticle:方法都会计算一次,而setArticle:方法调用在tableView:cellForRowAtIndexPath:方法里,即是,每次调用tableView:cellForRowAtIndexPath:都会计算一次cell高度。

  进入App的时候,在tableView:heightForRowAtIndexPath:会去根据IndexPath取出对应cell,再返回它的高度,这个方法这里也是调用了tableView:cellForRowAtIndexPath:方法去取cell的,所以就造成了这么个情况:进入App的时候,每个cell的高度都会被计算两次。

  (3)、于是就使用了以下这个方法预估cell的高度,减少了一次cell高度的计算,又优化了一小部分耗时:

  做完这些优化之后,发现加载数据的时间已经非常短了,以至于根本不需要一个加载浮框了,于是就把加载浮框移除掉了。

7、在真机上跑App的时候发现了另一个问题:拖动TableView的时候会卡顿。原因还是在于cell高度的计算上,由于拖动TableView的时候,哪怕这个cell之前已经显示过了,新出现的cell还是会调用tableView:cellForRowAtIndexPath:方法,这样就多次计算了一个cell的高度。而这些能耗在iOS 8系统的iPhone 4S上显得特别明显。

  于是我开始思考是否有办法让所有cell都只计算一次,毕竟对于已经计算过高度的cell,是完全没有必要再重复去计算高度的了。最终使用了以下的方法来处理:

  (1)、在cell里单独提供一个计算高度的方法,不再在设置随笔模型的setArticle:方法里去计算cell的高度:

  (2)、在随笔列表控制器里新增一个属性:

  这个属性用来存放cell的高度,以IndexPath.row为key,对应cell的高度为value存在这个字典里。

  (3)、然后将tableView:cellForRowAtIndexPath:方法修改如下:

  (4)、最后将tableView:heightForRowAtIndexPath:修改如下,这样,所有的cell就只会计算一次了:

8、创建了搜索栏之后,我希望能只点击搜索栏右上方的Handler拖动这个搜索栏,而在Handler左右方的透明部分则不拦截任何手势

  在搜索栏中重写了这个方法完成了这个功能:

9、当搜索栏调出了键盘后,控制器接收到UIKeyboardWillShowNotification通知后在self.view上会添加一层蒙板,用以点击时收起键盘,同时也将蒙板自身remove掉。但是在真机上,发现点击了蒙板后虽然键盘会收起,但是self.view却没有任何点击反应了,似乎它并没有将自身remove掉。

  最终排查之后发现,问题出在UIKeyboardWillShowNotification通知上。在iOS 8 系统下,中文键盘出现时会发送3次UIKeyboardWillShowNotification通知,这样就使得页面上添加了3层蒙板,导致了页面点击无反应。

  最终在UIKeyboardWillShowNotification通知的处理方法里,处理成先移除已有蒙板再添加新蒙板,解决了这个问题。

时间: 2024-10-14 22:58:49

所闻所获6:meditashayne项目总结的相关文章

所闻所获3:下拉刷新控件1

本文主要是讨论在最近项目中遇到的一个下拉刷新控件,这个控件的效果如下图: 在这里会用两篇博文的篇幅来解析这个控件,第一篇解析控件的框架,第二篇解析动画.源代码可以在下面的链接下载: TestPullToRefresh.zip 1.这个控件由以下几个文件组成:GMPullToAction.CircleProgressView.GMActivityView,其中GMPullToAction文件包含两个类:GMPullToRefresh和UIScrollView (GMPullToAction),Ci

所闻所获2:使用块回调来实现代理的功能

首先回顾一下代理模式,它的基本说明如下图: 控制器先成为子控件的代理(delegate)并实现相应的代理方法,那么子控件在运作的过程中,遇到某些需要控制器进行配合的场景时,就可以通过delegate属性调用对应场景的代理方法,实现让控制器进行对应操作的效果. 块回调的基本模式如下图: 块回调方法的模型是这样的:在一个方法B内嵌套另一个方法C,当其他地方的方法A使用B这个方法的时候,B方法能够通过C来将一些信息传递回给A方法,A自己就可以拿到传回来的这些信息进行操作(C的调用在B内,具体实现在A内

所闻所获4:下拉刷新控件2

在上一篇博文讨论了下拉刷新控件的框架,这一篇博文将会主要讨论刷新过程中控件的动画效果. 1.首先回顾一下在GMPullToRefresh类中的初始化方法: - (id)initWithScrollView:(UIScrollView *)scrollView { //初始化 ... //定制提示文字 ... //矩形上升动画图 self.activityView=[self activityIndicatorView]; //圆圈转动动画 self.circleView=[[CircleProg

多项目同时进行如何做好进度管理

多项目同时进行如何做好进度管理? 多个项目同时进行会发生很多不确定性事件,而且工作强度较高时效率会明显下降,请问这个时候如何做好时间管理,确保项目的进度可以控制在一定范围内? 1 条评论 按投票排序 按时间排序 28 个回答 warfalcon,微信号:read01 , 2011年完成每天一本书… 知乎用户.Ma Lance.邓涛 等人赞同 • 收录于 知乎周刊 我到是经常多项目多地点推进,只能说些大的方向,这种事情更多还是经验的积累,在做项目过程中千变万化什么事情都可能遇上. 1.不管你是做什

VS Bug 当获取其他项目的代码时, F5 无法进入调试模式. 也不报错....

在64位的机子下, 被获用的项目使用X86时会出现. 就会出现   F5 无法进入调试模式. 也不报错.... 打断点也没有用. 在不加入X86项目的代码时, 又可以运行..   解决方案:   检查一下你的项目的运行平台是不是跟你的操作系统是一样的.. 要不就都使用Any CPU吧...     我是开发在VSTO项目时出现这个问题. 之种开发的时候是使用32位系统, Office 2010+VS2010. 正常开发使用. 现在使用新的机子, 使用64位系统,  VS2013+Office 2

律师网站项目集合

建站官网 项目地址:http://www.djfw.net/JZ/ 广东楉泓律师事务所 项目地址:www.ruohong.com.cn 广东巨信律师事务所 项目地址:http://www.juxinlawyer.com/ 广东绿建律师事务所 项目地址:http://www.ljlst.com/ 四川睿桥律师事务所 项目地址:http://demo6.51dj.cn/ 四川鼎天律师事务所 项目地址:http://www.scdtlssws.cn/ 甘肃红升律师事务所 项目地址:http://www

第一周大作业1

---恢复内容开始--- 田继平-软件工程-第一次作业 一.自我介绍大家好,我叫田继平,目前就读于东北师范大学信息科学与技术学院计算机技术专业,是一名在读的专硕研一学生,本科就读于北华大学计算机科学技术学院,专业是计算机科学与技术,籍贯吉林省榆树市.二.回答作业问题1.回想一下你曾经对计算机专业的畅想我高考后报考的是计算机科学与技术,当时对计算机技术基本了解为零,当时以为什么东西都会用到计算机,学计算机以后不会找不到工作,刚开学的时候对计算机一窍不通,甚至连优盘拔出来,要单击右键然后弹出都不会,

2017年度最具商业价值人工智能公司TOP50 榜单发布

未来最有赚钱潜力的50个人工智能项目都在这里了. 经过了60年的发展,人工智能在2017年,正式走向应用的元年. 从今年起,人工智能首次被写入政府工作报告.AI相关内容,以前所未有的力度覆盖了各大媒体的头条,成为人们已不陌生的话题.但和之前不同的是,一场关于人工智能商业化应用的革命,已然显露雏形. 去年AlphaGo战胜李世乭,将业界对人工智能领域的关注引向了高潮.在今年年初,AlphaGo Master以60连胜中日韩棋坛的顶尖高手后,5月份在乌镇,AlphaGo对战柯洁又取得了三战全胜的成绩

PSP总结报告

回答作业问题 1.回想一下你曾经对计算机专业的畅想 我高考后报考的是计算机科学与技术,当时对计算机技术基本了解为零,当时以为什么东西都会用到计算机,学计算机以后不会找不到工作,刚开学的时候对计算机一窍不通,甚至连优盘拔出来,要单击右键然后弹出都不会,由于自己是乡下来的基本上没接触过计算机,开学后老师教了计算机的基础知识,然后教了各种语言,才算大概了解了计算机技术,经过一个学期,我认为我选择计算机专业是多么明智的选择.我觉得我接触的课程符合我对计算机专业的期待,经过一个学期,我突然特别喜欢专业知识