We can achieve by using UICollectionView delegate protocol method, pls find code snippt.
class ViewController: UIViewController {
@IBOutlet weak var sideMenuTableView: UITableView!
@IBOutlet weak var collectionView: UICollectionView!
let menueItem = ["Home", "Sports", "Movies", "Listen", "Play", "Game"]
let colors: [UIColor] = [.green, .blue, .purple, .orange, .yellow, .magenta, .brown, .black, .gray, .yellow, .green, .lightGray, .cyan, .magenta, .link, .blue, .yellow, .magenta, .brown, .black, .gray, .yellow, .green, .lightGray, .cyan, .magenta, .link, .blue]
var lastFocusedIndexPath: IndexPath?
override func viewDidLoad() {
super.viewDidLoad()
lastFocusedIndexPath = IndexPath(row: 2, section: 0)
initialConfiguration()
}
override var preferredFocusEnvironments : [UIFocusEnvironment] {
return [collectionView]
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
updateTableViewContentInset()
}
func updateTableViewContentInset() {
self.sideMenuTableView.contentInset = UIEdgeInsets(top: 0, left: -40, bottom: 0, right: 0)
}
func initialConfiguration() {
sideMenuTableView.register(UINib.init(nibName: "SideMenuTVCell", bundle: nil), forCellReuseIdentifier: "SideMenuTVCell")
sideMenuTableView.delegate = self
sideMenuTableView.dataSource = self
sideMenuTableView.backgroundColor = .yellow
sideMenuTableView.isHidden = false
collectionView.register(UINib.init(nibName: "ColorCVCell", bundle: nil), forCellWithReuseIdentifier: "ColorCVCell")
collectionView.delegate = self
collectionView.dataSource = self
collectionView.backgroundColor = .white
}
}
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return menueItem.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SideMenuTVCell", for: indexPath) as! SideMenuTVCell
cell.configureCell(string: menueItem[indexPath.row])
return cell
}
}
extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return colors.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ColorCVCell", for: indexPath) as! ColorCVCell
cell.backgroundColor = colors[indexPath.row]
cell.configureCell(color: colors[indexPath.row])
return cell
}
func collectionView(_ collectionView: UICollectionView, didUpdateFocusIn context: UICollectionViewFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
if let previousIndexPath = context.previouslyFocusedIndexPath,
let cell = collectionView.cellForItem(at: previousIndexPath) {
cell.contentView.layer.borderWidth = 0.0
cell.contentView.layer.shadowRadius = 0.0
cell.contentView.layer.shadowOpacity = 0
}
if let indexPath = context.nextFocusedIndexPath,
let cell = collectionView.cellForItem(at: indexPath) {
cell.contentView.layer.borderWidth = 8.0
cell.contentView.layer.borderColor = UIColor.black.cgColor
cell.contentView.layer.shadowColor = UIColor.black.cgColor
cell.contentView.layer.shadowRadius = 10.0
cell.contentView.layer.shadowOpacity = 0.9
cell.contentView.layer.shadowOffset = CGSize(width: 0, height: 0)
}
if let indexPath = context.previouslyFocusedIndexPath, let cell = collectionView.cellForItem(at: indexPath) {
UIView.animate(withDuration: 0.3) { () -> Void in
cell.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
}
}
if let indexPath = context.nextFocusedIndexPath, let cell = collectionView.cellForItem(at: indexPath) {
UIView.animate(withDuration: 0.3) { () -> Void in
cell.transform = CGAffineTransform(scaleX: 1.1, y: 1.1)
}
}
}
func collectionView(_ collectionView: UICollectionView, shouldUpdateFocusIn context: UICollectionViewFocusUpdateContext) -> Bool {
if let previouslyFocusedIndexPath = context.previouslyFocusedIndexPath, let cell = collectionView.cellForItem(at: previouslyFocusedIndexPath) {
let collectionViewWidth = collectionView.frame.width
let cellWidth = cell.frame.width
let rowCount = Int(ceil(collectionViewWidth / cellWidth))
let remender = previouslyFocusedIndexPath.row % rowCount
let nextIndex = previouslyFocusedIndexPath.row - remender + rowCount
if let nextFocusedInndexPath = context.nextFocusedIndexPath {
if context.focusHeading == .down {
moveFocus(to: IndexPath(row: nextIndex, section: 0))
return true
}
}
}
return true
}
private func moveFocus(to indexPath: IndexPath) {
lastFocusedIndexPath = indexPath
print(collectionView.indexPathsForVisibleItems)
DispatchQueue.main.async {
self.setNeedsFocusUpdate()
self.updateFocusIfNeeded()
}
}
func indexPathForPreferredFocusedView(in collectionView: UICollectionView) -> IndexPath? {
return lastFocusedIndexPath
}
}