【发布时间】:2013-03-28 16:25:07
【问题描述】:
在 Cocoa-Touch 中,我们找到了一个控件 UISearchBar。我需要对其进行自定义,以便文本字段中的搜索图标(我们单击它执行相应的操作)右对齐。通常我们会发现它左对齐。有可能这样做吗?做过研发却找不到...
我该怎么做?有什么好的教程可以找到吗?
【问题讨论】:
标签: iphone ios cocoa-touch uikit uisearchbar
在 Cocoa-Touch 中,我们找到了一个控件 UISearchBar。我需要对其进行自定义,以便文本字段中的搜索图标(我们单击它执行相应的操作)右对齐。通常我们会发现它左对齐。有可能这样做吗?做过研发却找不到...
我该怎么做?有什么好的教程可以找到吗?
【问题讨论】:
标签: iphone ios cocoa-touch uikit uisearchbar
不幸的是,UISearchBar 并非旨在直接支持这一点。在完成我们想要的事情时,我们可能不得不使用在视觉或功能方面妥协或编写大量自定义代码的变通方法。
我已经概述了一些接近我们想要并且可能有用的方法。
UISearchBar 中的文本是 UITextField,它是 UISearchBar 的子视图,可以通过通常的方式访问,即 view.subviews。
放大镜搜索图标是UITextField 的leftView 属性中的UIImageView。我们可以使用以下代码将其切换到右侧:
// The text within a UISearchView is a UITextField that is a subview of that UISearchView.
UITextField *searchField;
for (UIView *subview in self.searchBar.subviews)
{
if ([subview isKindOfClass:[UITextField class]]) {
searchField = (UITextField *)subview;
break;
}
}
// The icon is accessible through the 'leftView' property of the UITextField.
// We set it to the 'rightView' instead.
if (searchField)
{
UIView *searchIcon = searchField.leftView;
if ([searchIcon isKindOfClass:[UIImageView class]]) {
NSLog(@"aye");
}
searchField.rightView = searchIcon;
searchField.leftViewMode = UITextFieldViewModeNever;
searchField.rightViewMode = UITextFieldViewModeAlways;
}
这给了我们以下结果:
如您所见,图标超出了圆角矩形的边缘,并且清除图标已消失。此外,rightView 属性用于其他内容,例如搜索结果按钮和书签按钮。将搜索图标放在此处可能会在某种程度上与此功能发生冲突,即使您能够使用偏移填充来适当定位它。
至少您可以使用这种方法将图标提取为UIImageView,并将其显式放置在您认为合适的位置,就像任何其他视图一样,并编写自定义代码来处理点击事件等。
在iOS v5.0 及更高版本中,您可以使用here 列出的方法自定义搜索栏的外观。以下代码利用偏移量在UISearchBar 中定位图标和文本:
[self.searchBar setPositionAdjustment:UIOffsetMake(255, 0) forSearchBarIcon:UISearchBarIconSearch];
[self.searchBar setSearchTextPositionAdjustment:UIOffsetMake(-270, 0)];
在宽度为 320 的标准 UISearchBar 上,它如下所示:
这将使与图标相关的所有事件功能按预期工作,但不幸的是UITextField 很混乱,尽管它很宽,但它只显示其文本的一小部分。如果您能找到一种方法让文本显示超出它认为是UITextField 的结尾,这可能是您最好的选择。
【讨论】:
我的要求是搜索图标应该在右侧,并且当 X 图标出现时它应该隐藏。
我想出了与上面类似的解决方案,但有点不同,并且还使用了 Swift 2 和 AutoLayout。基本思想是隐藏左侧视图,用放大镜图像创建一个新视图,并使用自动布局将其固定到右侧。然后在搜索栏文本不为空时使用 UISearchBarDelegate 方法隐藏搜索图标。
class CustomSearchView: UIView {
//the magnifying glass we will put on the right
lazy var magnifyingGlass = UIImageView()
@IBOutlet weak var searchBar: UISearchBar!
func commonInit() {
searchBar.delegate = self
searchBar.becomeFirstResponder()
//find the search bar object inside the subview stack
if let searchField = self.searchBar.subviews.firstObject?.subviews.filter(
{($0 as? UITextField) != nil }).firstObject as? UITextField {
//hides the left magnifying glass icon
searchField.leftViewMode = .Never
//add a magnifying glass image to the right image view. this can be anything, but we are just using the system default
//from the old left view
magnifyingGlass.image = (searchField.leftView! as? UIImageView)?.image
//add the new view to the stack
searchField.addSubview(magnifyingGlass)
//use autolayout constraints to pin the view to the right
let views = ["view": magnifyingGlass]
magnifyingGlass.translatesAutoresizingMaskIntoConstraints = false
searchField.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat(
"H:[view(12)]-|", options: [], metrics: nil, views: views))
searchField.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat(
"V:[view]-|", options: [], metrics: nil, views: views))
}
}
//hides whenever text is not empty
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
magnifyingGlass.hidden = searchText != ""
}
}
【讨论】: