mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:55:59 +00:00
added argument to voice over on the search bar automatically
- also removed the geomtry reader in favour of a `readWidth` function
This commit is contained in:
@@ -31,4 +31,15 @@ extension View {
|
||||
height.wrappedValue = newValue
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads the width of the view and stores it in the `width` binding.
|
||||
/// - Parameters:
|
||||
/// - width: a `CGFloat` binding
|
||||
func readWidth(_ width: Binding<CGFloat>) -> some View {
|
||||
onGeometryChange(for: CGFloat.self) { geometry in
|
||||
geometry.size.width
|
||||
} action: { newValue in
|
||||
width.wrappedValue = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,12 +28,14 @@ extension View {
|
||||
placeholder: String? = nil,
|
||||
hidesNavigationBar: Bool = false,
|
||||
showsCancelButton: Bool = true,
|
||||
disablesInteractiveDismiss: Bool = false) -> some View {
|
||||
disablesInteractiveDismiss: Bool = false,
|
||||
accessibilityFocusOnStart: Bool = false) -> some View {
|
||||
modifier(SearchControllerModifier(searchQuery: query,
|
||||
placeholder: placeholder,
|
||||
hidesNavigationBar: hidesNavigationBar,
|
||||
showsCancelButton: showsCancelButton,
|
||||
disablesInteractiveDismiss: disablesInteractiveDismiss))
|
||||
disablesInteractiveDismiss: disablesInteractiveDismiss,
|
||||
accessibilityFocusOnStart: accessibilityFocusOnStart))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +46,7 @@ private struct SearchControllerModifier: ViewModifier {
|
||||
let hidesNavigationBar: Bool
|
||||
let showsCancelButton: Bool
|
||||
let disablesInteractiveDismiss: Bool
|
||||
let accessibilityFocusOnStart: Bool
|
||||
|
||||
/// Whether or not the user is currently searching. When ``automaticallyShowsCancelButton``
|
||||
/// is `false`, checking if this value is `false` is pretty much meaningless.
|
||||
@@ -58,6 +61,7 @@ private struct SearchControllerModifier: ViewModifier {
|
||||
hidesNavigationBar: hidesNavigationBar,
|
||||
showsCancelButton: showsCancelButton,
|
||||
hidesSearchBarWhenScrolling: false,
|
||||
accessibilityFocusOnStart: accessibilityFocusOnStart,
|
||||
isSearching: $isSearching)
|
||||
}
|
||||
.onDisappear {
|
||||
@@ -76,12 +80,19 @@ private struct SearchController: UIViewControllerRepresentable {
|
||||
let hidesNavigationBar: Bool
|
||||
let showsCancelButton: Bool
|
||||
let hidesSearchBarWhenScrolling: Bool
|
||||
let accessibilityFocusOnStart: Bool
|
||||
|
||||
@Binding var isSearching: Bool
|
||||
|
||||
func makeUIViewController(context: Context) -> SearchInjectionViewController {
|
||||
SearchInjectionViewController(searchController: context.coordinator.searchController,
|
||||
hidesSearchBarWhenScrolling: hidesSearchBarWhenScrolling)
|
||||
let controller = SearchInjectionViewController(searchController: context.coordinator.searchController,
|
||||
hidesSearchBarWhenScrolling: hidesSearchBarWhenScrolling)
|
||||
if accessibilityFocusOnStart {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
UIAccessibility.post(notification: .screenChanged, argument: controller.searchController.searchBar)
|
||||
}
|
||||
}
|
||||
return controller
|
||||
}
|
||||
|
||||
func updateUIViewController(_ viewController: SearchInjectionViewController, context: Context) {
|
||||
|
||||
@@ -11,6 +11,8 @@ import SwiftUI
|
||||
struct InviteUsersScreen: View {
|
||||
@ObservedObject var context: InviteUsersScreenViewModel.Context
|
||||
|
||||
@State private var formWidth = CGFloat.zero
|
||||
|
||||
var showTopSection: Bool {
|
||||
!context.viewState.selectedUsers.isEmpty || context.viewState.isSearching
|
||||
}
|
||||
@@ -25,7 +27,8 @@ struct InviteUsersScreen: View {
|
||||
.searchController(query: $context.searchQuery,
|
||||
placeholder: L10n.commonSearchForSomeone,
|
||||
showsCancelButton: false,
|
||||
disablesInteractiveDismiss: true)
|
||||
disablesInteractiveDismiss: true,
|
||||
accessibilityFocusOnStart: true)
|
||||
.compoundSearchField()
|
||||
.alert(item: $context.alertInfo)
|
||||
}
|
||||
@@ -33,34 +36,33 @@ struct InviteUsersScreen: View {
|
||||
// MARK: - Private
|
||||
|
||||
private var mainContent: some View {
|
||||
GeometryReader { proxy in
|
||||
Form {
|
||||
if showTopSection {
|
||||
// this is a fix for having the carousel not clipped, and inside the form, so when the search is dismissed, it wont break the design
|
||||
Section {
|
||||
EmptyView()
|
||||
} header: {
|
||||
VStack(spacing: 16) {
|
||||
selectedUsersSection
|
||||
.textCase(.none)
|
||||
.frame(width: proxy.size.width)
|
||||
|
||||
if context.viewState.isSearching {
|
||||
ProgressView()
|
||||
.frame(maxWidth: .infinity, alignment: .center)
|
||||
.listRowBackground(Color.clear)
|
||||
}
|
||||
Form {
|
||||
if showTopSection {
|
||||
// this is a fix for having the carousel not clipped, and inside the form, so when the search is dismissed, it wont break the design
|
||||
Section {
|
||||
EmptyView()
|
||||
} header: {
|
||||
VStack(spacing: 16) {
|
||||
selectedUsersSection
|
||||
.textCase(.none)
|
||||
.frame(width: formWidth)
|
||||
|
||||
if context.viewState.isSearching {
|
||||
ProgressView()
|
||||
.frame(maxWidth: .infinity, alignment: .center)
|
||||
.listRowBackground(Color.clear)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if context.viewState.hasEmptySearchResults {
|
||||
noResultsContent
|
||||
} else {
|
||||
usersSection
|
||||
}
|
||||
}
|
||||
|
||||
if context.viewState.hasEmptySearchResults {
|
||||
noResultsContent
|
||||
} else {
|
||||
usersSection
|
||||
}
|
||||
}
|
||||
.readWidth($formWidth)
|
||||
}
|
||||
|
||||
private var noResultsContent: some View {
|
||||
|
||||
Reference in New Issue
Block a user