Skip to content

Instantly share code, notes, and snippets.

@abbeyjackson
Last active May 18, 2017 19:05
Show Gist options
  • Save abbeyjackson/e7c3976af409c64b0ee78c05925de33b to your computer and use it in GitHub Desktop.
Save abbeyjackson/e7c3976af409c64b0ee78c05925de33b to your computer and use it in GitHub Desktop.
When you need to translate touches to views through other views you can use the hitTest method on the CONTAINING view. The hierarchy that this applies to is included as well.
class ContainerVC: BaseViewController {
override func loadView() {
view = ContainerView()
}
func addButton() {
// add the button
}
}
class ContainerView: UIView {
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
// We need to go through subviews in reversed order because
// the top displayed subview (subviews.last) is always in front
// of the bottom displayed subview (subviews.first). Hit test
// should always check views in the order it is displayed
// (top to bottom hierarchy).
for subview in subviews.reversed() {
let pointInSubview = convert(point, to: subview)
if let target = subview.hitTest(pointInSubview, with: event), target.tag != BaseViewController.viewTag {
Log.verbose?.message("Touch target: \(target)")
return target
}
}
return nil
}
}
/// NOTE: All View Controller subclasses must be children of a BaseViewController
/// so that a tag can be applied to use the above code. Could also filter
/// other ways such as using class type if you only wanted to apply to one
class AppCoordinator {
// 1. Create a navigation controller with a root view controller (menu). This
// by default will "steal" touches as it's the one on top of the view stack.
// The menuVC will have a clear background so you can see the viewableVC
// below it. The purpose is to access the navigation controller. The
// navigationController performs all navigation in the app. The AppCoordinator
// has an instance of navigationController to perform navigation actions.
let navigationController = UINavigationController()
let menuVC = MenuVC.instantiateFromStoryboard()
navigationController.setViewControllers([menuVC], animated: false)
// 2. Create a containerViewController which will hold the others
let container = containerViewController()
// 3. Create the view that you will see under the menuVC and add it as a
// subview to container
let viewableViewController = ViewableVC.instantiateFromStoryboard()
container.addChildViewController(viewableVC)
container.view.addSubview(viewableVC.view)
viewableVC.view.frame = container.view.frame
viewableVC.didMove(toParentViewController: container)
// 4. Add navigationController on top of viewableVC as a subview of container
container.addChildViewController(navigationController)
container.view.addSubview(mapNavigationController.view)
navigationController.view.frame = container.view.frame
navigationController.didMove(toParentViewController: container)
// 5. If there is a view that needs to persist across navigation actions it must
// be added last to container
container.addButton()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment