For what it's worth, here's my implementation to add a UILargeContentViewerInteraction
to a UITabBar
without using UITabBarController
but inside a custom UIViewController
.
First, add the interaction to the view
of the view controller with the view controller as the interaction delegate.
| view.showsLargeContentViewer = true |
| view.scalesLargeContentImage = true |
| view.addInteraction(UILargeContentViewerInteraction(delegate: self)) |
It's needed to implement tow function of the UILargeContentViewerInteractionDelegate
protocol:
Both functions have to get the index of the tab bar item for the point
parameter so here's a function to do that:
| private func tabItemIndex(for point: CGPoint) -> Int? { |
| let convertedPoint = view.convert(point, to: tabBar) |
| guard |
| tabBar.point(inside: convertedPoint, with: nil), |
| let numberOfItems = tabBar.items?.count, |
| numberOfItems > 0 |
| else { return nil } |
| |
| let itemWidth = tabBar.bounds.width / CGFloat(numberOfItems) |
| return Int(convertedPoint.x / itemWidth) |
| } |
The function converts the point from the view
to the tabBar
and ensures the point is inside the tabBar
. Then the point x
member is divided by the width of an item so that every point targets an item.
For the large content item, the view
itself is used. It is configured using the retrieved UITabBarItem
:
| func largeContentViewerInteraction( |
| _: UILargeContentViewerInteraction, |
| itemAt point: CGPoint |
| ) -> (any UILargeContentViewerItem)? { |
| guard |
| let tabItemIndex = tabItemIndex(for: point), |
| let item = tabBar.items?[tabItemIndex] |
| else { return nil } |
| |
| view.largeContentTitle = item.title |
| view.largeContentImage = item.image |
| return view |
| } |
The item is then selected when the interaction ends.
| func largeContentViewerInteraction( |
| _: UILargeContentViewerInteraction, |
| didEndOn _: (any UILargeContentViewerItem)?, |
| at point: CGPoint |
| ) { |
| guard |
| let tabItemIndex = tabItemIndex(for: point), |
| let item = tabBar.items?[tabItemIndex] |
| else { return } |
| |
| tabBar.selectedItem = item |
| tabBar(tabBar, didSelect: item) |
| } |