【问题标题】:How to left align UISearchBar placeholder text如何左对齐 UISearchBar 占位符文本
【发布时间】:2013-12-21 10:32:06
【问题描述】:

我需要制作一个像这样的自定义搜索栏。我遇到的问题是左对齐占位符文本,以及将搜索图标放在右侧。我有一个我尝试在UIImageView 中使用的搜索图标的png,并将UIImageView 设置为UISearchBarUITextFieldrightView。这个解决方案没有奏效,我没有主意了。有人有解决办法吗?

【问题讨论】:

  • 不确定文本的对齐方式,但您可以考虑将搜索图标设为自定义UIButton,放置在搜索栏顶部,用作“Enter”按钮。我遇到过一些这样做的应用程序,而且我一直很喜欢不必点击搜索字段,调出键盘,如果我想重新运行搜索,从那里点击“搜索” .
  • 我已经在另一个问题上回答了这个问题。很高兴收到有关如何改进它的反馈:stackoverflow.com/a/25827025/3746156

标签: ios objective-c uiimageview uisearchbar


【解决方案1】:

如果您需要进行此类自定义,请勿使用UISearchBar。您必须使用UITextFieldUIImageView 自己制作,并响应委托调用。

【讨论】:

  • 但请注意,UISearchController 似乎需要使用实际的 UISearchBar 或子类。
  • 但是我想要搜索栏的所有其他内置功能(例如,取消和 x 按钮)——我只是想左对齐占位符文本——这要求太多了吗?为什么会这么难做到?
【解决方案2】:

如果您希望您的控件准确地响应您的要求,您可能应该制作自己的自定义控件。 这个控件可以分为三个部分:

  1. 背景UIImageView
  2. UITextField
  3. 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

【讨论】:

  • 感谢详细解答,我一定会用这个的。
【解决方案3】:

不需要任何定制,只要做就行了......

    searchBar.placeholder=@"Search                                                        ";

searchbar 的 place-hoder 具有居中文本对齐方式,因此只需提供一些大文本即可。如果您的文字很小,则只需在占位符文字后使用一些空间。

【讨论】:

  • 如果有人反对任何答案。首先提交一个正确的答案。
  • 只有在您检查需要多少空间并动态添加时才能完美运行。 - 覆盖占位符变量,并检查文本的大小与控制器的大小,而不是一个空格的大小。如果有人想让我发布代码,请告诉我。
  • 嘿@DevC,我会回答能够发布代码,现在。
  • iOS 8 将修剪占位符周围的空白。
【解决方案4】:

根据 Mohittomar 的回答,@DevC 要求在占位符的末尾添加空格,这里是 swift 中的代码:

我在 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
                }
            }
        }
    }
}

【讨论】:

    【解决方案5】:

    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
                            }
                        }
                    }
                }
            }
        }
    }
    

    这个方法appearanceWhenContainedInInstancesOfClasses 在iOS 8 中不可用,iOS 8 有一个解决方法here

    【讨论】:

      【解决方案6】:

      为时已晚,但如果有人仍然想知道解决方案,那么你可以按照这个。

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

      您可以使用上述代码获取搜索字段。现在只需使用您要使用的属性,例如。

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

      PS。文本对齐属性用于文本和占位符。 谢谢。

      【讨论】:

        【解决方案7】:

        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");
        

        【讨论】:

        • 我的搜索栏图标在退出键盘 2-3 次后退出搜索栏。
        【解决方案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】:

          Drix 答案的有效 swift 3 解决方案:

          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
                  }
                  */
          
              }
          

          【讨论】:

            【解决方案10】:

            它可以从故事板上完成,如果您将其设置为强制从右到左,则搜索栏的属性检查器上的组合框具有名称语义

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2017-03-24
              • 2016-09-24
              • 1970-01-01
              • 2018-10-05
              • 1970-01-01
              • 1970-01-01
              • 2014-03-02
              相关资源
              最近更新 更多