project/Kuring(공지알림)

[SwiftUI] List Row 선택하기(TableView didSelectRow)

lgvv 2022. 5. 30. 20:50

List Row 선택하기(TableView didSelectRow)

 

✅ 오랜만이다! 제목이 참 UIKit스러움

 

제목을 이렇게 작성하게 된 이유로는 내가 1년 정도 UIKit을 사용하면서 이미 사고가 여기에 익숙해진 상태인데, SwiftUI로 List의 Row(UIKit에서 cell)을 선택하는 로직을 작성하는게 잘 아직까지는 어려운 느낌.

그래서 내가 구글에 저 키워드로 검색했는데, 딱히 맘에 드는게 안나타나서 직접 정리하려고 포스팅 함.

 

생각보다 간단한데, 이게 참 어려웠음.

우선 UIKit을 사용하다보니 tableView에서는 UITableViewDelegate를 상속받아서 didSelectRow를 구현하면 되었다.

그러니까 이와 비슷하게 List의 Row에 onTapGesture를 사용하면 될거라고 생각!!

 

✅ 잘못된 case

struct didSelectRow: View {
    var body: some View {
        List {
            ForEach((0...10), id: \.self) { index in
                Text("\(index)")
                    .onTapGesture {
                        print("\(index)")
                    }
            }
        }
    }
}

struct didSelectRow: View {
    var body: some View {
        List {
            ForEach((0...10), id: \.self) { index in
                Text("\(index)")
            }.onTapGesture {
                print("didTap")
            }
        }
    }
}

위의 두가지 경우에는 Text 영역에만 touch가 되어서 row전체를 커버할 수 없음.

 

✅ 그렇다면 List 자체에 onTapGesture를 붙이고 해당하는 정보를 얻어볼까?

struct didSelectRow: View {
    var body: some View {
        List {
            ForEach((0...10), id: \.self) { index in
                Text("\(index)")
            }
        }.onTapGesture {
            print("didTap")
        }
    }
}

이렇게 작성하면 List전체가 선택된다. 하지만 row안에 해당하는 정보를 얻을 수 없음.

 

그렇다면 어떻게 해야할까?

 

✅ 올바른 case

import SwiftUI

struct didSelectRow: View {
    var body: some View {
        NavigationView {
            List {
                ForEach((0...10), id: \.self) { index in
                    NavigationLink {
                        secondView(index: index)
//                        nextView(index: index)
                    } label: {
                        Text("\(index)")
                    }
                    
                    //                Text("\(index)")
                }
            }
        }
    }
    
    func secondView(index: Int) -> some View {
        var body: some View {
            Text("\(index)")
        }
        
        return body
    }
}

struct nextView: View {
    let index: Int!
    var body: some View {
        Text("\(index)")
    }
}

 

NavigationView로 묶어준 다음에 NavigationLink를 통해서 사용한다!

 (중요) 네비게이션 뷰로 묶는다. -> 없으면 NavigationLink 작동안함

 

위의 코드에서는 추가로 뷰를 func으로도 구성해 보았다!

 

✅ NavigationLink에 대해서 좀 더 알아보자

NavigationLink { 
	// action
} label: { 
	// 모양!
}

버튼이랑 똑같다. label이 겉모양이 되므로 이 모양을 클릭하면 action을 수행하게 된다.

그러니까 모양이 row가 되어야 한다는 의미이다!!

결과물 UI

 

 

이제 해결해야할 문제가 하나 남았다. 바로 각 row의 accessory 부분 이를 없애는 방법을 다음 포스팅에서 알아보자!

 

2022.05.31 - [iOS프로젝트/Kuring] - [SwiftUI] List accessory (feat. disclosure indicator)

 

[SwiftUI] List accessory (feat. disclosure indicator)

List accessory (feat. disclosure indicator) ✅ 이번에도 제목이 다소 UIKit스럽다. 저번 포스팅에서도 언급했지만, UIKit을 먼저 공부하고 SwiftUI를 하다보니까, 검색도 UIKit스럽게 하기 때문에! StackOv..

rldd.tistory.com