Ferrite-backup/Ferrite/Views/CommonViews/Modifiers/CustomScopeBar.swift
kingbri 0661ed66f3 Search: Fix picker overlay and position
iOS 14 requires the scope bar modifier to be on the first subview of
the NavView. This is because a VStack wraps the content.

A bug was that the segmented picker was being overlaid due to the
scope bar modifier having an AppStorage call. The AppStorage call
updated the modifier which for some reason added another HostingView.

I am not sure why this happens, but avoid using AppStorage in the modifier
to make sure this doesn't happen again.

Signed-off-by: kingbri <bdashore3@proton.me>
2023-02-28 19:42:20 -05:00

68 lines
2.9 KiB
Swift

//
// SearchAppearance.swift
// Ferrite
//
// Created by Brian Dashore on 2/14/23.
//
import SwiftUI
import Introspect
struct CustomScopeBarModifier<V: View>: ViewModifier {
let hostingContent: V
@State private var hostingController: UIHostingController<V>?
// Don't use AppStorage since it causes a view update
var autocorrectSearch: Bool {
UserDefaults.standard.bool(forKey: "Behavior.AutocorrectSearch")
}
func body(content: Content) -> some View {
if #available(iOS 15, *) {
content
.backport.introspectSearchController { searchController in
searchController.searchBar.autocorrectionType = autocorrectSearch ? .default : .no
searchController.searchBar.autocapitalizationType = autocorrectSearch ? .sentences : .none
// MARK: One-time setup
guard hostingController == nil else { return }
searchController.hidesNavigationBarDuringPresentation = true
searchController.searchBar.showsScopeBar = true
searchController.searchBar.scopeButtonTitles = [""]
(searchController.searchBar.value(forKey: "_scopeBar") as? UIView)?.isHidden = true
let hostingController = UIHostingController(rootView: hostingContent)
hostingController.view.translatesAutoresizingMaskIntoConstraints = false
hostingController.view.backgroundColor = .clear
guard let containerView = searchController.searchBar.value(forKey: "_scopeBarContainerView") as? UIView else {
return
}
containerView.addSubview(hostingController.view)
NSLayoutConstraint.activate([
hostingController.view.widthAnchor.constraint(equalTo: containerView.widthAnchor),
hostingController.view.topAnchor.constraint(equalTo: containerView.topAnchor),
hostingController.view.heightAnchor.constraint(equalTo: containerView.heightAnchor)
])
self.hostingController = hostingController
}
.introspectNavigationController { navigationController in
navigationController.navigationBar.prefersLargeTitles = true
navigationController.navigationBar.sizeToFit()
}
} else {
VStack {
hostingContent
content
Spacer()
}
.backport.introspectSearchController { searchController in
searchController.searchBar.autocorrectionType = autocorrectSearch ? .default : .no
searchController.searchBar.autocapitalizationType = autocorrectSearch ? .sentences : .none
}
}
}
}