Skip to content

Commit

Permalink
Merge pull request #28 from c-villain/support-rtl
Browse files Browse the repository at this point in the history
add support for RTL languages
  • Loading branch information
c-villain authored Aug 29, 2024
2 parents 84c9241 + 47bd4b7 commit f3ceac3
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 64 deletions.
84 changes: 48 additions & 36 deletions Example/iOS/ExampleView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,12 @@ struct ExampleView: View {
.frame(maxWidth: .infinity)
.padding()
.background(Color(UIColor.systemBackground))
.addFullSwipeAction(menu: .slided,
swipeColor: .green,
swipeRole: .defaults,
state: $state) {
.addFullSwipeAction(
menu: .slided,
swipeColor: .green,
swipeRole: .`default`,
state: $state
) {
Leading {
Button {
} label: {
Expand Down Expand Up @@ -123,6 +125,7 @@ struct ExampleView: View {
}
}
}
//.environment(\.layoutDirection, .rightToLeft) //check for TRL languages
.alert(isPresented: $fullSwiped) {
Alert(title: Text(selectedAction),
dismissButton: .default(Text("Archived!")) {
Expand Down Expand Up @@ -156,9 +159,11 @@ struct ExampleView: View {
.contentShape(Rectangle())
.padding()
.background(Color(UIColor.systemBackground))
.addFullSwipeAction(menu: .slided,
swipeColor: .red,
state: $state) {
.addFullSwipeAction(
menu: .slided,
swipeColor: .red,
state: $state
) {
Leading {
Button {
selectedAction = "cell \(cell) checked!"
Expand Down Expand Up @@ -237,10 +242,12 @@ struct ExampleView: View {
.frame(maxWidth: .infinity)
.padding()
.background(Color(UIColor.systemBackground))
.addFullSwipeAction(menu: .slided,
swipeColor: .green,
swipeRole: .defaults,
state: $state) {
.addFullSwipeAction(
menu: .slided,
swipeColor: .green,
swipeRole: .default,
state: $state
) {
Leading {
Button {
} label: {
Expand Down Expand Up @@ -272,12 +279,14 @@ struct ExampleView: View {
}
}
.alert(isPresented: $fullSwiped) {
Alert(title: Text(selectedAction),
dismissButton: .default(Text("Archived!")) {
withAnimation {
state = .swiped(UUID())
Alert(
title: Text(selectedAction),
dismissButton: .default(Text("Archived!")) {
withAnimation {
state = .swiped(UUID())
}
}
})
)
}
}
}
Expand Down Expand Up @@ -310,8 +319,10 @@ struct ExampleView: View {
)
.contentShape(Rectangle())
.listStyle(.plain)
.addSwipeAction(menu: .swiped,
state: $state) {
.addSwipeAction(
menu: .swiped,
state: $state
) {
Leading {
Button {
print("check \(cell)")
Expand Down Expand Up @@ -440,11 +451,11 @@ struct ExampleView: View {
.frame(width: UIScreen.main.bounds.size.width - 32, height: 80)
.contentShape(Rectangle())
.background(Color(UIColor.systemBackground))
.onTapGesture {
}
.addSwipeAction(menu: .swiped,
state: $state) {
.onTapGesture {}
.addSwipeAction(
menu: .swiped,
state: $state
) {
Leading {
Button {
} label: {
Expand All @@ -465,9 +476,8 @@ struct ExampleView: View {
.contentShape(Rectangle())
.background(Color.green)
}
}
.listRowInsets(EdgeInsets())
.hideSeparators()
}.listRowInsets(EdgeInsets())
.hideSeparators()
}
.padding(16)
.listStyle(.plain)
Expand All @@ -482,10 +492,11 @@ struct ExampleView: View {
.padding(.horizontal, 16)
.frame(width: UIScreen.main.bounds.size.width - 32, height: 80)
.background(Color(UIColor.systemBackground))
.onTapGesture {
}
.addSwipeAction(edge: .trailing,
state: $state) {
.onTapGesture {}
.addSwipeAction(
edge: .trailing,
state: $state
) {
Button {
print("remove")
} label: {
Expand All @@ -495,9 +506,8 @@ struct ExampleView: View {
.frame(width: 60, height: 80, alignment: .center)
.contentShape(Rectangle())
.background(Color.red)
}
.listRowInsets(EdgeInsets())
.hideSeparators()
}.listRowInsets(EdgeInsets())
.hideSeparators()

}
.padding(16)
Expand Down Expand Up @@ -577,9 +587,11 @@ struct ExampleView: View {
.contentShape(Rectangle())
.padding()
.background(Color(UIColor.systemBackground))
.addFullSwipeAction(menu: .slided,
swipeColor: .red,
state: $state) {
.addFullSwipeAction(
menu: .slided,
swipeColor: .red,
state: $state
) {
Leading {
Button {
selectedAction = "cell \(cell) checked!"
Expand Down
59 changes: 38 additions & 21 deletions Sources/SwipeActions/SwipeActions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public enum MenuType {
public enum SwipeRole {
case destructive /// for removing element
case cancel
case defaults
case `default`
}

/// For opened cells auto-hiding during swiping anothers
Expand All @@ -27,8 +27,10 @@ private enum VisibleButton: Equatable {
case right(UUID)
}

struct SwipeAction<V1: View, V2: View>: ViewModifier {
public struct SwipeAction<V1: View, V2: View>: ViewModifier {

@Environment(\.layoutDirection) var layoutDirection

@Binding private var state: SwipeState
@State private var offset: CGFloat = 0
@State private var oldOffset: CGFloat = 0
Expand Down Expand Up @@ -64,7 +66,7 @@ struct SwipeAction<V1: View, V2: View>: ViewModifier {
init(
menu: MenuType,
allowsFullSwipe: Bool = false,
fullSwipeRole: SwipeRole = .defaults,
fullSwipeRole: SwipeRole = .default,
swipeColor: Color? = nil,
state: Binding<SwipeState>,
@ViewBuilder _ content: @escaping () -> TupleView<(Leading<V1>, Trailing<V2>)>,
Expand All @@ -83,7 +85,7 @@ struct SwipeAction<V1: View, V2: View>: ViewModifier {
init(
menu: MenuType,
allowsFullSwipe: Bool = false,
fullSwipeRole: SwipeRole = .defaults,
fullSwipeRole: SwipeRole = .default,
swipeColor: Color? = nil,
state: Binding<SwipeState>,
@ViewBuilder leading: @escaping () -> V1,
Expand All @@ -102,7 +104,7 @@ struct SwipeAction<V1: View, V2: View>: ViewModifier {
init(
menu: MenuType,
allowsFullSwipe: Bool = false,
fullSwipeRole: SwipeRole = .defaults,
fullSwipeRole: SwipeRole = .default,
swipeColor: Color? = nil,
state: Binding<SwipeState>,
@ViewBuilder trailing: @escaping () -> V2,
Expand All @@ -118,13 +120,13 @@ struct SwipeAction<V1: View, V2: View>: ViewModifier {
self.action = action
}

func reset() {
private func reset() {
visibleButton = .none
offset = 0
oldOffset = 0
}

var leadingView: some View {
private var leadingView: some View {
leadingSwipeView
.measureSize {
if !maxLeadingOffsetIsCounted {
Expand All @@ -141,7 +143,7 @@ struct SwipeAction<V1: View, V2: View>: ViewModifier {
}
}

var trailingView: some View {
private var trailingView: some View {
trailingSwipeView
.measureSize {
if !minTrailingOffsetIsCounted {
Expand All @@ -158,7 +160,7 @@ struct SwipeAction<V1: View, V2: View>: ViewModifier {
}
}

var swipedMenu: some View {
private var swipedMenu: some View {
HStack(spacing: 0) {
leadingView
Spacer()
Expand All @@ -167,7 +169,7 @@ struct SwipeAction<V1: View, V2: View>: ViewModifier {
}
}

var slidedMenu: some View {
private var slidedMenu: some View {
HStack(spacing: 0) {
leadingView
.offset(x: (-1 * maxLeadingOffset) + offset)
Expand All @@ -177,24 +179,28 @@ struct SwipeAction<V1: View, V2: View>: ViewModifier {
}
}

func gesturedContent(content: Content) -> some View {

private func gesturedContent(content: Content) -> some View {
content
.id(id)
.contentShape(Rectangle()) ///otherwise swipe won't work in vacant area
.offset(x: offset)
.measureSize {
contentWidth = $0.width
}
.gesture(
// DragGesture(minimumDistance: 15, coordinateSpace: .local)
.gesture (
DragGesture(minimumDistance: 15, coordinateSpace: .global)
.updating($dragGestureActive) { value, state, transaction in
state = true
}
.onChanged { value in
let totalSlide = value.translation.width + oldOffset
let totalSlide: Double

switch layoutDirection {
case .rightToLeft:
totalSlide = -value.translation.width - oldOffset
default:
totalSlide = value.translation.width + oldOffset
}
if allowsFullSwipe && ...0 ~= Int(totalSlide) {
withAnimation {
offset = totalSlide
Expand All @@ -205,17 +211,26 @@ struct SwipeAction<V1: View, V2: View>: ViewModifier {
}
}
}.onEnded { value in
let translationWidth: Double

switch layoutDirection {
case .rightToLeft:
translationWidth = -value.translation.width
default:
translationWidth = value.translation.width
}

withAnimation {
if
///user dismisses right buttons
visibleButton == .left(id),
value.translation.width < -20
translationWidth < -20
{
reset()
} else if
///user dismisses right buttons
visibleButton == .right(id),
value.translation.width > 20
translationWidth > 20
{
reset()
} else if
Expand All @@ -239,7 +254,7 @@ struct SwipeAction<V1: View, V2: View>: ViewModifier {

if
allowsFullSwipe,
value.translation.width < -(contentWidth * 0.7)
translationWidth < -(contentWidth * 0.7)
{
withAnimation(.linear(duration: 0.3)) {
offset = -contentWidth
Expand All @@ -260,9 +275,10 @@ struct SwipeAction<V1: View, V2: View>: ViewModifier {

action?()
}
})
.valueChanged(of: dragGestureActive) { dragActive in
print("id: \(id) state: \(state) visibleButton: \(visibleButton) offset: \(offset)")
}
)
.valueChanged(of: dragGestureActive) { _ in
//print("id: \(id) state: \(state) visibleButton: \(visibleButton) offset: \(offset)")
}
.valueChanged(of: state) { value in
switch value {
Expand Down Expand Up @@ -338,3 +354,4 @@ struct SwipeAction<V1: View, V2: View>: ViewModifier {
}
}
}

19 changes: 12 additions & 7 deletions Sources/SwipeActions/ViewModifiers/SwipeHintModifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import SwiftUI

public extension View {
@ViewBuilder
func swipeHint(_ isActive: Bool = false, hintOffset: CGFloat, delayIn: CGFloat = 0.5, delayOut: CGFloat = 1.5) -> some View {
func swipeHint(
_ isActive: Bool = false,
hintOffset: CGFloat,
delayIn: CGFloat = 0.5,
delayOut: CGFloat = 1.5
) -> some View {
if isActive {
modifier(
SwipeHintModifier(
Expand All @@ -27,12 +32,12 @@ public struct SwipeHintModifier: ViewModifier {
content
.offset(x: -offset)
.onAppear {
withAnimation(.easeInOut.delay(delayIn)) {
offset = hintOffset
}
withAnimation(.easeInOut.delay(delayOut)) {
offset = 0
}
withAnimation(.easeInOut.delay(delayIn)) {
offset = hintOffset
}
withAnimation(.easeInOut.delay(delayOut)) {
offset = 0
}
}
}
}

0 comments on commit f3ceac3

Please sign in to comment.