Tab의 Item 을 클릭하여 위로 스크롤
개요
탭 아이콘을 눌렀을 때 자동으로 위로 스크롤
이루어지다
미리 준비하다
UItabBarController의viewController에 임의의 수량의 UINavigationController를 설정합니다
여기는 상관없으니 적당히 주십시오
스크롤 박스
우선 어떤 상태에서 스크롤하는지 정리
다음 중 하나만 스크롤 가능
잠깐만, 구르는 상자가 하나밖에 없으니까 그 상자가 움직일 수 있는 조건만 적으면 돼
스크롤 조건은
그러면 하나씩 해보도록 하겠습니다.
class ItemTapScrollTabController: UITabBarController { //アイコンタップでスクロールさせるためのラッパークラス
private var isRoot: Bool = false //表示中のviewControllerがrootかどうかのフラグ
private var currentItemIndex: Int = -1 //表示中のviewControllerのTabから見たときのインデックス
private var nextItemIndex: Int = -1 //遷移先のviewControllerのTabから見たときのインデックス
override func loadView() {
super.loadView()
delegate = self
}
}
extension ItemTapScrollTabController: UITabBarControllerDelegate {
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
//アイコンをタップする時に呼ばれる
return true
}
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
//画面遷移後に呼ばれる
}
}
로고용 속성을 만들어 내용을 넣었다class ItemTapScrollTabController: UITabBarController {
private var isRoot: Bool = false
private var currentItemIndex: Int = -1
private var nextItemIndex: Int = -1
override func loadView() {
super.loadView()
delegate = self
}
}
extension ItemTapScrollTabController: UITabBarControllerDelegate {
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
currentItemIndex = tabBarController.selectedIndex
return true
}
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
nextItemIndex = tabBarController.selectedIndex
}
}
tabBarController.selectedIndex
shouldSelect에서 현재 보이는viewController의 UItabBarController를 볼 때의 인덱스,didSelect에서 이전 목적지의viewController의 UItabBarController를 볼 때의 인덱스를 가져옵니다class ItemTapScrollTabController: UITabBarController {
private var isRoot: Bool = false
private var currentItemIndex: Int = -1
private var nextItemIndex: Int = -1
override func loadView() {
super.loadView()
delegate = self
}
}
extension ItemTapScrollTabController: UITabBarControllerDelegate {
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
currentItemIndex = tabBarController.selectedIndex
if let nav = viewController as? UINavigationController,
let current = nav.visibleViewController,
let currentStackIdx = nav.viewControllers.firstIndex(of: current) {
isRoot = currentStackIdx == 0
}
return true
}
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
nextItemIndex = tabBarController.selectedIndex
guard currentItemIndex == nextItemIndex, isRoot else { return }
//currntItemIndex == nextItemIndex → 表示中のviewControllerのタブから見たインデックスと遷移先のviewControllerのタブから見たインデックスが同じ, 表示中のタブと同じタブを選択
//isRoot → 表示中のviewControllerがnavigationControllerのrootである
}
}
shouldSelect의if let nav...
에서 먼저그리고 이 인덱스가 0이면 UINaviagationController의 루트를 나타낸다. 즉, 표시된viewController는 UINavian Controller의 루트ViewController이기 때문에 isRoot을 진짜로 한다.
다음 didSelect의
guard currentItemIndex == ...
에서 상기 두 조건을 코드에 입력하십시오navigationController.visibleViewController입니다.
shouldSelect에서 보이는viewController를 찾으려고 하기 때문에 다른 옵션으로 이동할 때viewController를 정확하게 찾을 수 없습니다
이 코드에서 shouldSelect
visibleViewController
에서 얻은viewController도 상황에 따라 달라지지만 currentItemIndex == nextItemIndex
부분에서는 같은 탭의 이동만 처리하기 때문에 동작에 문제가 없습니다다시 말아서 스크롤 처리만 할게요.스크롤 처리는 UIScrollView, UItableView, UICollectionView 등 여러 구성 요소로 이루어질 수 있습니다
protocol Scrollable {
func scrollToTop()
}
class ViewController: UIViewController {
private let tableView: UITableView = .init()
}
extension ViewController: Scrollable {
func scrollToTop() {
tableView.scrollToRow(at: .init(row: 0, section: 0), at: .top, animated: true)
}
}
extension ItemTapScrollTabController: UITabBarControllerDelegate {
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
currentItemIndex = tabBarController.selectedIndex
if let nav = viewController as? UINavigationController,
let current = nav.visibleViewController,
let currentStackIdx = nav.viewControllers.firstIndex(of: current) {
isRoot = currentStackIdx == 0
}
return true
}
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
nextItemIndex = tabBarController.selectedIndex
guard currentItemIndex == nextItemIndex, isRoot else { return }
if let nav = viewController as? UINavigationController,
let current = nav.visibleViewController,
let scrollable = current as? Scrollable {
scrollable.scrollToTop()
}
}
}
끝맺다
생각보다 행동이 번거롭고 대단하지만 자신이 먼저 위의 코드로 실현한다.별로 테스트를 안 해서 이상한 행동을 할 수도 있어요.
샘플을 담고 싶은 Gif가 용량이 너무 커서 담을 수가 없어요. 그래서 GiitHub 링크를 먼저 넣을게요.
참고 자료
Reference
이 문제에 관하여(Tab의 Item 을 클릭하여 위로 스크롤), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/hikaru_ios/articles/c2ab9e40ae21b0텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)