0

这有点奇怪,我不确定到底发生了什么。我正在使用具有自定义注释的 MKMapView。在该注释中,我有一个可编辑的文本字段。当用户点击该字段时,键盘会出现,我通过移动/缩小我的地图视图并重新居中注释来响应它。一切都很好,除了 iPad 在横向模式下使用拆分键盘。只有在这种情况下,当我更改地图视图的框架时,它会在我的文本字段上调用“resignFirstResponder”并开始在屏幕外设置键盘动画。当它被移出屏幕时,我的代码通过移动/扩展我的地图视图来填充空间来响应它。然后,我的文本字段再次收到消息becomeFirstResponder。我检查了调用堆栈,这来自:[UIView(Hierarchy) deferredBecomeFirstResponder]. 键盘重新启动,我再次响应,循环继续:上 -> 下 -> 上 -> 下 -> 上 -> 下.....不断。这resignFirstResponder肯定来自设置我的地图视图的框架。如果我在我的文本字段上设置一个中断resignFirstResponder并检查调用堆栈,则上一个调用是我设置地图视图框架。此外,如果我在关闭键盘时中断了响应键盘的代码,我会在设置地图视图框架后立即注意到堆栈上的这些调用:

#6  0x001264cf in -[CTView resignFirstResponder]
#7  0x00e3bed7 in -[UIView setUserInteractionEnabled:] ()
#8  0x00710020 in ___lldb_unnamed_function213$$MapKit ()
#9  0x00714c14 in ___lldb_unnamed_function326$$MapKit ()
#10 0x00716f82 in ___lldb_unnamed_function361$$MapKit ()
#11 0x007168c4 in ___lldb_unnamed_function359$$MapKit ()
#12 0x00716068 in ___lldb_unnamed_function344$$MapKit ()
#13 0x00715c5c in ___lldb_unnamed_function343$$MapKit ()
#14 0x007198d0 in ___lldb_unnamed_function385$$MapKit ()
#15 0x0071a1ad in ___lldb_unnamed_function392$$MapKit ()
#16 0x0071a417 in ___lldb_unnamed_function396$$MapKit ()
#17 0x00711074 in ___lldb_unnamed_function255$$MapKit ()

我可以通过不调整地图视图的大小来解决这个问题。如果我不这样做,则循环永远不会启动。相反,如果我将地图视图放在容器视图中,clipToBounds = YES在容器视图上设置并且地图视图上没有自动调整大小,我可以调整容器视图的大小并使地图视图保持相同的大小......问题是它解决方法。如果用户旋转 iPad,我需要更改地图视图的大小,但这将启动这个丑陋的循环。

有人知道发生了什么吗?

4

2 回答 2

0

在调整大小期间, MKMapView 可能会计算出注释的位置在屏幕外并转储或标记MKAnnotationView包含UITextField当前第一响应者的位置。这会导致UITextFieldResignFirstResponder反对。调整大小后,UIKit 决定UITextField仍然应该是第一响应者。也许UITextField仍然有isFirstResponder == YES因为这个特定的动画系列是 UIKit 不能很好处理的边缘情况。然后 UIKit 会显示键盘,触发你的代码,然后不断地运行。

您是否尝试过使用UITextField继承自的方法UIResponder?也许在调整大小动画期间设置canResignFirstResponder == NO

或者,如果这是由不应显示的MKMapView计算触发的,您是否尝试过设置动画以使注释永远不会被计算为超出可见范围?MKAnnotationView

于 2012-08-24T23:46:09.953 回答
0

所以最后我能想到的唯一解决方案是将文本字段作为 MKMapView 的子视图删除并将其放在 MKMapView 的超级视图中。据我所知,让 MKMapView 的任何子视图成为第一响应者并不是一个好主意。MKMapView 倾向于“窃取”帧更改的第一响应者状态。如果您响应 UIKeyboardNotifications,这可能会导致奇怪的响应周期。

Removing the text field from the Map View also ended up being a little better UI experience anyway. By animating the change, the user experienced the shift from "I am manipulating this map" to "I am editing this text field" much more definitely. Disabling the map during the editing also reinforces this. It took a little more work, but in the end proved to be valuable.

于 2012-08-25T14:33:29.417 回答