Allow theming of the search bar. (#700)

This commit is contained in:
Doug 2023-03-15 10:02:51 +00:00 committed by GitHub
parent 1a81768c62
commit 0ae664933b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 143 additions and 31 deletions

View File

@ -167,8 +167,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/siteline/SwiftUI-Introspect.git",
"state" : {
"revision" : "f2616860a41f9d9932da412a8978fec79c06fe24",
"version" : "0.1.4"
"revision" : "c18951c747ab62af7c15e17a81bd37d4fd5a9979",
"version" : "0.2.3"
}
},
{

View File

@ -0,0 +1,105 @@
//
// Copyright 2023 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import SwiftUI
/// The presentation that the search field should be styled to work with.
enum SearchableStyle {
/// The search field is styled for presentation inside of a `List` with the `.plain` style.
case list
/// The search field is styled for presentation inside of a `Form`.
case form
/// The colour of the search field's placeholder text and icon.
var placeholderColor: UIColor { .element.tertiaryContent }
/// The tint colour of the search text field which is applied to the caret and text selection.
var textFieldTintColor: UIColor { UIColor(.element.brand) }
/// The background colour of the search text field.
var textFieldBackgroundColor: UIColor {
switch self {
case .list:
return .element.system
case .form:
return UIColor(.element.formRowBackground)
}
}
}
extension View {
/// Styles the search bar text field added to the view with the `searchable` modifier.
/// - Parameter style: The presentation of the search bar to match the style to.
func searchableStyle(_ style: SearchableStyle) -> some View {
// Ported from Riot iOS as this is the only reliable way to get the exact look we want.
// However this is fragile and tied to gutwrenching the current UISearchBar internals.
introspectSearchController { searchController in
let searchTextField = searchController.searchBar.searchTextField
// Magnifying glass icon.
let leftImageView = searchTextField.leftView as? UIImageView
leftImageView?.tintColor = style.placeholderColor
// Placeholder text.
let placeholderLabel = searchTextField.value(forKey: "placeholderLabel") as? UILabel
placeholderLabel?.textColor = style.placeholderColor
// Text field.
searchTextField.backgroundColor = style.textFieldBackgroundColor
searchTextField.tintColor = style.textFieldTintColor
// Hide the effect views so we can the rounded rect style without any materials.
let effectBackgroundTop = searchTextField.value(forKey: "_effectBackgroundTop") as? UIView
effectBackgroundTop?.isHidden = true
let effectBackgroundBottom = searchTextField.value(forKey: "_effectBackgroundBottom") as? UIView
effectBackgroundBottom?.isHidden = false
}
}
}
struct SearchableStyle_Previews: PreviewProvider {
static var previews: some View {
NavigationStack {
List {
ForEach(0..<10, id: \.self) { index in
Text("Item \(index)")
}
}
.listStyle(.plain)
.searchable(text: .constant(""))
.searchableStyle(.list)
}
.tint(.element.accent)
NavigationStack {
Form {
Section("Settings") {
Button("Some Row") { }
.labelStyle(FormRowLabelStyle())
}
.formSectionStyle()
Section("More Settings") {
Toggle("Some Setting", isOn: .constant(true))
.tint(.element.brand)
.labelStyle(FormRowLabelStyle())
}
.formSectionStyle()
}
.background(Color.element.formBackground.ignoresSafeArea())
.scrollContentBackground(.hidden)
.searchable(text: .constant(""))
.searchableStyle(.form)
}
.tint(.element.accent)
}
}

View File

@ -45,6 +45,7 @@ struct EmojiPickerScreen: View {
.navigationBarTitleDisplayMode(.inline)
.toolbar { toolbar }
.searchable(text: $searchString)
.searchableStyle(.list)
.onChange(of: searchString) { _ in
context.send(viewAction: .search(searchString: searchString))
}

View File

@ -74,6 +74,7 @@ struct HomeScreen: View {
}
}
.searchable(text: $context.searchQuery)
.searchableStyle(.list)
.disableAutocorrection(true)
}
}

View File

@ -39,6 +39,7 @@ struct RoomMemberDetailsScreen: View {
}
}
.searchable(text: $context.searchQuery, placement: .navigationBarDrawer(displayMode: .always))
.searchableStyle(.list)
.background(Color.element.background.ignoresSafeArea())
.navigationTitle(ElementL10n.bottomActionPeople)
.alert(item: $context.alertInfo) { $0.alert }
@ -48,15 +49,18 @@ struct RoomMemberDetailsScreen: View {
// MARK: - Previews
struct RoomMemberDetails_Previews: PreviewProvider {
static let viewModel = {
let members: [RoomMemberProxy] = [
.mockAlice,
.mockBob,
.mockCharlie
]
return RoomMemberDetailsViewModel(mediaProvider: MockMediaProvider(),
members: members)
}()
static var previews: some View {
Group {
let members: [RoomMemberProxy] = [
.mockAlice,
.mockBob,
.mockCharlie
]
let viewModel = RoomMemberDetailsViewModel(mediaProvider: MockMediaProvider(),
members: members)
NavigationStack {
RoomMemberDetailsScreen(context: viewModel.context)
}
}

1
changelog.d/43.change Normal file
View File

@ -0,0 +1 @@
Allow the search bar to be styled.

View File

@ -73,7 +73,7 @@ packages:
branch: master
Introspect:
url: https://github.com/siteline/SwiftUI-Introspect
majorVersion: 0.1.4
majorVersion: 0.2.3
PostHog:
url: https://github.com/PostHog/posthog-ios
majorVersion: 1.4.4