We have run into this issue when implementing interactive dismissal of a modal view controller (dragging modal down should dismiss it) via UIPercentDrivenInteractiveTransition
.
Setup:
- setup
UIViewController
embedded inUINavigationController
with at least one button inUINavigationBar
- modally present another
UIViewController
embedded inUINavigationController
with at least one button inUINavigationBar
- setup
UIPanGestureRecognizer
on modaly presentedUINavigationController
to driveUIPercentDrivenInteractiveTransition
- drag modal down "holding" it by point on
UINavigationBar
Issue:
while slowly dragging down, animation glitches causing modal view to jump up and down
glitch only appears when :
- both
UINavigationBar
s have at least one button on them - you "hold" modal by the point on
UINavigationBar
- both
Minimal example can be downloaded from github repo.
Has anyone come accross such an issue? Are there any workarounds? Is there some flaw in our setup?
Update
Issue has been simulated on running project above on iPhone 5 simulator with iOS 9.3
, OSX 10.11.4
, compiled with Xcode 7.3.1
.
Update 2
Further investigation showed, that issue is probably not in the animation: For some reason in given setup pan.translationInView(view)
is returning unexpected values which causes animation to jump.
Partial workaround
Based on Vladimir's idea we partially fixed the issue by overriding hitTest
method of UINavigationBar
:
class DraggableNavigationBar: UINavigationBar {
override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
guard let view = super.hitTest(point, withEvent: event) else { return nil }
if view is UIControl || pointIsInsideNavigationButton(point) {
return view
} else {
return nil
}
}
private func pointIsInsideNavigationButton(point: CGPoint) -> Bool {
return subviews
.filter { $0.frame.contains(point) }
.filter { String($0.dynamicType) == "UINavigationItemButtonView" }
.isEmpty == false
}
}