可以修改UISearchbar TextField的高度吗?

时间:2015-06-16 04:44:01

标签: swift autolayout uisearchbar

我正在测试我的用户界面,我发现搜索栏有点太窄了,不符合我的喜好。我还想确保视力较差或手动灵巧较差的人在提出他们想要的界面方面没有任何问题。

所以,我想做的是调整UITextfieldUISearchbar的高度。

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

  1. 访问UITextField内的UISearchbar并修改其高度 - 结果:控制台输出显示参数已修改,但在屏幕上,UITextField高度保持不变。
  2. 注意 - 我可以使用方法2修改UITextField的其他参数,更改会反映在屏幕上,所以我知道我要进入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.
      }
    }
    

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

    修改

    回应马赫什。我不太了解客观的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))
        }
      }
    }
    

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

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

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

    我的代码基于Yuyutsu&#39>:

      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帖子遇到了link。根据我的阅读,我看到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)
            }
          }
        }
      }
    

    所以现在,唯一剩下的就是尝试制作它,使文本字段是视图可见之前的设置大小,这样用户就不会看到大小的变化。

    最终编辑:完全正常工作的代码 通过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从一开始就提出最终解决方案,只是遗漏了几个关键位。

10 个答案:

答案 0 :(得分: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)
                }
            }
        }

    }

这可能对您有所帮助:)。

答案 1 :(得分:8)

如果您使用:

func setSearchFieldBackgroundImage(backgroundImage: UIImage?, forState state: UIControlState)   

UISearchBar的UITextfield的高度与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
}

UIImage的宽度被忽略。但是有一个角半径,它比10.0更好。

代码如下所示:

let image = self.getImageWithColor(UIColor.lightGrayColor(), size: CGSizeMake(20, 20))
searchBar.setSearchFieldBackgroundImage(image, forState: .Normal)

答案 2 :(得分:6)

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

  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
    }

第四次测试。六月。 2018

答案 3 :(得分:5)

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

let image = getImageWithColor(UIColor.whiteColor(), size: CGSizeMake(600, 60))
searchBar.setSearchFieldBackgroundImage(image, forState: .Normal)

here

取得此功能
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 :(得分:3)

您可以更改内部文本字段的高度尝试此代码。

步骤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 子视图内,可以更改框架图片以及其他 属性也。感谢。

修改

正如你在swift中提出的那样,我很快就写出来了。我觉得你错了。请试试这个。

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索引视图作为循环的第一个和最后一个视图。我认为你翻译的代码没有问题。尝试一次,请回复。

答案 5 :(得分:2)

基于thelearner's answer,这是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
    }
}

这是我们如何应用它:

searchBar?.setSearchTextField(height: 48)

,结果如下: enter image description here

答案 6 :(得分:0)

Swift 4.2 / iOS 12.1更新:

sudo docker run --net=host mesosphere/spark:2.4.0-2.2.1-3-hadoop-2.7 \
bash /opt/spark/dist/bin/spark-submit \
--master mesos://172.26.32.32:7077 \
--deploy-mode cluster \
--class com.learning.spark.WordCount \
--conf spark.mesos.executor.docker.image=mesosphere/spark:2.4.0-2.2.1-3-hadoop-2.7 \
--conf spark.master.rest.enabled=true \
--conf spark.executor.home=/opt/spark/dist \
/home/mesos/wordcount.jar hdfs://***.**.**.36:8020/user/spark/big.txt hdfs://***.**.**.36:8020/outputdirectory

答案 7 :(得分:0)

对于swift 5.0来说效果很好:

extension UIImage {
    class func image(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) -> UIImage {
        return UIGraphicsImageRenderer(size: size).image { rendererContext in
            color.setFill()
            rendererContext.fill(CGRect(origin: .zero, size: size))
        }
    }
}

extension UISearchBar {
    func customize() {
        setSearchFieldBackgroundImage(UIImage.image(color: .clear, size: CGSize(width: 1, height: 44)), for: .normal)

        // other settings
        searchBarStyle = .minimal
        searchTextPositionAdjustment = UIOffset(horizontal: 0, vertical: 0)
        tintColor = .black
        backgroundColor = .whiteBackground
        searchTextField.leftViewMode = .never
        searchTextField.textColor = .black
        searchTextField.backgroundColor = UIColor.lightGrayBackground
        searchTextField.layer.borderColor = UIColor.gray.cgColor
        searchTextField.cornerRadius = 22
        searchTextField.borderWidth = 0.5
    }
}

只需使用:

let searchBar = UISearchBar()
searchBar.customize()

答案 8 :(得分:0)

wj2061 的 MonoTouch 版本答案:

UIImage GetImageWithColor(UIColor color, CGSize size)
{
    var rect = new CGRect(0, 0, size.Width, size.Height);
    var path = UIBezierPath.FromRoundedRect(rect, 5);
    UIGraphics.BeginImageContextWithOptions(size, false, 0);
    color.SetFill();
    path.Fill();
    var image = UIGraphics.GetImageFromCurrentImageContext();
    UIGraphics.EndImageContext();
    return image;
}

var image = GetImageWithColor(UIColor.LightGray, new CGSize(20, 20));
searchBar.SetSearchFieldBackgroundImage(image, UIControlState.Normal);

答案 9 :(得分:-1)

尝试一下:

for (size_t i = 0; i < n; ++i)
    free(str[i]);
free(str);