iOS 11 在导航栏中自定义搜索栏

Posted

技术标签:

【中文标题】iOS 11 在导航栏中自定义搜索栏【英文标题】:iOS 11 customise search bar in navigation bar 【发布时间】:2017-09-01 20:00:42 【问题描述】:

我想在 ios 11 搜索栏中嵌入导航栏中时更改文本和图标的颜色。所以占位符文本、搜索文本和搜索图标。

if #available(iOS 11.0, *) 
    navigationController?.navigationBar.prefersLargeTitles = false
    let searchController = UISearchController(searchResultsController: nil)
    navigationItem.searchController = searchController
    navigationItem.hidesSearchBarWhenScrolling = false

    searchController.searchBar.placeholder = "Suchen"
    searchController.searchBar.tintColor = .white

正如您在图像中看到的那样,深蓝色背景上的文本是灰色的,看起来很难看。我希望文本和图标至少是白色的。 (改变蓝色背景颜色也不是很好,见my other question)

唯一有效的方法是更改​​闪烁光标和“取消”按钮的颜色,这是通过 .tintColor 属性完成的。

似乎适用于 iOS 10 及更低版本的解决方案在 iOS 11 中似乎不再适用,因此请仅发布您知道适用于 iOS 11 的解决方案。谢谢。

也许我错过了关于 iOS 11 中这种“自动样式”的要点。感谢任何帮助。

【问题讨论】:

您尝试过UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).tintColor = .white 吗? 是的,不起作用。 【参考方案1】:

我刚刚发现了如何设置它们的其余部分:(在 Brandon 的帮助下,谢谢!)

“取消”文本:

searchController.searchBar.tintColor = .white

搜索图标:

searchController.searchBar.setImage(UIImage(named: "my_search_icon"), for: UISearchBarIcon.search, state: .normal)

清除图标:

searchController.searchBar.setImage(UIImage(named: "my_search_icon"), for: UISearchBarIcon.clear, state: .normal)

搜索文本:

UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = [NSAttributedStringKey.foregroundColor.rawValue: UIColor.white]

感谢@Brandon 的帮助!

占位符:

UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).attributedPlaceholder = NSAttributedString(string: "placeholder", attributes: [NSAttributedStringKey.foregroundColor: UIColor.white])

白色背景:

let searchController = UISearchController(searchResultsController: nil)
searchController.delegate = self

let searchBar = searchController.searchBar
searchBar.tintColor = UIColor.white
searchBar.barTintColor = UIColor.white

if let textfield = searchBar.value(forKey: "searchField") as? UITextField 
    textfield.textColor = UIColor.blue
    if let backgroundview = textfield.subviews.first 

        // Background color
        backgroundview.backgroundColor = UIColor.white

        // Rounded corner
        backgroundview.layer.cornerRadius = 10;
        backgroundview.clipsToBounds = true;
    


if let navigationbar = self.navigationController?.navigationBar 
    navigationbar.barTintColor = UIColor.blue


navigationItem.searchController = searchController
navigationItem.hidesSearchBarWhenScrolling = false

取自here。

【讨论】:

很棒的东西,非常有帮助 --- 但是,我遇到了背景颜色的问题,即字段的白色背景。如果您对其进行采样,它实际上并不是白色的,而是 rgb(.95,.95,.95)。事实证明,textField.subviews.first 视图有自己的子视图,它们应用 alpha 着色着色。我已经尝试了所有方法来杀死那些着色器,但没有运气。如果有人找到解决办法,很想听听 关于 ^^ 我终于找到了解决办法。在搜索栏didMoveToSuperview 之后,如果你去for subview in textField.subviews.first.subviews subview.removeFromSuperview() 似乎你可以消除着色器,得到一个纯白色的背景rgb(1,1,1) 所以我有一个自定义颜色(它是灰色阴影),它一直显示为黑色。我打算使用上述解决方案,但它完全删除了我的自定义颜色(尽管如果我将背景设置为白色则不会......这没有任何意义)。所以我开始有一个底部边框(如材料设计搜索栏),因为我的搜索栏与导航栏混合在一起,突然间,我的自定义灰色出现了。弄清楚我是否设置了tf.borderStyle = .none 它会神奇地起作用。哇。 要更改背景颜色,无需访问子视图,只需这样做:if let textfield = scb.value(forKey: "searchField") as? UITextField textfield.backgroundColor = UIColor.blue @BrunoMuniz 不,它不是私有 API。但这意味着了解导航栏的内部工作原理。这意味着 - 它可能会在未来的 iOS 版本中停止工作。所以你需要在 iOS 更新上测试它。【参考方案2】:

UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = [NSForegroundColorAttributeName: UIColor.white]

UISearchBar.appearance().tintColor = UIColor.whiteAppDelegate

或者,将它们都放在[UIViewController viewDidLoad:]

【讨论】:

这确实改变了搜索文本的颜色,太棒了!但占位符文本颜色和图标仍然缺失。 Objective-C 语法:[UISearchBar 外观].tintColor = [UIColor whiteColor]; [[UITextField appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setDefaultTextAttributes:@NSForegroundColorAttributeName: [UIColor whiteColor]];【参考方案3】:

除了达科的回答。 在我的情况下,我需要获得纯白色的搜索文本字段颜色。 我还需要一个自定义的borderLine 和cornerRadius。 因此,如果我只是将背景颜色设置为白色,设置自定义角半径和自定义边框线,我就会得到类似的东西。

问题是搜索栏有一些子视图,我刚刚删除了它们。 这是我的代码:

@interface YourViewController () <UISearchBarDelegate, UISearchControllerDelegate>
// your properties
@property (nonatomic,strong) UISearchController *searchController;
@property (nonatomic,strong) UISearchBar *searchBar;
@end

- (void)viewDidLoad 
[super viewDidLoad];

_searchController = [[UISearchController alloc] initWithSearchResultsController:self.resultsTableController];
_searchController.delegate = self;
_searchController.searchBar.delegate = self;
_searchBar = self.searchController.searchBar;

if (@available(iOS 11.0, *)) 

    UITextField *searchTextField = [_searchBar valueForKey:@"searchField"];
if (searchTextField != nil) 
        searchTextField.layer.cornerRadius = 4.f;
        searchTextField.layer.borderWidth = 1.f;
        searchTextField.clipsToBounds = YES;

        for (UIView *subView in searchTextField.subviews) 
            [subView removeFromSuperview];
        


// Color for "Cancel" button
    _searchBar.tintColor = [UIColor blackColor];
// Add searchController to navgationBar
    _navigationItem.searchController = _searchController;
// Hide searchBar when scroll
    _navigationItem.hidesSearchBarWhenScrolling = YES;


现在我有了一个纯白色背景、自定义角半径、自定义边框宽度的搜索栏。此外,我在点击时禁用了灰色突出显示。

【讨论】:

你是如何在点击时禁用灰色突出显示的? @AndrewMorris 查看上面的代码。有一个循环,我删除了“searchTextField.subviews”的子视图【参考方案4】:

设置搜索文本颜色

(UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]) ).defaultTextAttributes = [NSForegroundColorAttributeName: UIColor.white]

设置搜索占位符颜色

(UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]) ).attributedPlaceholder = [NSForegroundColorAttributeName: UIColor.white]

【讨论】:

这个非常适合搜索文本颜色。为什么更改背景的解决方案对我不起作用?【参考方案5】:

我为 Swift 4.x 准备的两分钱,稍微清理了一下。

添加控制器或应用代理:

appearance.backgroundColor = .green
let myFont = UIFont.italicSystemFont(ofSize: 12)
let attribs = [
    NSAttributedString.Key(rawValue: NSAttributedString.Key.font.rawValue): myFont,
    NSAttributedString.Key(rawValue: NSAttributedString.Key.foregroundColor.rawValue): UIColor.red
]

appearance.defaultTextAttributes =  attribs

在控制器中:

self.searchBar.barTintColor = .blue

你会得到蓝色背景,绿色搜索栏背景,红色斜体:

【讨论】:

你忘了说appearance是如何声明的。 对! //搜索栏:让外观 = UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self])【参考方案6】:

我尝试了 Daroko 解决方案,但在将背景更改为纯白色时出现问题(它是灰色的)。 我的解决方案是使用setSearchFieldBackgroundImage。我也不想依赖苹果结构来获取 UITextField

  if #available(iOS 11.0, *) 
     let whiteImage = UIImage(color: UIColor.white, size: CGSize(width: searchController.searchBar.layer.frame.width, height: searchController.searchBar.layer.frame.height))
     searchController.searchBar.setSearchFieldBackgroundImage(whiteImage, for: .normal)
     self.navigationItem.searchController = searchController
     self.navigationItem.hidesSearchBarWhenScrolling = true
 


public extension UIImage 
  public convenience init?(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) 
    let rect = CGRect(origin: .zero, size: size)
     UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
     color.setFill()
     UIRectFill(rect)
     let image = UIGraphicsGetImageFromCurrentImageContext()
     UIGraphicsEndImageContext()
     guard let cgImage = image?.cgImage else  return nil 
     self.init(cgImage: cgImage)
 

我使用了 UIImage 扩展: Create UIImage with solid color in Swift

【讨论】:

【参考方案7】:

如果有人想知道为什么 Darkos solution 不起作用,请尝试将 UINavigationBar 的样式更改为 default 而不是 black。花了我半天时间才弄明白¯\_(ツ)_/¯

【讨论】:

【参考方案8】:

此代码更改文本字段的背景颜色

斯威夫特 4

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 

        //background color of text field
         UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).backgroundColor = .cyan

        

已编辑:青色 UISearchBar 示例

【讨论】:

不起作用。还是有什么我可能遗漏的东西? 不适用于 UISearchController,也许它适用于 UISearchBar 我又试了一次,这行代码对我仍然有效,我用截图编辑了我的回复。这是 iOS 11

以上是关于iOS 11 在导航栏中自定义搜索栏的主要内容,如果未能解决你的问题,请参考以下文章

在导航栏中自定义 UIBarButtonItem

可以在 IB 的导航栏中自定义提示字符串的字体吗?

iOS NavigationBar 导航栏自定义

如何减少iOS导航栏自定义视图的左右间隙

iOS 11 搜索栏中的搜索文本字段位置错误

IOS/Objective-C:导航栏自定义Segue效果对比Show Segue