나의 발자취
iOS Context menu란? (+Haptic Feedback) 본문
contextMenu는 iOS에서 3D Touch나 길게 눌렀을 때 나타나는 팝업 메뉴다.
사진을 3d 터치로 눌러서 신고하기 버튼을 누른다고 할 때 나타나는 바로 여기다. 내 앱은
- 이미지를 길게 누르거나 3D Touch하면
- "신고하기" 옵션이 포함된 메뉴가 팝업으로 나타나고
- 그 메뉴에서 "신고하기"를 선택하면 ReportView가 표시되는 구조
- 이다.
문제 상황
현재 ChallengeImagesGrid.swift에서 '신고하기'를 누르면 아래와 같이 바로 접수 화면으로 넘어가야하는데, 로딩이 오래걸리는지 뭔지 흰 화면만 뜨는것이다.
- contextMenu 안에서 showReportView.toggle()을 호출
- 그리고 별도의 .sheet modifier에서 ReportView를 표시
- 이 구조에서 contextMenu가 닫히기 전에 sheet가 표시되려고 해서 문제가 발생하는 것 같았다.
문제 원인 분석
현재 문제는 이 contextMenu(팝업 메뉴)가 아직 완전히 사라지기 전에 ReportView를 표시하려고 해서 발생하는 것 같다. 그래서 중간 상태 변수(shouldShowReport)를 두어 팝업 메뉴가 완전히 사라진 후에 ReportView를 표시하도록 하는 것이 해결 방법인 것 같았다.
해결 방법
struct ChallengeImagesGrid: View {
// ... 기존 프로퍼티들 ...
@State private var shouldShowReport: Bool = false // 새로운 상태 변수 추가
var body: some View {
VStack(alignment: .leading, spacing: 12) {
// ... 기존 코드 ...
LazyVGrid(...) {
// ... 기존 코드 ...
ForEach(challengeImages.indices, id: \.self) { index in
AsyncImage(url: URL(string: challengeImages[index].imageUrl)) { phase in
switch phase {
case .success(let image):
image
.resizable()
.aspectRatio(1, contentMode: .fit)
.contextMenu {
Button(role: .destructive, action: {
print("=== 신고하기 버튼 클릭 ===")
print("선택된 이미지 ID:", challengeImages[index].id)
print("이미지 업로더 ID:", challengeImages[index].userId)
selectedImageId = challengeImages[index].id
shouldShowReport = true // contextMenu가 닫힌 후 실행될 상태 변수
}) {
Label("신고하기", systemImage: "exclamationmark.bubble.fill")
}
}
.sensoryFeedback(.impact(weight: .medium), trigger: true)
// ... 나머지 case 문 ...
}
}
}
}
}
.onChange(of: shouldShowReport) { newValue in
if newValue {
showReportView = true
shouldShowReport = false
}
}
.sheet(isPresented: $showReportView) {
if let imageId = selectedImageId {
ReportView(targetType: "L", targetId: imageId)
}
}
}
}
+ 3D 터치 햅틱
let impactGenerator = UIImpactFeedbackGenerator(style: .medium)
impactGenerator.impactOccurred()
햅틱 피드백과 3D Touch/Force Touch의 지원은 기기별로 다르다.
1. 햅틱 피드백 (Haptic Feedback):
- iPhone 7 이상 지원
- SE 1세대는 미지원
- iPad는 미지원
2. 3D Touch/Force Touch:
- iPhone 6S ~ iPhone XS 까지는 3D Touch 지원
- iPhone XR, 11 이후 모델은 Haptic Touch로 대체 (길게 누르기)
- iPad는 길게 누르기로 동작
하지만 나는 모든 기기에서
1. 3D Touch가 있는 기기에서는 3D Touch로
2. 없는 기기에서는 길게 누르기(Haptic Touch)로
3. 햅틱 피드백은 지원하는 기기에서만
import UIKit
let impactGenerator = UIImpactFeedbackGenerator(style: .medium)
impactGenerator.impactOccurred()
오늘 작업 내역
*홈: 백엔드에서 챌린지 기간 다되면 MyOngoingChallenge에서 사라지기
*챌린지 참여 전
- 챌린지 id별로 이미지 보여주기 / 챌린지 사진 꾹 누르면 3d 터치로 신고하기 기능 + 진동(햅틱)
- 홈화면에서 챌린지 랭킹 버그 픽스
-챌린지 참여(백엔드 카운트) 인원 수 백엔드 업데이트(아래로 당기면 새로고침?? )
'프로젝트' 카테고리의 다른 글
챌린지 참여 상태에 따라 UI 변경하기(@ObservedObject, @StateObject) (0) | 2024.12.12 |
---|---|
챌린지 더미 데이터(사진) 만들고 무한 스크롤 구현 (0) | 2024.12.11 |
KeyPath란? (0) | 2024.12.10 |
Instagram, Facebook 같은 앱에서도 사용하는 일반적인 패턴인 페이지네이션이란? (0) | 2024.12.10 |
(고생) VARCHAR(1), CHAR(1) 차이를 모르면... (0) | 2024.11.27 |