'Need to fix tooltip view position
Here I want to show the tooltip on of tap in the button. The position of the tooltip should be just the top of the TooTipButton
and should have the dynamic height to the message text. It is used in many places in 'HStack', 'VStack's with the other content. It should fit in the layout.
For example here the code has HStack
inside that Text
and TooTipButton
. But it does not show the Text component with the text Created by Me
import SwiftUI
import Combine
struct ContentView: View {
@State var showing = false
var body: some View {
GeometryReader { reader in
VStack {
HStack {
Text("Created by Me")
TooTipButton(message: "hey.!! here is some view.", proxy: reader)
}
Spacer()
}
}
}
}
struct ToolTipMessage<Presenting>: View where Presenting: View {
@Binding var isShowing: Bool
let presenting: () -> Presenting
let text: String
let proxy: GeometryProxy
var body: some View {
ZStack(alignment: .center) {
self.presenting()
Group {
Text(text)
.font(.body)
.padding(.horizontal)
.padding(.vertical, 8)
.multilineTextAlignment(.center)
.foregroundColor(.white)
.shadow(radius: 6)
.background(Color(.systemBlue).opacity(0.96) )
.cornerRadius(20)
.transition(.slide)
.opacity(self.isShowing ? 1 : 0)
}.frame(width: proxy.size.width)
}
.onReceive(Just(isShowing)) { shwoing in
if shwoing {
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
self.isShowing = false
}
}
}
.onTapGesture {
self.isShowing = false
}
}
}
extension View {
func toast(isShowing: Binding<Bool>, text: String, proxy: GeometryProxy) -> some View {
ToolTipMessage(isShowing: isShowing,
presenting: { self },
text: text,
proxy: proxy)
}
}
struct TooTipButton: View {
let message: String
@State var showMessage = false
let proxy: GeometryProxy
var body: some View {
Button {
showMessage = true
} label: {
Image(systemName: "exclamationmark.circle.fill")
.foregroundColor(.red)
}
.toast(isShowing: $showMessage, text: message, proxy: proxy)
}
}
Solution 1:[1]
Using .overlay
and .offset
should help:
struct ToolTipMessage<Presenting>: View where Presenting: View {
@Binding var isShowing: Bool
let presenting: () -> Presenting
let text: String
let proxy: GeometryProxy
var body: some View {
ZStack(alignment: .center) {
self.presenting()
.overlay {
Text(text)
.font(.body)
.padding(.horizontal)
.padding(.vertical, 8)
.multilineTextAlignment(.center)
.foregroundColor(.white)
.shadow(radius: 6)
.background(Color(.systemBlue).opacity(0.96) )
.cornerRadius(20)
.transition(.slide)
.opacity(self.isShowing ? 1 : 0)
.frame(width: proxy.size.width)
.offset(x: 0, y: -30)
}
}
.onReceive(Just(isShowing)) { shwoing in
if shwoing {
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
self.isShowing = false
}
}
}
.onTapGesture {
self.isShowing = false
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | ChrisR |