一个 bug / Masonry的引入

支持iOS 6/6 Plus的时候碰到这样一个问题:

塞在UITableViewCell里的UIPageControl居中设置失败了,偏右

刚刚设置时下断点查看(6Plus模拟器):

<GrayPageControl: 0x7f96a535c350; baseClass = UIPageControl; frame = (179.5 241.75; 55 6); autoresize = W; layer = <CALayer: 0x7f96a535c4a0>>

运行后:

<GrayPageControl: 0x7f96a535c350; baseClass = UIPageControl; frame = (179.333 241.75; 149 6); autoresize = W; layer = <CALayer: 0x7f96a535c4a0>>

好奇在什么时候被改变的,考虑搞个内存修改断点,上lldb,听从忠告检测CALayer的frame改动而不是UIView的:

(lldb) po pc
<GrayPageControl: 0x15fe26ca0; baseClass = UIPageControl; frame = (160 217.375; 55 6); autoresize = W; layer = <CALayer: 0x174c38500>>

(lldb) break set -F ‘-[CALayer setBounds:]‘ -c ‘$x0 == 0x174c38500‘
Breakpoint 113: where = QuartzCore`-[CALayer setBounds:], address = 0x000000018a3eb93c

结果是 layoutSubviews:

#0 0x000000018a3eb93c in -[CALayer setBounds:] ()
#1 0x000000018a3ec684 in -[CALayer setFrame:] ()
#2 0x000000018aa9da3c in -[UIView(Geometry) setFrame:] ()
#3 0x000000018aaba7b4 in -[UIView(Geometry) _applyAutoresizingMaskWithOldSuperviewSize:] ()
#4 0x000000018618cfc8 in __53-[__NSArrayM enumerateObjectsWithOptions:usingBlock:]_block_invoke ()
#5 0x000000018618ce6c in -[__NSArrayM enumerateObjectsWithOptions:usingBlock:] ()
#6 0x000000018aaa9f58 in -[UIView(Geometry) resizeSubviewsWithOldSize:] ()
#7 0x000000018aa9daf4 in -[UIView(Geometry) setFrame:] ()
#8 0x000000018ab7b9d4 in -[UITableViewCellContentView setFrame:] ()
#9 0x000000018abe442c in __53-[UITableView _configureCellForDisplay:forIndexPath:]_block_invoke ()
#10 0x000000018aab24c8 in +[UIView(Animation) performWithoutAnimation:] ()
#11 0x000000018abe3b0c in -[UITableView _configureCellForDisplay:forIndexPath:] ()
#12 0x000000018ad9b4d8 in -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] ()
#13 0x000000018ad9006c in -[UITableView _updateVisibleCellsNow:isRecursive:] ()
#14 0x000000018ab84c44 in -[UITableView layoutSubviews] ()
#15 0x000000018aaa14a4 in -[UIView(CALayerDelegate) layoutSublayersOfLayer:] ()
#16 0x000000018a3f57a8 in -[CALayer layoutSublayers] ()
#17 0x000000018a3f0378 in CA::Layer::layout_if_needed(CA::Transaction*) ()
#18 0x000000018a3f021c in CA::Layer::layout_and_display_if_needed(CA::Transaction*) ()
#19 0x000000018a3efa14 in CA::Context::commit_transaction(CA::Transaction*) ()
#20 0x000000018a3ef798 in CA::Transaction::commit() ()
#21 0x000000018a3e91c8 in CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) ()
#22 0x000000018624ed98 in __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ ()
#23 0x000000018624bd24 in __CFRunLoopDoObservers ()
#24 0x000000018624c104 in __CFRunLoopRun ()
#25 0x00000001861791f4 in CFRunLoopRunSpecific ()
#26 0x000000018f59b6fc in GSEventRunModal ()
#27 0x000000018ab0a10c in UIApplicationMain ()
#28 0x0000000100029ce0 in main 

看一下赋值过程:

(lldb) po $x0
<CALayer:0x174c38500; position = CGPoint (215 220.375); bounds = CGRect (0 0; 55 6); delegate = <GrayPageControl: 0x15fe26ca0; baseClass = UIPageControl; frame = (187.5 217.375; 55 6); autoresize = W; layer = <CALayer: 0x174c38500>>; sublayers = (<CALayer: 0x170a3fd40>, <CALayer: 0x1704250a0>, <CALayer: 0x174c38200>, <CALayer: 0x174c38080>); opaque = YES; allowsGroupOpacity = YES; >

(lldb) finish

(lldb) po 0x174c38500

<CALayer:0x174c38500; position = CGPoint (215 220.375); bounds = CGRect (0 0; 110 6); delegate = <GrayPageControl: 0x15fe26ca0; baseClass = UIPageControl; frame = (160 217.375; 110 6); autoresize = W; layer = <CALayer: 0x174c38500>>; sublayers = (<CALayer: 0x170a3fd40>, <CALayer: 0x1704250a0>, <CALayer: 0x174c38200>, <CALayer: 0x174c38080>); opaque = YES; allowsGroupOpacity = YES; >

这里借了台iPhone 6/iOS8, cpu是ARM64 所以得参考下面link里bcattle的补充回答,寄存器是$x0, iphone 5/iOS7 上用$r0 但是居然值没变化。模拟器上没成功。另外同样是layoutSubviews 前者是UITableView的,后者是UITableViewCell调用的。

http://stackoverflow.com/questions/13976219/how-do-i-set-an-lldb-watchpoint-on-a-property-of-self-view

好奇满足了,然后想办法解决。so上搜索PageControl UITableViewCell layoutSubViews/center 等等,没有看到相关讨论。某天学了一点AutoLayout赶紧过来写一行:

 1 [pc setTranslatesAutoresizingMaskIntoConstraints:NO];
 2 [cell.contentView addConstraints:[NSLayoutConstraint
 3                   constraintsWithVisualFormat:@"H:|-0-[pc]-0-|”
 4                                       options:0
 5                                       metrics:nil
 6                                         views:NSDictionaryOfVariableBindings(pc)]];
 7
 8 [cell.contentView addConstraints:[NSLayoutConstraint
 9                     constraintsWithVisualFormat:[NSString stringWithFormat: @"V:|-%f-[pc]-11-|",  CGRectGetHeight(scroll.frame)-11-6]
10                                         options:0
11                                         metrics:nil
12                                           views:NSDictionaryOfVariableBindings(pc)]];

不卖关子,成功了。于是结论出来了,AutoLayout升级为必修。Masonry,我来了。

1 [pc mas_makeConstraints:^(MASConstraintMaker * make){
2     make.bottom.equalTo(cell.contentView.mas_bottom).with.offset(-6);
3     make.centerX.equalTo(cell.contentView.mas_centerX);
4 }];

尾声:storyboard的预览功能+sizeClass会不会比传统的手码代码快一点呢?

2015.03.30

时间: 2024-07-29 17:49:48

一个 bug / Masonry的引入的相关文章

【Qt】无边框窗体中带有ActiveX组件时的一个BUG

无意中发现的一个BUG,Qt5.1.1正式版首先创建一个GUI工程,拖入一个QAxWidget控件(为了使ActiveX生效,需要在.pro文件中加入CONFIG += qaxcontainer)接着,为了让ActiveX有效,需要引入一个组件,我这里引入的是IE组件 [cpp] view plain copy MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->s

在CentOS 5.5上使用sed遇到的一个bug

在 CentOS 5.5 上使用 sed 遇到一个bug $ echo AAA > config $ ln -s config cfg $ sed -i 's/AAA/aaa/' cfg sed: ck_follow_symlink: couldn't lstat c/config: No such file or directory 这个bug发生在 sed -i do_sth symbolic_links_without_slash 时 下载它的源代码 https://google-sear

发现一个骗粉丝的人后发现博客园的一个bug

发现一个骗粉丝的人后发现博客园的一个bug 当你点开这篇文章的时候,如果你已经登录博客园账号,那么你自动回成为我的博客园粉丝,因为我加了自动关注的js,这里并不是想骗粉丝,希望博客园能重视这个bug(当然博客园肯定知道这个bug的).明天早上我会删除掉这段js的. 起因>发现一个骗粉丝的人 经过>他是如何实现骗粉丝的 我的一些思考 1.发现一个骗粉丝的人 今天下班,打开博客园的时候看到这篇文章,点了进去,感觉排版不错,自定义的界面体验非常不错,职业性地点击了主页看了看,发现了一个问题,于是乎有

Ibatis2.3.4的一个bug

java.lang.ClassCastException: com.chat.upgrade.domain.ClientFile cannot be cast to java.lang.String 今天查一个对象转化成json串报错的问题,查了两个小时,最后问题的根源居然是ibatis. ibatis的语句如下: <typeAlias alias="Client" type="com.chat.upgrade.domain.ClientFile"/>

Win10系统菜单打不开问题的解决,难道是Win10的一个Bug ?

Win10左下角菜单打不开,好痛苦,点击右下角的时间也没反应,各种不爽,折磨了我好几天,重装又不忍心,实在费劲,一堆开发环境要安装,上网找了很多方法都不适用.今天偶然解决了,仔细想了下,难道是Win10的一个Bug? 1.问题和现象 右下角菜单点不开,下面的状态栏的右键也没有反应.时间日期也点不开,音频喇叭同样点不开....各种烦人,百度一堆都无果.... 说明:Win10是正式版,已激活:杀毒也全盘扫描过,因为电脑是开发和办公用,几乎不上其他网站,所以中毒的可能性几乎为0. 2.解决方法 晚上

Universal-Image-Loader的一个BUG

使用UIL的内置圆角图片的功能时,发现一个BUG,就是它会拉伸图片,造成图片失真.费了一下午的功夫,重写了RoundedBitmapDisplayer,总算解决这个问题. 代码如下: public class RoundedBitmapDisplayer implements BitmapDisplayer { protected final int cornerRadius; protected final int margin; public RoundedBitmapDisplayer(i

ubuntu12.04 software-center 的一个BUG

ubuntu software-center 软件中心今天突然发现打不开了,就是在启动的过程中启动一半就退出了,多次启动无果.首先想到的办法当然是最彻底的两句话 sudo apt-get purge software-center sudo apt-get install software-center 结果未果,启动起来还是首先一个窗体初始化 接着..就直接关闭了.然后查看它的输出信息,发现原来是py输出中文导致的,因为我们窗体上有很多中文字体的组件需要加载,而python处理的时候有一个使用

docker 1.0.0发布以及一个bug依赖apparmor_parser

6月10号docker 1.0稳定版本发布,找了台ubuntu的机器,装了下 ubuntu version:12.04 docker version:1.0.0 装docker的步骤可以看官方文档:https://docs.docker.com/installation/ubuntulinux/ 装好之后,运行docker -d尝试启动docker守护进程,报错如下: [0fcb4ed6] +job serveapi(tcp://127.0.0.1:2375) [0fcb4ed6] +job i

使用getDrawable时遇到的一个bug

做一个筛选菜单时候,用到了dongjunkun的DropDownMenu,github地址:https://github.com/dongjunkun/DropDownMenu 遇到几个问题: (1)最右面的上三角形.下三角形很难看,需要改成向上箭头向下箭头,而且靠近文件,在右边: (2)背景颜色需要改成白色: (3)下面的子菜单的文字在最左边,需要居中: (4)第一次进来Fragment的时候DropDownMenu的下拉选项没有选中任意一项 上面几个需求看起来很容易改,不就是改改布局什么的,