안녕하세요. iOSangBong입니다.
오늘은 ScrollView + ForEach에서 SwipeAction을
사용할 수 있도록 커스텀 UI에 대해 알아보도록 하겠습니다~!
일단 기존 apple에서 제공하고 있는 swipeActions가 있는데요.
https://developer.apple.com/documentation/swiftui/view/swipeactions(edge:allowsfullswipe:content:)
이것을 사용하면 List에서 손쉽게 스와이프 액션을 만들 수 있습니다.
하지만 저는 프로젝트를 진행하면서
List 대신 ScollView와 ForEach의 조합을 사용하고 있습니다.
왜냐면 List는 UI를 프로젝트의 요구사항에 맞게 꾸며줄 수 없기 때문이죠...
그래서 찾아보니 저와 같이 ScrollView + ForEach에
사용할 수 있는 SwipeAction을 고맙게도
먼저 개발해주신 분이 있었습니다.
https://github.com/c-villain/SwipeActions
간단하게 SPM으로 라이브러리를 받아준 다음
import SwipeActions를 해주면 됩니다.
간단하게 샘플 코드를 짜보자면
import SwiftUI
import SwipeActions
struct ContentView: View {
@State var list = ["item1", "item2", "item3", "item4", "item5", "item6"]
@State private var offsets = [CGSize](repeating: CGSize.zero, count: 6)
@State var state: SwipeState = .untouched // <=== HERE
var body: some View {
VStack {
ForEach(list.indices, id: \.self) { index in
Text(list[index])
.id("\(index)")
.frame(height: 50, alignment: .center)
.frame(maxWidth: .infinity)
.background(Color.blue)
.onTapGesture {
print("\(index)")
}
.addSwipeAction(menu: .slided ,edge: .trailing, state: $state) { // <== HERE! choose .trailing or .leading
Button {
print("remove")
} label: {
Image(systemName: "trash")
.foregroundColor(.white)
}
.frame(width: 60, height: 50, alignment: .center)
.contentShape(Rectangle())
.background(Color.red)
Button {
print("Inform")
} label: {
Image(systemName: "bell.slash.fill")
.foregroundColor(.white)
}
.frame(width: 60, height: 50, alignment: .center)
.background(Color.blue)
}
}
.padding(.horizontal, 10)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.white)
}
}
이런식으로 만들 수가 있는데요
그러나 몇가지 불편한 점이 있었는데요.
1. 다른 View를 터치시 스와이프 종료를 할 수 없다.
2. slided타입을 사용하면 아래와 같이 나오는 걸 볼 수 있습니다.
그래서 두가지 항목을 수정해보도록 하겠습니다.
1번을 해결하기 위해서
swipeEnd를 추가해줬습니다.
스와이프된 View외의 다른 View를 터치시
self.state = .swipeEnd를 해주면 스와이프가 종료가 됩니다.
그리고 2번을 해결해주기 위해
둥근 모양으로 잘라주었습니다.
그 결과는?
성공적으로
원하는 데로 다른 View를 터치시 스와이프도 종료되고
오른쪽에 버튼이 나오지 않고 있습니다~!
참고를 위해 코드와 깃헙을 올려놓겠습니다
이걸 프로젝트에 잘 활용해 보세요~
import SwiftUI
import BongStorage
struct SwipeView: View {
@State var list = ["item1", "item2", "item3", "item4", "item5", "item6"]
@State private var offsets = [CGSize](repeating: CGSize.zero, count: 6)
@State var state: BongSwipeState = .untouched // <=== HERE
var body: some View {
VStack {
ForEach(list.indices, id: \.self) { index in
Text(list[index])
.id("\(index)")
.frame(height: 50, alignment: .center)
.frame(maxWidth: .infinity)
.background(Color.blue)
.onTapGesture {
print("\(index)")
self.state = .swipeEnd
}
.bongSwipeAction(edge: .trailing, state: $state) {
HStack(spacing: .zero) {
Button {
state = .swipeEnd
print("remove")
list.remove(at: index)
} label: {
Image(systemName: "trash")
.foregroundColor(.white)
}
.frame(width: 60, height: 50)
.background(Color.red)
Button {
print("Inform")
} label: {
Image(systemName: "bell.slash.fill")
.foregroundColor(.white)
}
.frame(width: 60, height: 50, alignment: .center)
.background(Color.blue)
}
}
.clipShape(RoundedRectangle(cornerRadius: 10))
}
.padding(.horizontal, 10)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.white)
.onTapGesture {
self.state = .swipeEnd
}
}
}
https://github.com/bongbong9708/BongStorage
다들 즐코딩하세요. 그럼 이만~
'SwiftUI > 3. 커스텀 UI' 카테고리의 다른 글
[iOS][SwiftUI] Custom SideMenu 간단하게 만들기 (0) | 2023.08.10 |
---|---|
[iOS][SwiftUI] Custom 하단시트 간단하게 만들기 (0) | 2023.08.03 |
[iOS][SwiftUI] Custom Alert 간단하게 만들기 (0) | 2023.07.19 |