iOS 11 UISearchBar 背景颜色

14

我知道这个问题在SO上已经被问了很多次。然而,就像苹果一直以来所做的那样,在发布 iOS 11后,他们似乎对UISearchBar进行了一个看似不必要的更改,具体而言是它的视图层次结构。

此外,搜索栏的“文本字段”不再可以在搜索栏的子视图中访问,导致之前所有旧的解决方案都无法“访问”和更改文本字段的背景颜色,或者更改文本字段的任何属性。

  • 有人知道如何在iOS 11中实际调整搜索栏的背景颜色吗?

FYI: 我特别指的是文本后面的颜色...现在默认为白色,除非您将搜索栏样式指定为minimal。

UPDATE 1:

自从我发布这个问题以来,我仍然没有找到有效或真正的解决方案来解决这个问题。最接近的解决方案似乎是深入研究外观属性。

[[UISearchBar class] appearanceWhenContainedInInstancesOfClasses:(nonnull NSArray<Class<UIAppearanceContainer>> *)]

UISearchBar 中使用. 通过以下方法操作找到的 UITextField:

if ([view isKindOfClass:[UITextField class]]) {
    return (UITextField*)view;
}
UITextField *searchTextField;
for (UIView *subview in view.subviews) {
    searchTextField = [self searchViewForTextFieldBg:subview];
    if (searchTextField) {
        break;
    }
}
return searchTextField;

您可以开始绘制一个新的背景视图,以放置在该视图后面。但是,我发现要进一步追求的问题是,绘制具有正确框架/边界的视图,以精确模仿原始背景,这些问题太烦琐了。

希望有人能找到这个问题的真正解决方案。苹果错过了不错。。。


你尝试过使用UIView.appearance(whenContainedIn: UISearchBar)吗?这只是一个想法。 - Oscar Apeland
你看过这个问答吗?https://dev59.com/ZlYO5IYBdhLWcg3wU_-M#46010398 - zgosalvez
@OscarApeland 是的,我尝试了很多东西,包括 appearanceWhenCont... 但是没有任何效果。 - Will Von Ullrich
1
@zgosalvez 是的,但是要覆盖答案建议的白色背景,需要使用let textfield = scb.value(forKey: "searchField") as? UITextField。我认为这违反了苹果的条款和条件,因为这实际上是访问私有API,不是吗? - Will Von Ullrich
1
@WillVonUllrich 这并不是严格禁止的,但这是不安全的,因为iOS更新可能会破坏未记录的功能。这也可能被视为使用私有API,但我已经在生产中使用了这个确切的hack而没有问题。 - Oscar Apeland
显示剩余2条评论
5个回答

17

我觉得你可能在寻找这个,对吧?但是我只有用Swift语言写的它 :(

@IBOutlet weak var sbSearchBar: UISearchBar!

if let textfield = sbSearchBar.value(forKey: "searchField") as? UITextField {
    textfield.textColor = UIColor.blue
    textfield.backgroundColor = UIColor.yellow
}

这是结果:

在此输入图片描述


2
这个方法是可行的,你说得对。但我更希望找到一个相对于苹果非私有API的解决方案。当然,这个方法确实可以用,只是不被推荐,因为它存在风险,可能会在未来的苹果更新中失效。 - Will Von Ullrich
这适用于文本颜色,但不适用于背景颜色。 - drewster

10

这段 Swift 代码更改了文本字段的背景颜色:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        
    // background color of text field
    UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).backgroundColor = .cyan        
}

这是结果

用于将背景更改为青色的示例


4
很遗憾,我尝试了但没有成功(就像我在我的帖子评论中所说的那样)。 - Will Von Ullrich
在苹果随机停止显示我选择的背景色后,这对我起作用了。 - user3078365

7
let searchBar = UISearchBar(frame: CGRect())
let searchField: UITextField? = searchBar.value(forKey: "searchField") as? UITextField
let searchBarBackground: UIView? = searchBar.value(forKey: "background") as? UIView
// searchBarBackground?.removeFromSuperview()

if searchField != nil {
    var frame = searchField?.frame
    frame?.size.height = 30
    searchField?.frame = frame!
    searchField?.backgroundColor = .yellow
}

searchBar.barTintColor = .red
searchBar.delegate = self
searchBar.backgroundColor = .green

运行时视图层次结构

如果我们使用上面的代码为UISearchBar设置背景颜色,我们可以看到以下带有颜色的子视图(点击链接查看)。

backgroundColor用于UISearchBar子视图的父视图

我们可以在对象检查器中看到绿色视图的类名是UISearchBar

因此,如果我们使用searchBar.backgroundColor = .green,我们将设置父视图的背景颜色为绿色。因此,UISearchBar实例属性backgroundColor将设置父视图的背景颜色。

UISearchBar的父视图

barTintColor用于UISearchBarBackground

我们可以在对象检查器中看到红色视图的类名是UISearchBarBackground

然而,没有直接的方法来访问这个视图,我们可以使用KVC searchBar.value(forKey: "background") as? UIView尝试获取searchBarBackground

如果我们使用searchBar.barTintColor = .red,我们将设置UISearchBarBackground的视图背景颜色为红色。 为了删除色调条层上的两个黑色边框,我们必须从父视图中删除背景。

UISearchBarbarTintColor

searchField?.backgroundColor用于UITextField

我们可以在对象检查器中看到黄色视图的类名是_UISearchBarSearchFieldBackgroundViewUISearchBarTextField的子视图)。

searchBarBackground一样,没有直接访问searchField的方法。我们也可以使用KVC searchField: UITextField? = searchBar.value(forKey: "searchField") as? UITextField尝试获取searchField

如果我们使用searchField?.backgroundColor = .yellow,我们将设置UITextField的背景颜色为黄色。因此,如果我们想要设置文本字段的背景颜色,我们必须先使用KVC访问searchField

UISearchBarUITextField


欢迎来到 Stack Overflow,请解释一下这段代码如何帮助 OP。 - Daniel
1
抱歉,这是我第一次在stackoverflow上回答问题,我对此还不太熟悉,所以我没有解释它为什么有效。我将在调试运行时捕获我的应用程序的层次结构,并解释明天如何帮助它。:) - 请忽略我的英语语法错误,来自一位中国女孩,谢谢~ 囧 - user5533269

4

在Swift 5中,比这简单得多。

    searchBar.barTintColor = .black
    searchBar.searchTextField.backgroundColor = .white

4
请注意,在iOS 13之后才有searchTextField可用。 - Michael Revlis

2

Swift 4-5

searchController.searchBar.barTintColor = .white

搜索控制器.搜索栏.barTintColor = .white


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接