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.white
在AppDelegate
。
或者,将它们都放在[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 在导航栏中自定义搜索栏的主要内容,如果未能解决你的问题,请参考以下文章