可以修改UISearchbar TextField的高度吗?

jan*_*son 35 uisearchbar autolayout swift

我正在测试我的用户界面,我觉得搜索栏有点太狭隘了.我还想确保视力较差或手动灵巧较差的人在提出他们想要的界面方面没有任何问题.

所以,我想做的是调整UITextfield内部的高度UISearchbar.

我尝试过:1.在Storyboard中,添加UISearchbar高度约束 - 结果:搜索栏大小增加,但UITextField内部保持不变.

  1. 访问UITextField内部UISearchbar并修改其高度 - 结果:控制台输出显示参数已修改,但在屏幕上,UITextField高度保持不变.

注意 - 我可以修改UITextField使用方法2的其他参数,并且更改会反映在屏幕上,所以我知道我正在使用UITextField

方法2的代码,放在UISearchbar所在的ViewController的viewDidLoad()中:

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.
  }
}
Run Code Online (Sandbox Code Playgroud)

我认为它与autolayout有某种关系,无论它在何处设置,都可以忽略参数.我想继续使用autolayout,因为它为我做了很多工作,但我希望它会像在Storyboard中那样表现,当用户设置设置时,它会在自动布局中使用这些参数并在它可以'时抱怨而不是在没有反馈的情况下忽略设置.

编辑:

回应马赫什.我不太了解客观的C++,但我尽力将你写的内容转换为swift.这就是我所拥有的:

(在我的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))
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我保留了我的代码以进入文本字段,因为我有一些问题将您的代码转换为swift.对于CGRectMake - swift抱怨各种类型,包括topPadding不是CGFloat和最后一个变量(Y大小),再次它不喜欢将CGFloat与Float混合所以我不得不改变它.

不幸的是,它似乎不起作用.我在故事板中将UISearchbar高度更改为80,我只有一个非常高的搜索栏,文本域占总高度的1/3.

编辑#2:合并Yuyutsu和Mahesh代码的更正版本. 仍然不完美,但更接近.Yuyutsu的代码可以工作,但正如我的评论中提到的,字段不居中,当首次加载视图时,调整大小也是可见的(从高度A跳到高度B).另一个缺点是,因为调整大小viewDidAppear一次完成,方向改变,字段返回到内在大小.

我的代码基于Yuyutsu的:

  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)
        }
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

看看Yuyutsu的代码,我想知道我还能把这个调整放在哪里,我通过另一个stackoverflow帖子找到了链接.根据我的阅读,我看到Mahesh的答案应该有效.这就是我意识到它为什么不起作用的地方 - 我需要覆盖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)
        }
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

所以现在,唯一剩下的就是尝试制作它,使文本字段是视图可见之前的设置大小,这样就没有用户可见的大小偏移.

最终编辑:完全正常工作的代码 使用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
        }
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

谢谢Yuyutsu.感谢Mahesh从一开始就提出最终解决方案,只是缺少一些关键位.

Yuy*_*tsu 13

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

    }
Run Code Online (Sandbox Code Playgroud)

这可能会帮助你:)


wj2*_*061 9

如果您使用:

func setSearchFieldBackgroundImage(backgroundImage: UIImage?, forState state: UIControlState)   
Run Code Online (Sandbox Code Playgroud)

UISearchBar的UITextfield的高度与Image的高度相同.

您可以放入一个Image,使用它来自定义UISearchBar的UITextfield高度和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
}
Run Code Online (Sandbox Code Playgroud)

UIImage的宽度被忽略.但是有一个角半径,它的大于10.0.

代码看起来像这样:

let image = self.getImageWithColor(UIColor.lightGrayColor(), size: CGSizeMake(20, 20))
searchBar.setSearchFieldBackgroundImage(image, forState: .Normal)
Run Code Online (Sandbox Code Playgroud)


Bas*_*lta 8

根据学习者的回答,这里是 Swift 5.* 的代码:

extension UISearchBar {
    func updateHeight(height: CGFloat, radius: CGFloat = 8.0) {
        let image: UIImage? = UIImage.imageWithColor(color: UIColor.clear, size: CGSize(width: 1, height: height))
        setSearchFieldBackgroundImage(image, for: .normal)
        for subview in self.subviews {
            for subSubViews in subview.subviews {
                if #available(iOS 13.0, *) {
                    for child in subSubViews.subviews {
                        if let textField = child as? UISearchTextField {
                            textField.layer.cornerRadius = radius
                            textField.clipsToBounds = true
                        }
                    }
                    continue
                }
                if let textField = subSubViews as? UITextField {
                    textField.layer.cornerRadius = radius
                    textField.clipsToBounds = true
                }
            }
        }
    }
}

private extension UIImage {
    static func imageWithColor(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)
        guard let image: UIImage = UIGraphicsGetImageFromCurrentImageContext() else {
            return nil
        }
        UIGraphicsEndImageContext()
        return image
    }
}
Run Code Online (Sandbox Code Playgroud)

我们可以这样应用它:

searchBar?.updateHeight(height: 48)
Run Code Online (Sandbox Code Playgroud)

结果如下: 在此输入图像描述


dfi*_*dfi 7

这是关于如何更改UISearchBar高度的正确Swift 4.0答案:

  let image = getImageWithColor(color: UIColor.clear, size: CGSize(width: 1, height: 40))
  searchBar.setSearchFieldBackgroundImage(image, for: .normal)
Run Code Online (Sandbox Code Playgroud)

使用以下方法:

  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
    }
Run Code Online (Sandbox Code Playgroud)

测试4日.六月.2018


小智 5

我发现接受的答案有时候是错误的.
这就是我如何解决为searchBar设置自定义高度的问题:我设置了一个我想要的大小的彩色图像,并将其添加到searchBar的textField中viewDidLoad:

let image = getImageWithColor(UIColor.whiteColor(), size: CGSizeMake(600, 60))
searchBar.setSearchFieldBackgroundImage(image, forState: .Normal)
Run Code Online (Sandbox Code Playgroud)

接下来是从这里取得的这个功能

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
}
Run Code Online (Sandbox Code Playgroud)