Files
Pulse/Sources/PulseUI/Features/FileViewer/RichTextView/RichTextViewSearchToobar-ios.swift
2024-07-14 15:55:18 -04:00

74 lines
2.3 KiB
Swift

// The MIT License (MIT)
//
// Copyright (c) 2020-2024 Alexander Grebenyuk (github.com/kean).
#if os(iOS) || os(visionOS)
import SwiftUI
@available(iOS 15, visionOS 1.0, *)
struct RichTextViewSearchToobar: View {
@ObservedObject var viewModel: RichTextViewModel
@State private var isRealMenuShown = false
var body: some View {
HStack(alignment: .center, spacing: 24) {
options
stepper
}
.padding(12)
.background(Material.regular)
.cornerRadius(8)
.onReceive(Keyboard.isHidden) { _ in
// Show a non-interactive placeholder during animation,
// then show the actual menu when navigation is settled.
withAnimation(nil) {
isRealMenuShown = false
}
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(750)) {
withAnimation(nil) {
isRealMenuShown = true
}
}
}
}
private var options: some View {
ZStack {
Image(systemName: "ellipsis.circle")
.foregroundColor(.accentColor)
.font(.system(size: 20))
.opacity(isRealMenuShown ? 0 : 1)
if isRealMenuShown {
Menu(content: {
StringSearchOptionsMenu(options: $viewModel.searchOptions, isKindNeeded: false)
}, label: {
Image(systemName: "ellipsis.circle")
.font(.system(size: 20))
})
.menuStyle(.borderlessButton)
.fixedSize()
}
}
}
private var stepper: some View {
HStack(spacing: 12) {
Button(action: viewModel.previousMatch) {
Image(systemName: "chevron.left.circle")
.font(.system(size: 20))
}.disabled(viewModel.matches.isEmpty)
Text(viewModel.matches.isEmpty ? "0 of 0" : "\(viewModel.selectedMatchIndex+1) of \(viewModel.matches.count)")
.font(Font.body.monospacedDigit())
Button(action: viewModel.nextMatch) {
Image(systemName: "chevron.right.circle")
.font(.system(size: 20))
}.disabled(viewModel.matches.isEmpty)
}
.fixedSize()
}
}
#endif