Last active
March 4, 2022 11:54
-
-
Save niaeashes/d8f7f17c56f2ccd444032b0145b62283 to your computer and use it in GitHub Desktop.
Revisions
-
niaeashes revised this gist
Mar 4, 2022 . 1 changed file with 32 additions and 26 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,19 +1,5 @@ import SwiftUI struct OffsetKey: PreferenceKey { static var defaultValue: CGFloat = .zero static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) { @@ -23,10 +9,7 @@ struct OffsetKey: PreferenceKey { struct ContentView: View { @Namespace var scrollId var body: some View { ScrollView { @@ -39,13 +22,7 @@ struct ContentView: View { .padding() .compositingGroup() } .modifier(proxy.capturer) ForEach(0..<10, id: \.self) { i in Text("No.\(i)").padding() } } GeometryReader { geometry in @@ -57,11 +34,9 @@ struct ContentView: View { OverlayView() }) .onPreferenceChange(OffsetKey.self) { _ in withAnimation { proxy.hide() } } } } .coordinateSpace(name: scrollId) } @@ -78,11 +53,13 @@ struct TooltipReader<Content: View>: View { var body: some View { content(proxy) .coordinateSpace(name: proxy.contentId) .environmentObject(proxy) } } class TooltipProxy: ObservableObject { var isPresented = false { willSet { if isPresented != newValue { @@ -92,6 +69,8 @@ class TooltipProxy: ObservableObject { } @Published var frame: CGRect = .zero var contentId = UUID() func focus(frame: CGRect) { self.frame = frame } @@ -107,6 +86,33 @@ class TooltipProxy: ObservableObject { func hide() { isPresented = false } var capturer: some ViewModifier { FrameCaptureModifier(proxy: self) } struct RectKey: PreferenceKey { static var defaultValue: CGRect = .zero static func reduce(value: inout CGRect, nextValue: () -> CGRect) { value = nextValue() } } struct FrameCaptureModifier: ViewModifier { let proxy: TooltipProxy func body(content: Content) -> some View { content .background(GeometryReader { geometry in Color.clear .preference(key: RectKey.self, value: geometry.frame(in: .named(proxy.contentId))) .onPreferenceChange(RectKey.self) { proxy.focus(frame: $0) } }) } } } struct TooltipModifier<Tooltip: View>: ViewModifier { -
niaeashes revised this gist
Mar 4, 2022 . 1 changed file with 77 additions and 31 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -24,64 +24,110 @@ struct OffsetKey: PreferenceKey { struct ContentView: View { @State var size: CGSize? = nil @Namespace var scrollId @Namespace var contentId var body: some View { ScrollView { TooltipReader { proxy in ZStack { VStack { ForEach(0..<10, id: \.self) { i in Text("No.\(i)").padding() } Button(action: { withAnimation { proxy.toggle() } }) { Text("Hello, world!") .padding() .compositingGroup() } .background(GeometryReader { geometry in Color.clear .preference(key: RectKey.self, value: geometry.frame(in: .named(contentId))) .onPreferenceChange(RectKey.self) { proxy.focus(frame: $0) } }) ForEach(0..<10, id: \.self) { i in Text("No.\(i)").padding() } } GeometryReader { geometry in Color.clear.preference(key: OffsetKey.self, value: geometry.frame(in: .named(scrollId)).minY) } .frame(height: 0) } .modifier(TooltipModifier { OverlayView() }) .onPreferenceChange(OffsetKey.self) { _ in print(Date(), "Change offset!!!") withAnimation { proxy.hide() } } } .coordinateSpace(name: contentId) } .coordinateSpace(name: scrollId) } } struct TooltipReader<Content: View>: View { let content: (TooltipProxy) -> Content @StateObject var proxy = TooltipProxy() init(@ViewBuilder content: @escaping (TooltipProxy) -> Content) { self.content = content } var body: some View { content(proxy) .environmentObject(proxy) } } class TooltipProxy: ObservableObject { var isPresented = false { willSet { if isPresented != newValue { objectWillChange.send() } } } @Published var frame: CGRect = .zero func focus(frame: CGRect) { self.frame = frame } func toggle() { isPresented.toggle() } func show() { isPresented = true } func hide() { isPresented = false } } struct TooltipModifier<Tooltip: View>: ViewModifier { let tooltip: Tooltip @EnvironmentObject var proxy: TooltipProxy init(@ViewBuilder tooltip: () -> Tooltip) { self.tooltip = tooltip() } var frame: CGRect { proxy.frame } func body(content: Content) -> some View { ZStack { content if proxy.isPresented { tooltip .position(x: frame.midX, y: frame.midY - frame.height - 16) } } } } -
niaeashes revised this gist
Mar 4, 2022 . 1 changed file with 49 additions and 19 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,6 +7,13 @@ struct SizeKey: PreferenceKey { } } struct RectKey: PreferenceKey { static var defaultValue: CGRect = .zero static func reduce(value: inout CGRect, nextValue: () -> CGRect) { value = nextValue() } } struct OffsetKey: PreferenceKey { static var defaultValue: CGFloat = .zero static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) { @@ -18,41 +25,63 @@ struct ContentView: View { @State var size: CGSize? = nil @State var showOverlay = false @State var buttonFrame: CGRect = .zero @Namespace var scrollId @Namespace var contentId var body: some View { ScrollView { ZStack { VStack { ForEach(0..<10, id: \.self) { i in Text("No.\(i)").padding() } Button(action: { withAnimation { showOverlay.toggle() } }) { Text("Hello, world!") .padding() .compositingGroup() } .background(GeometryReader { geometry in Color.clear .preference(key: RectKey.self, value: geometry.frame(in: .named(contentId))) .onPreferenceChange(RectKey.self) { buttonFrame = $0 } }) ForEach(0..<10, id: \.self) { i in Text("No.\(i)").padding() } } GeometryReader { geometry in Color.clear.preference(key: OffsetKey.self, value: geometry.frame(in: .named(scrollId)).minY) } .frame(height: 0) } .modifier(TooltipModifier(frame: buttonFrame) { OverlayView() }) .coordinateSpace(name: contentId) } .coordinateSpace(name: scrollId) .onPreferenceChange(OffsetKey.self) { _ in print(Date(), "Change offset!!!") withAnimation { showOverlay = false } } } } struct TooltipModifier<Tooltip: View>: ViewModifier { let tooltip: Tooltip let frame: CGRect init(frame: CGRect, @ViewBuilder tooltip: () -> Tooltip) { self.frame = frame self.tooltip = tooltip() } func body(content: Content) -> some View { ZStack { content tooltip .position(x: frame.midX, y: frame.midY - frame.height - 16) } } } @@ -61,9 +90,10 @@ struct OverlayView: View { var body: some View { Button(action: { print("Tap!!!") }) { Text("Can you tap this button?") .padding() } .background(Color(UIColor.systemBackground)) .clipShape(Capsule()) .contentShape(Capsule()) .overlay(Capsule().stroke(Color.accentColor, lineWidth: 2)) -
niaeashes renamed this gist
Mar 4, 2022 . 1 changed file with 5 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -25,9 +25,6 @@ struct ContentView: View { var body: some View { ScrollView { ZStack { VStack { GeometryReader { geometry in Button(action: { withAnimation { showOverlay.toggle() } }) { @@ -46,12 +43,16 @@ struct ContentView: View { .overlay(OverlayView().opacity(showOverlay ? 1.0 : 0).offset(x: 0, y: -(size?.height ?? 0) - 16)) ForEach(0..<30, id: \.self) { i in Text("No.\(i)").padding() } } GeometryReader { geometry in Color.clear.preference(key: OffsetKey.self, value: geometry.frame(in: .named(scrollId)).minY) } .frame(height: 0) } } .coordinateSpace(name: scrollId) .onPreferenceChange(OffsetKey.self) { offset = $0 print(Date(), "Change offset!!!") } } } -
niaeashes created this gist
Mar 4, 2022 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,76 @@ import SwiftUI struct SizeKey: PreferenceKey { static var defaultValue: CGSize = .zero static func reduce(value: inout CGSize, nextValue: () -> CGSize) { value = nextValue() } } struct OffsetKey: PreferenceKey { static var defaultValue: CGFloat = .zero static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) { value = nextValue() } } struct ContentView: View { @State var size: CGSize? = nil @State var showOverlay = false @State var offset: CGFloat = .zero @Namespace var scrollId var body: some View { ScrollView { ZStack { GeometryReader { geometry in Color.clear.preference(key: OffsetKey.self, value: geometry.frame(in: .named(scrollId)).minY) } VStack { GeometryReader { geometry in Button(action: { withAnimation { showOverlay.toggle() } }) { Text("Hello, world!") .padding() .compositingGroup() } .background(GeometryReader { geometry in Color.clear .preference(key: SizeKey.self, value: geometry.size) .onPreferenceChange(SizeKey.self) { size = $0 } }) } .frame(width: size?.width, height: size?.height) .border(Color.red) .overlay(OverlayView().opacity(showOverlay ? 1.0 : 0).offset(x: 0, y: -(size?.height ?? 0) - 16)) ForEach(0..<30, id: \.self) { i in Text("No.\(i)").padding() } } } } .coordinateSpace(name: scrollId) .onPreferenceChange(OffsetKey.self) { offset = $0 print("Change offset!!!") } } } struct OverlayView: View { var body: some View { Button(action: { print("Tap!!!") }) { Text("Tap") .padding() } .clipShape(Capsule()) .contentShape(Capsule()) .overlay(Capsule().stroke(Color.accentColor, lineWidth: 2)) } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }