web-dev-qa-db-fra.com

La hauteur de UISearchbar TextField peut-elle être modifiée?

Je teste mon interface utilisateur et je trouve la barre de recherche un peu trop étroite à mon goût. Je veux également m'assurer que les personnes ayant une vision ou une dextérité manuelle médiocre n'ont pas de problèmes pour afficher l'interface qu'elles souhaitent.

Donc, ce que je voudrais faire, c'est ajuster la hauteur de UITextfield à l'intérieur de UISearchbar.

Ce que j'ai essayé: 1. Dans Storyboard, ajoutez la variable UISearchbar Height - Résultats: la taille de la barre de recherche augmente, mais la valeur UITextField à l'intérieur reste la même.

  1. Accédez à UITextField à l'intérieur de UISearchbar et modifiez sa hauteur - Résultats: la sortie de la console indique que le paramètre est modifié, mais à l'écran, la hauteur de UITextField reste la même.

Remarque - Je peux modifier d'autres paramètres de UITextField à l'aide de la méthode 2 et le changement est reflété à l'écran. Je sais donc que j'arrive à la UITextField

Code pour la méthode 2, mis dans viewDidLoad () de ViewController où UISearchbar est situé:

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

Je pense que cela a quelque chose à voir avec l'autolayout de pouvoir en quelque sorte ignorer les paramètres indépendamment de l'endroit où il est défini. J'aimerais continuer à utiliser l'autolayout, car cela me donne beaucoup de travail, mais j'aimerais que tout se passe comme dans Storyboard: lorsqu'un utilisateur définit un paramètre, il utilisera ces paramètres dans son autolayout et se plaindra quand il le pourra. " t plutôt que de simplement ignorer le paramètre sans retour.

Modifier:

En réponse à Mahesh. Je ne connais pas beaucoup Objective C++, mais j'ai fait de mon mieux pour convertir ce que vous avez écrit en Swift. Voici ce que j'ai

(Dans mon 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))
    }
  }
}

J'ai gardé mon code pour accéder au champ de texte depuis que j'ai eu quelques problèmes pour convertir votre code en Swift. Pour le CGRectMake - Swift s'est plaint de divers types, dont topPadding n'était pas un CGFloat et pour la dernière variable (taille Y), encore une fois, il n'aimait pas mélanger CGFloat avec Float.

Malheureusement, cela ne semble pas fonctionner. J'ai changé la hauteur de la barre UISearch à 80 dans le storyboard et je viens de recevoir une barre de recherche très haute avec un champ de texte couvrant environ 1/3 de la hauteur totale.

Edit # 2: Incorporant Yuyutsu et la version corrigée du code Mahesh. Toujours pas parfait, mais plus proche. Le code de Yuyutsu fonctionne, mais comme mentionné dans mes commentaires, le champ ne se centre pas, le redimensionnement est également visible (saute de la hauteur A à la hauteur B) lorsque la vue est chargée pour la première fois. Une lacune supplémentaire est que, comme le redimensionnement est effectué à viewDidAppear une fois que l'orientation change, le champ revient à la taille intrinsèque.

Mon code est basé sur celui de 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)
        }
      }
    }
  }

En regardant le code de Yuyutsu, je voulais savoir où d'autre je pourrais mettre cet ajustement et je suis tombé sur link via un autre poste de stackoverflow. D'après ce que j'ai lu, j'ai vu que la réponse de Mahesh devrait fonctionner. C'est là que j'ai compris pourquoi cela ne fonctionnait pas - j'avais besoin de remplacer func viewWillLayoutSubviews().

Code actuel: conserve la taille avec le changement d'orientation. Mais le saut de taille est toujours visible (il ne devrait pas être visible))

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

Donc, pour le moment, il ne reste plus qu'à essayer de faire en sorte que le champ de texte soit la taille définie avant que la vue ne soit visible afin d'éviter tout décalage de taille visible pour l'utilisateur.

Final Edit: Code pleinement fonctionnel Avec l'aide supplémentaire de Yuyutsu, le code ci-dessous fait tout ce que je veux - commence à la taille définie, le champ est centré, traite de la rotation avec précision.

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

Merci Yuyutsu ... Merci Mahesh d'avoir à peu près mis au point la solution finale dès le début, manquant juste quelques éléments critiques.

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

    }

Cela pourrait vous aider :)

12
Yuyutsu

Si tu utilises : 

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

La hauteur de l'UITextfield de UISearchBar serait la même que la hauteur de l'image. 

Vous pouvez déposer une image, l'utiliser pour personnaliser la hauteur UITextfield et la propriété backgroundImage de UISearchBar. 

Ou vous pouvez utiliser la fonction ci-dessous pour créer un coin arrondi 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
}

La largeur de UIImage est ignorée. Mais pour avoir un rayon de coin, il vaut mieux que 10.0

Le code ressemblerait à ceci:

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

Ceci est la bonne réponse Swift 4.0 sur la façon de modifier la hauteur d'un UISearchBar:

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

En utilisant la méthode suivante:

  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
    }

Testé le 4ème. Juin. 2018

5
dfi

J'ai trouvé la réponse acceptée parfois très difficile. 
C'est comment j'ai résolu le problème d'avoir une hauteur personnalisée pour le searchBar: j'ai défini une image couleur avec la taille souhaitée et l'a ajoutée à textField du searchBar dans viewDidLoad:

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

Suivi avec ce func pris de ici

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

Vous pouvez changer la hauteur du champ de texte intérieur essayez ce code.

étape 1) définissez la contrainte pour augmenter la hauteur de votre UISearchBar, puis sortez la barre de recherche et notez ce code dans le contrôleur de vue.

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

de plus, si vous voulez changer quoi que ce soit dans la barre de recherche, vous pouvez trouver l'élément de base exact comme UILabel , UIImage et UIView dans le UITextField subviews et peut changer le cadre et image et autre propriétés aussi. Merci.

MODIFIER:

comme vous l'avez demandé dans Swift, je l'écris dans Swift. Je pense que vous essayez quelque chose de mal. s'il vous plaît essayez ceci.

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

vous avez pris la vue 0 index comme première et dernière vue à être mise en boucle. Je pense que c’est le problème que le code que vous avez traduit n’a pas fonctionné. Essayez une fois et répondez s'il vous plaît.

3
Mahesh Agrawal

Essaye ça:

searchBar.frame.size.height = 80
searchBar.frame.size.width = 200
0
HSAM

Mise à jour pour 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
        }
    }
}
0
WR-BikAir