Skip to content

Commit

Permalink
feat: Adding ability to hide and show tooltips.
Browse files Browse the repository at this point in the history
  • Loading branch information
danielbaldwin-ltk committed Apr 20, 2022
1 parent b1f0d41 commit 13f2261
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 52 deletions.
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import PackageDescription

let package = Package(
name: "SwiftUITooltip",
name: "SwiftUITooltipRS",
platforms: [
.iOS(.v13), .macOS(.v10_15), .tvOS(.v13), .watchOS(.v6)
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ public struct DefaultTooltipConfig: TooltipConfig {

public var borderRadius: CGFloat = 8
public var borderWidth: CGFloat = 2
public var borderColor: Color = Color.primary
public var backgroundColor: Color = Color.clear
public var borderColor: Color = Color.black
public var backgroundColor: Color = Color.black

public var contentPaddingLeft: CGFloat = 8
public var contentPaddingRight: CGFloat = 8
Expand Down
59 changes: 26 additions & 33 deletions Sources/SwiftUITooltip/TooltipModifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,19 @@
import SwiftUI

struct TooltipModifier<TooltipContent: View>: ViewModifier {

// MARK: - Uninitialised properties

var config: TooltipConfig
var content: TooltipContent

/// Indicates whether tooltips are displayed.
@Binding var isPresented: Bool

// MARK: - Initialisers

init(config: TooltipConfig, @ViewBuilder content: @escaping () -> TooltipContent) {
init(isPresented: Binding<Bool>, config: TooltipConfig, @ViewBuilder content: @escaping () -> TooltipContent) {
_isPresented = isPresented
self.config = config
self.content = content()
}
Expand All @@ -24,7 +29,7 @@ struct TooltipModifier<TooltipContent: View>: ViewModifier {

@State private var contentWidth: CGFloat = 10
@State private var contentHeight: CGFloat = 10

@State var animationOffset: CGFloat = 0

// MARK: - Computed properties
Expand Down Expand Up @@ -97,16 +102,16 @@ struct TooltipModifier<TooltipContent: View>: ViewModifier {
return (g.size.height - contentHeight) / 2
}
}

// MARK: - Animation stuff

private func dispatchAnimation() {
if (config.enableAnimation) {
DispatchQueue.main.asyncAfter(deadline: .now() + config.animationTime) {
self.animationOffset = config.animationOffset
DispatchQueue.main.asyncAfter(deadline: .now() + config.animationTime*0.1) {
self.animationOffset = 0

self.dispatchAnimation()
}
}
Expand Down Expand Up @@ -134,7 +139,6 @@ struct TooltipModifier<TooltipContent: View>: ViewModifier {
.rotation(Angle(radians: self.arrowRotation))
.frame(width: self.config.arrowWidth+2, height: self.config.arrowHeight+1)
.foregroundColor(self.config.backgroundColor)

).frame(width: self.config.arrowWidth, height: self.config.arrowHeight)
.offset(x: self.arrowOffsetX, y: self.arrowOffsetY)
}
Expand Down Expand Up @@ -163,23 +167,26 @@ struct TooltipModifier<TooltipContent: View>: ViewModifier {
var tooltipBody: some View {
GeometryReader { g in
ZStack {
RoundedRectangle(cornerRadius: self.config.borderRadius)
.stroke(self.config.borderWidth == 0 ? Color.clear : self.config.borderColor)
.background(RoundedRectangle(cornerRadius: self.config.borderRadius)
.foregroundColor(self.config.backgroundColor))
.frame(width: self.contentWidth, height: self.contentHeight)
.mask(self.arrowCutoutMask)

ZStack {
content
.padding(self.config.contentPaddingEdgeInsets)
.fixedSize()
}
.background(self.sizeMeasurer)
if isPresented {
RoundedRectangle(cornerRadius: self.config.borderRadius)
.stroke(self.config.borderWidth == 0 ? Color.clear : self.config.borderColor)
.background(RoundedRectangle(cornerRadius: self.config.borderRadius)
.foregroundColor(self.config.backgroundColor))
.frame(width: self.contentWidth, height: self.contentHeight)
.mask(self.arrowCutoutMask)

ZStack {
content
.padding(self.config.contentPaddingEdgeInsets)
.fixedSize()
}
.background(self.sizeMeasurer)
.overlay(self.arrowView)
}
}
.offset(x: self.offsetHorizontal(g), y: self.offsetVertical(g))
.animation(.easeInOut)
.opacity(isPresented ? 1 : 0)
.onAppear {
self.dispatchAnimation()
}
Expand All @@ -193,17 +200,3 @@ struct TooltipModifier<TooltipContent: View>: ViewModifier {
.overlay(tooltipBody)
}
}

struct Tooltip_Previews: PreviewProvider {
static var previews: some View {
var config = DefaultTooltipConfig(side: .top)
config.backgroundColor = Color(red: 0.8, green: 0.9, blue: 1)


return VStack {
Text("Say...").tooltip(config: config) {
Text("Something nice!")
}
}.previewDevice(.init(stringLiteral: "iPhone 12 mini"))
}
}
32 changes: 16 additions & 16 deletions Sources/SwiftUITooltip/TooltipViewExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,27 @@
import SwiftUI

public extension View {
func tooltip<TooltipContent: View>(@ViewBuilder content: @escaping () -> TooltipContent) -> some View {
func tooltip<TooltipContent: View>(isPresented: Binding<Bool>, @ViewBuilder content: @escaping () -> TooltipContent) -> some View {
let config: TooltipConfig = DefaultTooltipConfig.shared

return modifier(TooltipModifier(config: config, content: content))
return modifier(TooltipModifier(isPresented: isPresented, config: config, content: content))
}

func tooltip<TooltipContent: View>(config: TooltipConfig, @ViewBuilder content: @escaping () -> TooltipContent) -> some View {
modifier(TooltipModifier(config: config, content: content))
}
func tooltip<TooltipContent: View>(isPresented: Binding<Bool>, config: TooltipConfig, @ViewBuilder content: @escaping () -> TooltipContent) -> some View {
modifier(TooltipModifier(isPresented: isPresented, config: config, content: content))
}

func tooltip<TooltipContent: View>(_ side: TooltipSide, @ViewBuilder content: @escaping () -> TooltipContent) -> some View {
var config = DefaultTooltipConfig.shared
config.side = side
func tooltip<TooltipContent: View>(isPresented: Binding<Bool>, _ side: TooltipSide, @ViewBuilder content: @escaping () -> TooltipContent) -> some View {
var config = DefaultTooltipConfig.shared
config.side = side

return modifier(TooltipModifier(config: config, content: content))
}

func tooltip<TooltipContent: View>(_ side: TooltipSide, config: TooltipConfig, @ViewBuilder content: @escaping () -> TooltipContent) -> some View {
var config = config
config.side = side
return modifier(TooltipModifier(isPresented: isPresented, config: config, content: content))
}

return modifier(TooltipModifier(config: config, content: content))
}
func tooltip<TooltipContent: View>(isPresented: Binding<Bool>, _ side: TooltipSide, config: TooltipConfig, @ViewBuilder content: @escaping () -> TooltipContent) -> some View {
var config = config
config.side = side

return modifier(TooltipModifier(isPresented: isPresented, config: config, content: content))
}
}

0 comments on commit 13f2261

Please sign in to comment.