Можно ли изменить высоту текстового поля UISearchbar?
Я тестирую свой пользовательский интерфейс, и я считаю, что панель поиска немного слишком узка по моему вкусу. Я также хочу, чтобы у людей с более низким зрением или меньшей ручной ловкостью не возникало проблем, связанных с желаемым интерфейсом.
Итак, что бы я хотел сделать, это отрегулировать высоту UITextfield
внутри UISearchbar
.
То, что я пробовал:
1. В Storyboard добавьте UISearchbar
Ограничение по высоте - Результаты: размер поисковой панели увеличивается, но UITextfield
внутри остается тем же.
- Получите доступ к
UITextfield
внутри UISearchbar
и измените его высоту. - Результаты: вывод консоли показывает, что параметр изменен, но на экране высота UITextfield
остается прежней.
Примечание. Я могу изменить другие параметры UITextfield
, используя метод 2, и изменение отразится на экране, поэтому я знаю, что добираюсь до UITextfield
Код для метода 2, поместите в viewDidLoad() ViewController, где находится UISearchbar:
for tempView in (self.roomInfoSearchBar.subviews[0] as! UIView).subviews as! [UIView]
{
if let tV = tempView as? UITextField
{
var currentFrameRect = tV.frame
currentFrameRect.size.height = 80
//tV.layer.backgroundColor = UIColor.blueColor().CGColor //This works fine
//tV.layer.cornerRadius = 5 //This works fine
//tV.font = UIFont(name: "Courier", size: 40) //This works fine
println(tV.frame.height) //console output:0.0
tV.frame = currentFrameRect
println(tV.frame) //console output:(0.0, 0.0, 0.0, 80.0)
println(currentFrameRect) //console output:(0.0, 0.0, 0.0, 80.0) - redundant, just checking
println(tV.frame.height) //console output:80.0 - it says 80, but screen shows searchbar definitely not 80.
}
}
Я думаю, что это имеет какое-то отношение к автозапуску, так или иначе способному игнорировать параметры независимо от того, где он установлен. Я хотел бы продолжать использовать автозапуск, так как он много работает для меня, но я бы хотел, чтобы он вел себя так, как в Storyboard, где, когда пользователь устанавливает настройку, он будет использовать эти параметры в своем автозапуске и жаловаться, t, а не просто игнорировать настройку без обратной связи.
Edit:
В ответ на Махеша. Я не знаю много объективного С++, но я изо всех сил пытался преобразовать то, что вы написали, в быстром. Это то, что у меня есть:
(Внутри моего viewcontroller.swift)
func viewDIdLayoutSubviews()
{
super.viewDidLayoutSubviews()
self.roomInfoSearchBar.layoutSubviews()
var topPadding: Float = 5.0
for view in (self.roomInfoSearchBar.subviews[0] as! UIView).subviews as! [UIView]
{
if let tfView = view as? UITextField
{
var calcheight = self.roomInfoSearchBar.frame.size.height - 10
tfView.frame = CGRectMake(tfView.frame.origin.x, CGFloat(topPadding), tfView.frame.size.width, self.roomInfoSearchBar.frame.size.height - CGFloat(topPadding * 2))
}
}
}
Я сохранил свой код для доступа к текстовому полю, так как у меня возникли проблемы с преобразованием кода в быстрый. Для CGRectMake - swift жаловался на различные типы, в том числе, что topPadding не был CGFloat, а для последней переменной (размер Y) снова не нравилось смешивать CGFloat с Float, поэтому мне тоже пришлось это изменить.
К сожалению, он не работает. Я изменил высоту UISearchbar до 80 в раскадровке, и у меня появилась очень высокая панель поиска с текстовым полем, охватывающим около 1/3 от общей высоты.
Изменить # 2: Включить Yuyutsu и скорректированную версию кода Mahesh.
Все еще не идеально, но ближе. Код Yuyutsu работает, но, как упоминалось в моих комментариях, поле не центрируется, изменение размера также видно (прыгать с высоты A на высоту B), когда представление сначала загружается. Еще один недостаток заключается в том, что, поскольку изменение размера выполняется при viewDidAppear
после изменения ориентации, поле возвращается к внутреннему размеру.
Мой код, основанный на Yuyutsu's:
override func viewDidAppear(animated: Bool)
{
super.viewDidAppear(animated)
var roomInfoSearchBarFrame = roomInfoSearchBar.frame
var newHeight: CGFloat = 60
for subView in roomInfoSearchBar.subviews
{
for subsubView in subView.subviews
{
if let textField = subsubView as? UITextField
{
var currentTextFieldFrame = textField.frame
var recenteredY = (roomInfoSearchBarFrame.height - newHeight)/2
var newTextFieldFrame = CGRectMake(textField.frame.minX, recenteredY, textField.frame.width, newHeight)
textField.frame = newTextFieldFrame
textField.borderStyle = UITextBorderStyle.RoundedRect
textField.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight
//textField.backgroundColor = UIColor.redColor()
// textField.font = UIFont.systemFontOfSize(20)
}
}
}
}
Глядя на код Yuyutsu, я хотел знать, где еще я мог бы установить эту настройку, и я наткнулся на ссылку через другую запись stackoverflow. Основываясь на том, что я читал, я увидел, что ответ Махеша должен работать. Вот где я понял, почему он не работает - мне нужно было переопределить func viewWillLayoutSubviews()
.
Текущий код: сохраняет размер с изменением ориентации. Но скачок размера остается видимым (его не должно быть видно)
override func viewWillLayoutSubviews()
{
super.viewWillLayoutSubviews()
var roomInfoSearchBarFrame = roomInfoSearchBar.frame
var newHeight: CGFloat = 60
for subView in roomInfoSearchBar.subviews
{
for subsubView in subView.subviews
{
if let textField = subsubView as? UITextField
{
var currentTextFieldFrame = textField.frame
var recenteredY = (roomInfoSearchBarFrame.height - newHeight)/2
var newTextFieldFrame = CGRectMake(textField.frame.minX, recenteredY, textField.frame.width, newHeight)
textField.frame = newTextFieldFrame
textField.borderStyle = UITextBorderStyle.RoundedRect
textField.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight
//textField.backgroundColor = UIColor.redColor()
// textField.font = UIFont.systemFontOfSize(20)
}
}
}
}
Итак, прямо сейчас осталось только попытаться сделать так, чтобы текстовое поле было установленным размером до того, как вид был видимым, поэтому нет сдвига по размеру, который видим пользователю.
Final Edit: Полностью рабочий код
С дополнительной помощью Yuyutsu код ниже делает все, что я хочу - начинается с заданного размера, поле центрируется, отлично работает с вращением.
override func viewDidLayoutSubviews()
{
super.viewDidLayoutSubviews()
self.roomInfoSearchBar.layoutIfNeeded()
self.roomInfoSearchBar.layoutSubviews()
var roomInfoSearchBarFrame = roomInfoSearchBar.frame
var newHeight: CGFloat = 60 //desired textField Height.
for subView in roomInfoSearchBar.subviews
{
for subsubView in subView.subviews
{
if let textField = subsubView as? UITextField
{
var currentTextFieldBounds = textField.bounds
currentTextFieldBounds.size.height = newHeight
textField.bounds = currentTextFieldBounds
textField.borderStyle = UITextBorderStyle.RoundedRect
//textField.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight
}
}
}
}
Спасибо Yuyutsu.
Спасибо Mahesh за то, что он придумал окончательное решение с самого начала, просто пропустил несколько критических бит.
Ответы
Ответ 1
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
for subView in searchBars.subviews {
for subsubView in subView.subviews {
if let textField = subsubView as? UITextField {
var bounds: CGRect
bounds = textField.frame
bounds.size.height = 35 //(set height whatever you want)
textField.bounds = bounds
textField.borderStyle = UITextBorderStyle.RoundedRect
// textField.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight
textField.backgroundColor = UIColor.redColor()
// textField.font = UIFont.systemFontOfSize(20)
}
}
}
}
Это может вам помочь:)
Ответ 2
Если вы используете:
func setSearchFieldBackgroundImage(backgroundImage: UIImage?, forState state: UIControlState)
Высота UISearchBar UITextfield будет такой же, как высота изображения.
Вы можете загрузить изображение, использовать его для настройки UISearchBar UITextfield height и backgroundImage.
Или вы можете использовать функцию ниже, чтобы создать круглый угол UIImage:
func getImageWithColor(color: UIColor, size: CGSize) -> UIImage {
let rect = CGRectMake(0, 0, size.width, size.height)
let path = UIBezierPath(roundedRect: rect, cornerRadius: 5.0)
UIGraphicsBeginImageContextWithOptions(size, false, 0)
color.setFill()
path.fill()
let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
Ширина UIImage игнорируется. Но чтобы иметь радиус угла, он больше, чем 10.0
.
Код будет выглядеть так:
let image = self.getImageWithColor(UIColor.lightGrayColor(), size: CGSizeMake(20, 20))
searchBar.setSearchFieldBackgroundImage(image, forState: .Normal)
Ответ 3
Я нашел, что принятый ответ иногда был ошибкой.
Вот как я решил проблему с настраиваемой высотой для searchBar: я установил цветное изображение с размером, которое я хочу, и добавил его в textField в SearchBar в viewDidLoad
:
let image = getImageWithColor(UIColor.whiteColor(), size: CGSizeMake(600, 60))
searchBar.setSearchFieldBackgroundImage(image, forState: .Normal)
После этого функция func взята из здесь
func getImageWithColor(color: UIColor, size: CGSize) -> UIImage {
var rect = CGRectMake(0, 0, size.width, size.height)
UIGraphicsBeginImageContextWithOptions(size, false, 0)
color.setFill()
UIRectFill(rect)
var image: UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
Ответ 4
Это правильный ответ Swift 4.0 о том, как изменить высоту UISearchBar:
let image = getImageWithColor(color: UIColor.clear, size: CGSize(width: 1, height: 40))
searchBar.setSearchFieldBackgroundImage(image, for: .normal)
Используя следующий метод:
func getImageWithColor(color: UIColor, size: CGSize) -> UIImage {
let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
UIGraphicsBeginImageContextWithOptions(size, false, 0)
color.setFill()
UIRectFill(rect)
let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return image
}
Проверено на 4-м. Июнь. 2018
Ответ 5
Вы можете изменить высоту внутреннего текстового поля, попробуйте этот код.
шаг 1) установите ограничение, чтобы увеличить высоту UISearchBar, затем выйдите из строки поиска и запишите этот код в контроллер.
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
[self.searchBar layoutSubviews];
float topPadding = 5.0;
for(UIView *view in self.searchBar.subviews)
{
for(UITextField *textfield in view.subviews)
{
if ([textfield isKindOfClass:[UITextField class]]) {
textfield.frame = CGRectMake(textfield.frame.origin.x, topPadding, textfield.frame.size.width, (self.searchBar.frame.size.height - (topPadding * 2)));
}
}
}
}
также, если вы хотите изменить что-либо еще в строке поиска, вы можете найти точный базовый элемент, например UILabel, UIImage и UIView внутри UITextField subviews и может изменять фрейм и изображение и другое свойства. Спасибо.
EDIT:
как вы быстро спросили, быстро написали. Я думаю, вы пытаетесь что-то не так. пожалуйста, попробуйте это.
func viewDIdLayoutSubviews()
{
super.viewDidLayoutSubviews()
self.roomInfoSearchBar.layoutSubviews()
var topPadding: Float = 5.0
for view in self.roomInfoSearchBar.subviews as [UIView]
{
for viewNew in view.subviews as [UIView]
{
if viewNew.isKindOfClass(UITextField)
{
viewNew.frame = CGRectMake(viewNew.frame.origin.x, CGFloat(topPadding), viewNew.frame.size.width, self.roomInfoSearchBar.frame.size.height - CGFloat(topPadding * 2))
}
}
}
}
вы взяли индексный индекс 0, поскольку первое и последнее представление должны быть закодированы. Я думаю, что проблема в том, что код, который вы перевели, не сработал. Попробуйте один раз и, пожалуйста, ответьте.
Ответ 6
Добавьте ограничение высоты в панель поиска в режиме раскадровки.
Этот снимок позволяет легко понять.
![введите описание изображения здесь]()
Ответ 7
Обновление для Swift 4.2/iOS 12.1:
let newHeight : CGFloat = 45
for subview in searchBar.subviews {
for subsubview in subview.subviews {
if let textField = subsubview as? UITextField {
var currentTextfieldBounds = textField.bounds
currentTextfieldBounds.size.height = newHeight
textField.bounds = currentTextfieldBounds
textField.borderStyle = .roundedRect
textField.contentVerticalAlignment = .center
}
}
}
Ответ 8
Попробуй это:
searchBar.frame.size.height = 80
searchBar.frame.size.width = 200