@@ -7,56 +7,88 @@ import SwiftUI
77
88public struct SlidableImage < ArrowsIcon: View , LeftView: View , RightView: View > : View {
99 @State private var location : CGPoint ?
10+ private let axis : Axis
1011 private let arrows : ( ) -> ArrowsIcon
1112 private let leftView : ( ) -> LeftView
1213 private let rightView : ( ) -> RightView
1314
14- public init ( @ViewBuilder arrows: @escaping ( ) -> ArrowsIcon ,
15+ public init ( axis: Axis = . horizontal,
16+ @ViewBuilder arrows: @escaping ( ) -> ArrowsIcon ,
1517 @ViewBuilder leftView: @escaping ( ) -> LeftView ,
1618 @ViewBuilder rightView: @escaping ( ) -> RightView ) {
19+ self . axis = axis
1720 self . arrows = arrows
1821 self . leftView = leftView
1922 self . rightView = rightView
2023 }
2124
2225 public var body : some View {
2326 GeometryReader { geometry in
24- ZStack ( alignment: . leading) {
27+ ZStack ( alignment: axis == . horizontal ? . leading : . top ) {
2528 rightView ( )
2629 leftView ( )
2730 . mask {
28- HStack {
29- Color . black
30- Spacer ( minLength: maskSize ( width: geometry. size. width) )
31+ if axis == . horizontal {
32+ HStack {
33+ Color . black
34+ Spacer ( minLength: maskSize ( total: geometry. size. width) )
35+ }
36+ } else {
37+ VStack {
38+ Color . black
39+ Spacer ( minLength: maskSize ( total: geometry. size. height) )
40+ }
3141 }
3242 }
3343
3444 arrows ( )
3545 . frame ( width: Constants . arrowSize, height: Constants . arrowSize)
36- . padding ( . leading, location? . x ?? geometry. size. width / 2 - Constants. arrowSize / 2 )
46+ . padding ( axis == . horizontal ? . leading : . top,
47+ locationValue ?? defaultOffset ( geometry: geometry) )
3748 . gesture (
3849 DragGesture ( )
3950 . onChanged { value in
40- guard value. location. x <= geometry. size. width - Constants. arrowSize else { return }
41-
42- location = CGPoint ( x: value. location. x, y: geometry. size. height / 2 )
51+ if axis == . horizontal {
52+ let x = min ( max ( value. location. x, 0 ) , geometry. size. width - Constants. arrowSize)
53+ location = CGPoint ( x: x, y: geometry. size. height / 2 )
54+ } else {
55+ let y = min ( max ( value. location. y, 0 ) , geometry. size. height - Constants. arrowSize)
56+ location = CGPoint ( x: geometry. size. width / 2 , y: y)
57+ }
4358 }
4459 )
4560 }
4661 }
4762 }
4863
49- package func maskSize( width: CGFloat , locationX: CGFloat ? = nil ) -> CGFloat {
50- guard let locationX = locationX ?? location? . x else {
51- return width / 2
64+ private var locationValue : CGFloat ? {
65+ axis == . horizontal ? location? . x : location? . y
66+ }
67+
68+ private func defaultOffset( geometry: GeometryProxy ) -> CGFloat {
69+ axis == . horizontal
70+ ? geometry. size. width / 2 - Constants. arrowSize / 2
71+ : geometry. size. height / 2 - Constants. arrowSize / 2
72+ }
73+
74+ package func maskSize( total: CGFloat , locationValue: CGFloat ? = nil ) -> CGFloat {
75+ guard let value = locationValue ?? self . locationValue else {
76+ return total / 2
5277 }
5378
54- return width - locationX - Constants. arrowSize / 2
79+ return total - value - Constants. arrowSize / 2
5580 }
5681}
5782
5883#Preview {
59- SlidableImage ( arrows: { Arrows ( ) } ,
60- leftView: { Color . red } ,
61- rightView: { Color . green } )
84+ VStack {
85+ SlidableImage ( arrows: { Arrows ( ) } ,
86+ leftView: { Color . red } ,
87+ rightView: { Color . green } )
88+
89+ SlidableImage ( axis: . vertical,
90+ arrows: { Arrows ( ) } ,
91+ leftView: { Color . blue } ,
92+ rightView: { Color . orange } )
93+ }
6294}
0 commit comments