@@ -28,26 +28,27 @@ struct TooltipModifier<TooltipContent: View>: ViewModifier {
2828 @State private var contentHeight : CGFloat = 10
2929
3030 @State var animationOffset : CGFloat = 0
31+ @State var animation : Optional < Animation > = nil
3132
3233 // MARK: - Computed properties
3334
34- var arrowRotation : Double { Double ( config. side . rawValue ) * . pi / 4 }
35- var actualArrowHeight : CGFloat { config . showArrow ? config. arrowHeight : 0 }
35+ var showArrow : Bool { config. showArrow && config . side . shouldShowArrow ( ) }
36+ var actualArrowHeight : CGFloat { self . showArrow ? config. arrowHeight : 0 }
3637
3738 var arrowOffsetX : CGFloat {
3839 switch config. side {
3940 case . bottom, . center, . top:
4041 return 0
41- case . leading :
42+ case . left :
4243 return ( contentWidth / 2 + config. arrowHeight / 2 )
43- case . leadingTop , . leadingBottom :
44+ case . topLeft , . bottomLeft :
4445 return ( contentWidth / 2
4546 + config. arrowHeight / 2
4647 - config. borderRadius / 2
4748 - config. borderWidth / 2 )
48- case . trailing :
49+ case . right :
4950 return - ( contentWidth / 2 + config. arrowHeight / 2 )
50- case . trailingTop , . trailingBottom :
51+ case . topRight , . bottomRight :
5152 return - ( contentWidth / 2
5253 + config. arrowHeight / 2
5354 - config. borderRadius / 2
@@ -57,18 +58,18 @@ struct TooltipModifier<TooltipContent: View>: ViewModifier {
5758
5859 var arrowOffsetY : CGFloat {
5960 switch config. side {
60- case . leading , . center, . trailing :
61+ case . left , . center, . right :
6162 return 0
6263 case . top:
6364 return ( contentHeight / 2 + config. arrowHeight / 2 )
64- case . trailingTop , . leadingTop :
65+ case . topRight , . topLeft :
6566 return ( contentHeight / 2
6667 + config. arrowHeight / 2
6768 - config. borderRadius / 2
6869 - config. borderWidth / 2 )
6970 case . bottom:
7071 return - ( contentHeight / 2 + config. arrowHeight / 2 )
71- case . leadingBottom , . trailingBottom :
72+ case . bottomLeft , . bottomRight :
7273 return - ( contentHeight / 2
7374 + config. arrowHeight / 2
7475 - config. borderRadius / 2
@@ -80,9 +81,9 @@ struct TooltipModifier<TooltipContent: View>: ViewModifier {
8081
8182 private func offsetHorizontal( _ g: GeometryProxy ) -> CGFloat {
8283 switch config. side {
83- case . leading , . leadingTop , . leadingBottom :
84+ case . left , . topLeft , . bottomLeft :
8485 return - ( contentWidth + config. margin + actualArrowHeight + animationOffset)
85- case . trailing , . trailingTop , . trailingBottom :
86+ case . right , . topRight , . bottomRight :
8687 return g. size. width + config. margin + actualArrowHeight + animationOffset
8788 case . top, . center, . bottom:
8889 return ( g. size. width - contentWidth) / 2
@@ -91,11 +92,11 @@ struct TooltipModifier<TooltipContent: View>: ViewModifier {
9192
9293 private func offsetVertical( _ g: GeometryProxy ) -> CGFloat {
9394 switch config. side {
94- case . top, . trailingTop , . leadingTop :
95+ case . top, . topRight , . topLeft :
9596 return - ( contentHeight + config. margin + actualArrowHeight + animationOffset)
96- case . bottom, . leadingBottom , . trailingBottom :
97+ case . bottom, . bottomLeft , . bottomRight :
9798 return g. size. height + config. margin + actualArrowHeight + animationOffset
98- case . leading , . center, . trailing :
99+ case . left , . center, . right :
99100 return ( g. size. height - contentHeight) / 2
100101 }
101102 }
@@ -106,6 +107,7 @@ struct TooltipModifier<TooltipContent: View>: ViewModifier {
106107 if ( config. enableAnimation) {
107108 DispatchQueue . main. asyncAfter ( deadline: . now( ) + config. animationTime) {
108109 self . animationOffset = config. animationOffset
110+ self . animation = config. animation
109111 DispatchQueue . main. asyncAfter ( deadline: . now( ) + config. animationTime*0. 1 ) {
110112 self . animationOffset = 0
111113
@@ -121,66 +123,91 @@ struct TooltipModifier<TooltipContent: View>: ViewModifier {
121123 GeometryReader { g in
122124 Text ( " " )
123125 . onAppear {
124- self . contentWidth = g. size. width
125- self . contentHeight = g. size. height
126+ self . contentWidth = config . width ?? g. size. width
127+ self . contentHeight = config . height ?? g. size. height
126128 }
127129 }
128130 }
129131
130132 private var arrowView : some View {
131- return ArrowShape ( )
132- . rotation ( Angle ( radians: self . arrowRotation) )
133- . stroke ( self . config. borderColor)
133+ guard let arrowAngle = config. side. getArrowAngleRadians ( ) else {
134+ return AnyView ( EmptyView ( ) )
135+ }
136+
137+ return AnyView ( ArrowShape ( )
138+ . rotation ( Angle ( radians: arrowAngle) )
139+ . stroke ( config. borderColor)
134140 . background ( ArrowShape ( )
135141 . offset ( x: 0 , y: 1 )
136- . rotation ( Angle ( radians: self . arrowRotation ) )
137- . frame ( width: self . config. arrowWidth+ 2 , height: self . config. arrowHeight+ 1 )
138- . foregroundColor ( self . config. backgroundColor)
142+ . rotation ( Angle ( radians: arrowAngle ) )
143+ . frame ( width: config. arrowWidth+ 2 , height: config. arrowHeight+ 1 )
144+ . foregroundColor ( config. backgroundColor)
139145
140- ) . frame ( width: self . config. arrowWidth, height: self . config. arrowHeight)
141- . offset ( x: self . arrowOffsetX, y: self . arrowOffsetY)
146+ ) . frame ( width: config. arrowWidth, height: config. arrowHeight)
147+ . offset ( x: self . arrowOffsetX, y: self . arrowOffsetY) )
142148 }
143149
144150 private var arrowCutoutMask : some View {
145- return ZStack {
146- Rectangle ( )
147- . frame (
148- width: self . contentWidth + self . config. borderWidth * 2 ,
149- height: self . contentHeight + self . config. borderWidth * 2 )
150- . foregroundColor ( . white)
151- Rectangle ( )
152- . frame (
153- width: self . config. arrowWidth,
154- height: self . config. arrowHeight + self . config. borderWidth)
155- . rotationEffect ( Angle ( radians: self . arrowRotation) )
156- . offset (
157- x: self . arrowOffsetX,
158- y: self . arrowOffsetY)
159- . foregroundColor ( . black)
151+ guard let arrowAngle = config. side. getArrowAngleRadians ( ) else {
152+ return AnyView ( EmptyView ( ) )
160153 }
161- . compositingGroup ( )
162- . luminanceToAlpha ( )
154+
155+ return AnyView (
156+ ZStack {
157+ Rectangle ( )
158+ . frame (
159+ width: self . contentWidth + config. borderWidth * 2 ,
160+ height: self . contentHeight + config. borderWidth * 2 )
161+ . foregroundColor ( . white)
162+ Rectangle ( )
163+ . frame (
164+ width: config. arrowWidth,
165+ height: config. arrowHeight + config. borderWidth)
166+ . rotationEffect ( Angle ( radians: arrowAngle) )
167+ . offset (
168+ x: self . arrowOffsetX,
169+ y: self . arrowOffsetY)
170+ . foregroundColor ( . black)
171+ }
172+ . compositingGroup ( )
173+ . luminanceToAlpha ( )
174+ )
163175 }
164176
165177 var tooltipBody : some View {
166178 GeometryReader { g in
167179 ZStack {
168- RoundedRectangle ( cornerRadius: self . config. borderRadius)
169- . stroke ( self . config. borderWidth == 0 ? Color . clear : self . config. borderColor)
170- . background ( RoundedRectangle ( cornerRadius: self . config. borderRadius)
171- . foregroundColor ( self . config. backgroundColor) )
172- . frame ( width: self . contentWidth, height: self . contentHeight)
180+ RoundedRectangle ( cornerRadius: config. borderRadius)
181+ . stroke ( config. borderWidth == 0 ? Color . clear : config. borderColor)
182+ . frame (
183+ minWidth: contentWidth,
184+ idealWidth: contentWidth,
185+ maxWidth: config. width,
186+ minHeight: contentHeight,
187+ idealHeight: contentHeight,
188+ maxHeight: config. height
189+ )
190+ . background (
191+ RoundedRectangle ( cornerRadius: config. borderRadius)
192+ . foregroundColor ( config. backgroundColor)
193+ )
173194 . mask ( self . arrowCutoutMask)
174195
175196 ZStack {
176197 content
177- . padding ( self . config. contentPaddingEdgeInsets)
178- . fixedSize ( )
198+ . padding ( config. contentPaddingEdgeInsets)
199+ . frame (
200+ width: config. width,
201+ height: config. height
202+ )
203+ . fixedSize ( horizontal: config. width == nil , vertical: true )
179204 }
180205 . background ( self . sizeMeasurer)
181- . overlay ( self . arrowView)
206+ . overlay ( self . arrowView)
182207 }
183208 . offset ( x: self . offsetHorizontal ( g) , y: self . offsetVertical ( g) )
209+ . animation ( self . animation)
210+ . zIndex ( config. zIndex)
184211 . onAppear {
185212 self . dispatchAnimation ( )
186213 }
@@ -198,7 +225,12 @@ struct TooltipModifier<TooltipContent: View>: ViewModifier {
198225struct Tooltip_Previews : PreviewProvider {
199226 static var previews : some View {
200227 var config = DefaultTooltipConfig ( side: . top)
201- config. backgroundColor = Color ( red: 0.8 , green: 0.9 , blue: 1 )
228+ config. enableAnimation = false
229+ // config.backgroundColor = Color(red: 0.8, green: 0.9, blue: 1)
230+ // config.animationOffset = 10
231+ // config.animationTime = 1
232+ // config.width = 120
233+ // config.height = 80
202234
203235
204236 return VStack {
0 commit comments