네비게이션과 탭제스쳐를 어떻게 구분할까

Jehyeon Lee·2024년 9월 12일
0

지금 만들고 있는 코드는 한 셀에 이벤트가 여러개를 둬야하는 상황입니다.


이것은 편집 버튼을 눌렀을 경우


이것은 편집 버튼이 눌리지 않은 경우

문제

네비게이션 링크가 들어가지지 않음

이유

  • 한 셀에 이벤트가 여러개가 겹칠경우 네비게이션 링크의 이벤트가 가장 아래로 씹히는 경우가 생깁니다.
    -- 복잡한 레이아웃과 터치 이벤트가 겹치는 경우 발생한다고 합니다.
    -- zstack의 경우 상위 레이어가 터치 영역을 덮고 있으면 하위 레이어의 네비게이션 링크는 터치 이벤트를 받지 못합니다.

문제의 코드

if selectedButton == "투표" {
                    ScrollView(showsIndicators: false) {
                        ForEach(bookmarkStore.currentUserVotesBookmark) { bookmark in
                            if isEdit {
                                VotesBookmarkCell(categoryStore: categoryStore, voteStore: voteStore, bookmarkStore: bookmarkStore, isEdit: $isEdit,  bookmark: bookmark)
                                    .padding(.horizontal, 20)
                            } else {
                                NavigationLink {
                                    VoteDetailView(voteId: bookmark.voteId, voteStore: voteStore, bookmarkStore: bookmarkStore)
                                } label: {
                                    VotesBookmarkCell(categoryStore: categoryStore, voteStore: voteStore, bookmarkStore: bookmarkStore, isEdit: $isEdit, bookmark: bookmark)
                                        .padding(.horizontal, 20)
                                }
                                .buttonStyle(PlainButtonStyle())

                            }
                        }
                    }
ZStack {
            ZStack {
                RoundedRectangle(cornerRadius: 8)
                    .frame(height: 66)
                    .foregroundStyle(CustomColor.GrayScaleColor.white)
                HStack(spacing: 0) {
                    if isEdit {
                        Image("checkCircle_\(isTap)")
                            .frame(width: 16, height: 16)
                            .padding(.leading, 16)
                    }
                    VStack(alignment: .leading, spacing: 0) {
                        HStack(spacing: 0) {
                            
                            Text(bookmark.title)
                                .font(.createFont(weight: .bold, size: 14))
                                .foregroundStyle(CustomColor.GrayScaleColor.black)
                                .lineLimit(1)
                            Spacer()
                        }
                        .padding(.bottom, 10)
                        HStack(spacing: 0) {
                            Text(bookmark.description)
                                .font(.createFont(weight: .bold, size: 12))
                                .foregroundStyle(CustomColor.GrayScaleColor.gs6)
                                .lineLimit(1)
                            Spacer()
                        }
                    }
                    .padding(.horizontal, 16)
                }
            }
            .onTapGesture {
                if isEdit {
                    isTap.toggle()
                }
            }
        }

해결

  • 뷰 계층구조에서 상위 뷰의 터치이벤트가 하위 뷰에 영향을 미치지 않도록 분리 하였습니다.
  • 분기를 나눠서 분기마다의 처리를 해줬습니다.
  • 뷰빌더를 사용하여 코드의 재사용성을 높?인거같아요 호호
//
//  VotesBookmarkCell.swift
//  Sachosaeng
//
//  Created by LJh on 9/11/24.
//

import SwiftUI

struct VotesBookmarkCell: View {
    @StateObject var categoryStore: CategoryStore
    @StateObject var voteStore: VoteStore
    @StateObject var bookmarkStore: BookmarkStore
    @Binding var isEdit: Bool
    @State var isTap: Bool = false
    var bookmark: Bookmark
    
    var body: some View {
        ZStack {
            if isEdit {
                cellContent
                    .onTapGesture {
                        isTap.toggle()
                    }
            } else {
                NavigationLink {
                    VoteDetailView(voteId: bookmark.voteId, voteStore: voteStore, bookmarkStore: bookmarkStore)
                } label: {
                    cellContent
                } //: navigation
            }
        } //: ZSTACK
    }
    
    @ViewBuilder
    var cellContent: some View {
        RoundedRectangle(cornerRadius: 8)
            .frame(height: 66)
            .foregroundStyle(CustomColor.GrayScaleColor.white)
            .overlay {
                HStack(spacing: 0) {
                    if isEdit {
                        Image("checkCircle_\(isTap)")
                            .frame(width: 16, height: 16)
                            .padding(.leading, 16)
                    }
                    VStack(alignment: .leading, spacing: 0) {
                        HStack(spacing: 0) {
                            
                            Text(bookmark.title)
                                .font(.createFont(weight: .bold, size: 14))
                                .foregroundStyle(CustomColor.GrayScaleColor.black)
                                .lineLimit(1)
                            Spacer()
                        }
                        .padding(.bottom, 10)
                        HStack(spacing: 0) {
                            Text(bookmark.description)
                                .font(.createFont(weight: .bold, size: 12))
                                .foregroundStyle(CustomColor.GrayScaleColor.gs6)
                                .lineLimit(1)
                            Spacer()
                        }
                    }
                    .padding(.horizontal, 16)
                }
            }
    }
}
profile
공부한거 느낌대로 써내려갑니당

0개의 댓글

관련 채용 정보