Как оставить выравнивание текста заполнителя UISearchBar

This is the searchbar that the designers want me to create

Мне нужно создать обычную панель поиска, как это. Проблема, с которой я столкнулась, - это выровнять текст заполнителя, а также поместить значок поиска справа. У меня есть png значка поиска, который я пытался использовать в UIImageView, и установите UIImageView как rightView в UISearchBar UITextField. Это решение не сработало, и у меня кончились идеи. У кого-нибудь есть решение?

Ответы

Ответ 1

Не используйте UISearchBar, если вам нужно выполнить эти настройки. Вы должны будете сделать свой собственный, используя UITextField и UIImageView, и отвечать на вызовы делегатов.

Ответ 2

SWIFT 3

swift 3 не позволяет переопределить свойство заполнителя. Это модифицированная версия ответа Drix.

func setPlaceHolder(placeholder: String)-> String
   {

       var text = placeholder
           if text.characters.last! != " " {

               //                         define a max size

               let maxSize = CGSize(width: UIScreen.main.bounds.size.width - 97, height: 40)

               //                        let maxSize = CGSizeMake(self.bounds.size.width - 92, 40)
               // get the size of the text
               let widthText = text.boundingRect( with: maxSize, options: .usesLineFragmentOrigin, attributes:nil, context:nil).size.width
               // get the size of one space
               let widthSpace = " ".boundingRect( with: maxSize, options: .usesLineFragmentOrigin, attributes:nil, context:nil).size.width
               let spaces = floor((maxSize.width - widthText) / widthSpace)
               // add the spaces
               let newText = text + ((Array(repeating: " ", count: Int(spaces)).joined(separator: "")))
               // apply the new text if nescessary
               if newText != text {
                   return newText
               }

           }

       return placeholder;
   }

и вызовите функцию как:

searchBar.placeholder = self.setPlaceHolder(placeholder: "your placeholder text");

Ответ 3

На основании ответа Mohittomar, по просьбе @DevC, чтобы добавить пробелы в конец держателя места, вот код в быстрой:

Заполнитель-подкласс подкласса в UISearchBar, после установки значения, я проверяю, является ли последний символ пробелом. затем получите размер одного пробела и количество пробелов, которые нужно добавить для выравнивания влево.

class SearchBar: UISearchBar, UISearchBarDelegate {
override var placeholder:String? {
    didSet {
        if let text = placeholder {
            if text.last != " " {

// get the font attribute
                let attr = UITextField.s_appearanceWhenContainedIn(SearchBar).defaultTextAttributes
// define a max size
                let maxSize = CGSizeMake(UIScreen.mainScreen().bounds.size.width - 60, 40)
// get the size of the text
                var widthText = text.boundingRectWithSize( maxSize, options: .UsesLineFragmentOrigin, attributes:attr, context:nil).size.width
// get the size of one space
                var widthSpace = " ".boundingRectWithSize( maxSize, options: .UsesLineFragmentOrigin, attributes:attr, context:nil).size.width
                let spaces = floor((maxSize.width - widthText) / widthSpace)
// add the spaces
                let newText = text + (" " * spaces)
// apply the new text if nescessary
                if newText != text {
                    placeholder = newText
                }
            }
        }
    }
}

Ответ 4

Рабочее решение для ответа Drix

import Foundation
import UIKit

class LeftAlignedSearchBar: UISearchBar, UISearchBarDelegate {
    override var placeholder:String? {
        didSet {
            if #available(iOS 9.0, *) {
                if let text = placeholder {
                    if text.characters.last! != " " {
                        // get the font attribute
                        let attr = UITextField.appearanceWhenContainedInInstancesOfClasses([LeftAlignedSearchBar.self]).defaultTextAttributes
                        // define a max size
                        let maxSize = CGSizeMake(UIScreen.mainScreen().bounds.size.width - 87, 40)
//                        let maxSize = CGSizeMake(self.bounds.size.width - 92, 40)
                        // get the size of the text
                        let widthText = text.boundingRectWithSize( maxSize, options: .UsesLineFragmentOrigin, attributes:attr, context:nil).size.width
                        // get the size of one space
                        let widthSpace = " ".boundingRectWithSize( maxSize, options: .UsesLineFragmentOrigin, attributes:attr, context:nil).size.width
                        let spaces = floor((maxSize.width - widthText) / widthSpace)
                        // add the spaces
                        let newText = text + ((Array(count: Int(spaces), repeatedValue: " ").joinWithSeparator("")))
                        // apply the new text if nescessary
                        if newText != text {
                            placeholder = newText
                        }
                    }
                }
            }
        }
    }
}

Этот метод появленияWhenContainedInInstancesOfClasses недоступен в iOS 8, есть обходной путь для iOS 8 здесь

Ответ 5

Рабочее быстрое решение 3 для ответа Drix:

import Foundation
    import UIKit

    class LeftAlignedSearchBar: UISearchBar, UISearchBarDelegate {
        override var placeholder:String? {
            didSet {
                if #available(iOS 9.0, *) {

                    if let text = placeholder {
                        if text.characters.last! != " " {
                            // get the font attribute
                            let attr = UITextField.appearance(whenContainedInInstancesOf: [LeftAlignedSearchBar.self]).defaultTextAttributes
                            // define a max size
                            let maxSize = CGSize(width: UIScreen.main.bounds.size.width - 87, height: 40)
                            // let maxSize = CGSize(width:self.bounds.size.width - 92,height: 40)
                            // get the size of the text
                            let widthText = text.boundingRect( with: maxSize, options: .usesLineFragmentOrigin, attributes:attr, context:nil).size.width
                            // get the size of one space
                            let widthSpace = " ".boundingRect( with: maxSize, options: .usesLineFragmentOrigin, attributes:attr, context:nil).size.width
                            let spaces = floor((maxSize.width - widthText) / widthSpace)
                            // add the spaces
                            let newText = text + ((Array(repeating: " ", count: Int(spaces)).joined(separator: "")))
                            // apply the new text if nescessary
                            if newText != text {
                                placeholder = newText
                            }
                        }
                    }
                }
            }
        }

        /*
        // Only override draw() if you perform custom drawing.
        // An empty implementation adversely affects performance during animation.
        override func draw(_ rect: CGRect) {
            // Drawing code
        }
        */

    }

Ответ 6

Если вы хотите, чтобы ваш контроль отвечал точно так, как вы хотите, вы должны, вероятно, создать свой собственный пользовательский элемент управления. Этот элемент управления можно разделить на три части:

  • фон UIImageView
  • a UITextField
  • a UIButton для значка поиска, если вы хотите, чтобы пользователь взаимодействовал с ним

Самый простой способ сделать это, вероятно, создать новый класс MySearchBar с тремя частями в частном интерфейсе:

@interface MySearchBar ()
@property (nonatomic, strong) UISearchBar* searchBar;
@property (nonatomic, strong) UITextField* textField;
@property (nonatomic, strong) UIButton* button;
@end

В вашем MySearchBar вы можете создать свой компонент, настроить его, добавить лучший внешний вид. Чтобы вернуть результат поиска, ваш элемент управления может иметь делегат id<UISearchBarDelegate> (ваш UIViewController), который будет в основном имитировать наличие стандартного UISearchBar.

Осталось создать ваш MySearchBar в вашем контроллере и установить делегат на ваш контроллер просмотра. Сообщения из UISearchBarDelegate могут либо перейти к вашему MySearchBar для фильтрации или предварительной обработки перед отправкой на ваш UIViewController, либо перейти непосредственно к вашему UIViewController.

Ответ 7

Нет необходимости в какой-либо настройке, просто сделайте это...

    [email protected]"Search                                                        ";

searchbar имеет центральное выравнивание текста для своего места-ходера, поэтому просто дайте некоторый большой текст. и если текст небольшой, то просто используйте пробел после текста места.

Ответ 8

Версия для Xamarin

SearchBar.MovePlaceHolderLeft();

public static void MovePlaceHolderLeft(this UISearchBar  searchbar)
{
    NSAttributedString text = new NSAttributedString(searchbar.Placeholder ?? "");
    // define a max size
    var maxSize = new CGSize(width: UIScreen.MainScreen.Bounds.Size.Width - 97, height: 40);
    // get the size of the text
    var widthText = text.GetBoundingRect(maxSize, NSStringDrawingOptions.UsesLineFragmentOrigin, null).Size.Width;
    // get the size of one space
    var widthSpace = new NSAttributedString(" ").GetBoundingRect(maxSize, NSStringDrawingOptions.UsesLineFragmentOrigin, null).Size.Width;
    var spaces = Math.Floor((maxSize.Width - widthText) / widthSpace);
    // add the spaces
    string newText = searchbar.Placeholder;
    for (double i = 0; i < spaces; i++)
    {
        newText += " ";
    }
    searchbar.Placeholder = newText;
}

Ответ 9

это можно сделать из раскадровки. В инспекторе атрибутов панели поиска есть поле со списком имен семантическое, если вы установите его принудительно справа налево, то есть у вас есть строка поиска выравнивания по правому краю, и она имеет аналогичную функцию для выравнивания по левому краю.

Ответ 10

Это слишком поздно, но если кто-то все еще задается вопросом о решении, вы можете следовать этому.

UITextField *searchTextField = [searchBarController.searchBar valueForKey:@"_searchField"];

Вы можете получить поле поиска, используя вышеуказанный код. Теперь просто используйте свойства, которые вы хотите использовать, например.

searchTextField.layer.cornerRadius = 10.0f;
searchTextField.textAlignment = NSTextAlignmentLeft;

PS. Свойство выравнивания текста используется для текста и заполнителя. Спасибо.