iOS开发奇葩问题集

1,使用autolayout时,用编程方式push一个新的controller时,如果该controller需要隐藏tab bar时会出现视图先出现,然后tabbar被隐藏而试图被拉伸时出现一个非预期的动画效果的情况。

解决方案:
解决方法看这里。

大神提供的方法有效,但是在Xcode7下会发现,无法选中大神所说的选项,这个时候我们只需要用文本编辑器直接修改storyboard的源码就可以了。不要害怕,找到对应的id直接修改就行了。


2,push新视图时,右上角会有黑色色块闪现?

解决方案:这个问题很简单,只要把mainwindow和root controller的背景色设置成白色就行了。其他很多奇葩的解决方案都没有这个方法简单有效。


3,自增高的uitextview在自增高的范围内(比如限制四行,超过四行后高度不便)输入文字时uitextview会自动滚动文字,导致极差的用户体验。

解决方案:有人很自然地会在text view 的delegate方法中去修正滚动,这样做是无效的。

修正滚动需要在uitextview的layoutsubviews中实现,那么这样就需要我们自己去实现一个uitextview的子类。其实所有uiscrollview的子类,需要在滑动是线性地处理一些问题,都只能在layoutsubviews中实现。比如滑动是blur背景图等,如果放到delegate方法中去做,都会出现跳跃的情况。

此外,超出最大高度之后,输入中文可能会出现文本区域滚动跳跃的情况。这个时候的处理方法是,在收到text变动的delegate时,我们自己将文本区域滚动到最下方,像这样:

    self.contentOffset = CGPointMake(0, self.contentSize.height - self.frame.size.height);

并且要设置textview的

    self.layoutManager.allowsNonContiguousLayout = NO;

不要相信苹果的注释,他们说默认值是NO(除此之外的注释还是要相信的)。必须要手动设置为NO,才不会跳动。


4,pop一个uitableviewcontroller(只要是包含uiscorllview及其子类的controller都可以照此法解决)的时候莫名crash。

解决方案:首先需要使用intruments的zombie工具,找到crash发生的原因,如果你发现是该[UIScrollview(UIScrollViewInternal)] _notifyDidScroll]方法向zombie发送了消息,那么恭喜你有办法解决了。出现这个问题一般是系统在uiscrollview及其子类(例如tableview)在其delegate对象release之后还向其发送了消息,至于为啥会这样,你得去问apple的工程师。那么解决方法很简单:

- (void)dealloc
{
    self.tableView.delegate = nil;
    self.tableView.dataSource = nil;
}

5,在中使用autolayout布局时,通常在旋转屏幕的时候,会出现unsafe contains的警告,这通常是由于auto resize mask生成的约束和我们自定义的约束出现了冲突。

解决方案:很简单,调高出现冲突约束的priory,默认是1000,你可以调到750。这样就不会出现冲突了。但前提是你要确保自己的约束是正确的。


6,autolayout的cell使用自动算高的tableview时,发现cell右侧的控件不显示?

解决方案:其实不是控件不显示,只是约束使得cell的宽度变宽。相对cell的traeing的控件超出了屏幕的可是范围。那么你问为什么会这样,原因就是你在设计cell的时候,约束都是在anyH,anyW的size class下添加的。解决这个问题的方法就是,在特定设备对应的size class下去添加约束。


7,uibarbuttonitem无法获取frame?

答:是的,uibarbuttonitem是NSObject的子类,他不是一个uiresponed或者uiview的子类,所以他没有frame属性。然后有的时候,我们会要求在点击他之后显示一个弹出框,就像微信右上角的加号一样。一般这种弹出框都需要一个目标控件的frame,一遍能够确定弹出框的位置。那么我可以这么办:

UIBarButtonItem *addContactItem = [[UIBarButtonItem alloc] initWithTitle:@"添加"
                                                                   style:UIBarButtonItemStylePlain
                                                                  target:self action:@selector(addContact:event:)];

在设置action selector的时候多传递一个event参数,然后:

- (void)addContact:(UIBarButtonItem *)sender event:(UIEvent *) event {
    NSArray *menuItems = @[
                         [KxMenuItem menuItem:@"添加朋友" image:nil target:self action:@selector(addFriend)],
                         [KxMenuItem menuItem:@"添加群组" image:nil target:self action:@selector(addGroup)],
                         [KxMenuItem menuItem:@"添加班级" image:nil target:self action:@selector(addClass)],
                         [KxMenuItem menuItem:@"扫一扫" image:nil target:self action:@selector(scan)]
                         ];

    CGRect fromRect = [[event.allTouches anyObject] view].frame;

    fromRect.origin.y += 20;

    [KxMenu showMenuInView:self.view.window
                  fromRect:fromRect
                 menuItems:menuItems];
}

这样我们就可以定位到触发动作的uibarbuttonitem的位置,并正确弹出窗口。

那么这么有两点值得思考的问题:1,@selector是如何传递多个参数的?2,uibarbuttonitem是如何响应事件的,或者说他只是一个表象,由装载他的对象响应的事件?


8,在tableview中加载了历史数据,然后使用tableview的insert方法后,再滚动到之前的位置,一直会有动画,及时代码里禁止了动画。

解决方案:不要使用insert后再滚动的方法,直接用reloaddata然后再滚动就不会出现抖动的现象了。虽然reloaddata性能消耗更大,但是用户体验更加重要不是么。


9,translatesAutoresizingMaskIntoConstraints是什么鬼,怎么用?

答:首先,Apple说,auto resize mask会导致autolayout系统生成一些约束来决定view的最终位置。这玩意儿的初衷是让auto layout系统能追踪视图中哪些手动控制的frame的变化(比如你在代码中通过-setFrame:来控制视图的大小位置的时候),这个时候你不可能加入更多的约束,而不导致冲突。所以当你选择添加自己的约束来控制视图的布局的时候,你必须把这个属性设置为NO。在IB中设置约束的时候,IB会自动为你把这个属性设置为NO。

其次,真如Apple所说,当你在IB里添加约束,IB就给你把这个属性设置为NO了?你要真信了,那就掉大坑里了。至少在uitabelviewcell里面,Apple没有这么做。我通常通过xib来自定义,然后在cell中加入各种约束,以使用iOS8的自动算高功能。然而,这个自动算高功能并不是那么好用,经常出现约束冲突警告。你仔细看日志就会发现,老实有autoresie mask转换成的约束在搞鬼。这个时候你会觉得,妈蛋,IB不是会关掉自动转换autoresize mask成为约束的功能吗?感情没关掉,冲突了就手动去设置cell的translatesAutoresizingMaskIntoConstraints为NO呗。等你设置完,run起来一看,卧槽,cell里的东西都被狗吃了吗?全都不见了!所以你只能乖乖再设置为YES。那么问题来了,冲突怎么解决,请参考问题5。再多想一步,为啥cell的translatesAutoresizingMaskIntoConstraints不能为NO。个人认为,tableview在计算cell的高度的时候还是使用了setFrame等方法,而不全是用autolayout添加约束来实现的,所以不能设为NO,设置为NO就是导致cell的frame计算出错。


10,背景色消失,当cell为选中状态。

解决方案:在layoutSubviews中把丢失的颜色设置回来,至于为什么请看下面的解释


本帖会持续更新,如果有看到的朋友,遇到了其他奇葩问题也请告诉我哟。

你可能感兴趣的:(iOS开发奇葩问题集)