[Swift] Comment modifier dynamiquement la hauteur de la barre d'outils sur le clavier

introduction

Si vous appuyez sur le bouton de la barre de la barre d'outils du clavier affiché par UITextField ou UITextView, une autre barre sera affichée. En tant qu'image, la barre d'outils pour sélectionner l'heure et les paramètres régionaux du rappel, qui est implémentée dans la véritable application de rappel iOS, sera la même. Je vois souvent la manière de base de définir une barre d'outils sur le clavier avec textView.inputAccessoryView = toolbar, Je n'ai pas pu trouver un moyen de changer la hauteur de la barre de manière dynamique, alors j'espère que cela aide.

Image complète

Lorsque vous appuyez sur le bouton de la cloche dans la barre d'outils, un bouton pour sélectionner l'intervalle de temps de notification apparaîtra un cran plus haut. RocketSim Recording - iPhone 12 Pro Max - 2020-11-13 16.39.07.gif

Méthode de mise en œuvre

Au début, j'ai essayé de changer dynamiquement la hauteur de la barre d'outils définie avec textView.inputAccessoryView = toolbar, mais je n'ai pas pu le faire correctement. .. .. (S'il vous plaît laissez-moi savoir si vous savez comment le mettre en œuvre!) Cette fois, masquez la vue enfant sur la face arrière avec addSubview et sendSubviewToBack pour la barre d'outils définie avec textView.inputAccessoryView = toolbar. L'affichage est commuté en se déplaçant vers le haut et vers le bas.

Cette fois, j'ai créé un CustomTableViewCell dans l'UITableView et placé l'UITextView sur la cellule. Fait en sorte que le clavier soit visible par UITextView dans CustomTableViewCell pour afficher la barre d'outils sur le clavier.

CustomTableViewCell.swift


let lowerToolbar = LowerToolbar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
lowerToolbar.initToolbarButton(item: item!)
lowerToolbar.delegate = self
textView.inputAccessoryView = lowerToolbar

Voici le contenu de la barre d'outils inférieure définie ci-dessus

LowerToolbar.swift


protocol LowerToolbarDelegete: class {
    func onTouchToolbarButton(selectedTimeInterval: Int)
}

class LowerToolbar: UIView {
    @IBOutlet weak var toolbar: UIToolbar!
    var upperToolbar: UIView?
    var isHidenUpperToolbar: Bool = true
    var upperToolbarCenterY: CGFloat = 0
    weak var delegate: LowerToolbarDelegete! = nil
    let oneHourButton = UIButton(type: .system)
    let threeHourButton = UIButton(type: .system)
    let fiveHourButton = UIButton(type: .system)
    var item: ItemModel?
    var selectedTimeInterval: Int = 0 // Last tapped button.
    
    override init(frame: CGRect){
        super.init(frame: frame)
        loadNib()
    }
    
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
        loadNib()
    }
    
    func loadNib(){
        let view = Bundle.main.loadNibNamed("LowerToolbar", owner: self, options: nil)?.first as! UIView
        view.frame = self.bounds
        self.addSubview(view)
        toolbar.clipsToBounds = true
        
        upperToolbar = UIView(frame: CGRect(x: 0, y: -1, width: self.frame.size.width, height: 61))
        upperToolbar?.backgroundColor = UIColor.toolbar
        self.addSubview(upperToolbar!)
        self.sendSubviewToBack(upperToolbar!)
        upperToolbarCenterY = upperToolbar!.center.y
    }
    
    func createToolbarButton(btn: UIButton, title: String, timeInterval: Int) {
        btn.setTitle(title, for: .normal)
        btn.tag = timeInterval
        btn.layer.borderWidth = 1
        btn.layer.borderColor = UIColor.toolbarBorder.cgColor
        btn.layer.cornerRadius = 20
        btn.contentEdgeInsets = UIEdgeInsets(top: 10, left: 20, bottom: 10, right: 20)
        btn.backgroundColor = UIColor.toolbarButton
        btn.addTarget(self, action: #selector(tapHoursButton), for: .touchUpInside)
        upperToolbar?.addSubview(btn)
        
        if self.item?.timeInterval == timeInterval {
            btn.layer.borderColor = UIColor.systemBlue.cgColor
            btn.backgroundColor = UIColor.systemBlue
            btn.tintColor = UIColor.white
        }
    }
    
    func initToolbarButton(item: ItemModel) {
        self.item = item

        createToolbarButton(btn: oneHourButton, title: "1hour", timeInterval: 60)
        oneHourButton.translatesAutoresizingMaskIntoConstraints = false
        oneHourButton.leadingAnchor.constraint(equalTo: upperToolbar!.leadingAnchor, constant: 20).isActive = true
        oneHourButton.topAnchor.constraint(equalTo: upperToolbar!.topAnchor, constant: 10).isActive = true
        
        createToolbarButton(btn: threeHourButton, title: "3hour", timeInterval: 180)
        threeHourButton.translatesAutoresizingMaskIntoConstraints = false
        threeHourButton.leadingAnchor.constraint(equalTo: oneHourButton.trailingAnchor, constant: 20).isActive = true
        threeHourButton.topAnchor.constraint(equalTo: upperToolbar!.topAnchor, constant: 10).isActive = true
        
        createToolbarButton(btn: fiveHourButton, title: "5hour", timeInterval: 400)
        fiveHourButton.translatesAutoresizingMaskIntoConstraints = false
        fiveHourButton.leadingAnchor.constraint(equalTo: threeHourButton.trailingAnchor, constant: 20).isActive = true
        fiveHourButton.topAnchor.constraint(equalTo: upperToolbar!.topAnchor, constant: 10).isActive = true
    }
    
    func initUpperToolbar() {
        upperToolbar?.center.y = upperToolbarCenterY
        isHidenUpperToolbar = true
    }
    
    func decorateTappedHourButton(btn: UIButton) {
        btn.layer.borderColor = UIColor.systemBlue.cgColor
        btn.backgroundColor = UIColor.systemBlue
        btn.tintColor = UIColor.white
    }
    
    func decorateNormalHourButton(btn: UIButton) {
        btn.layer.borderColor = UIColor.toolbarBorder.cgColor
        btn.backgroundColor = UIColor.toolbarButton
        btn.tintColor = .systemBlue
    }
    
    func decorateHourButton(btn1: UIButton, btn2: UIButton, btn3: UIButton, newTimeInterval: Int) {
        if selectedTimeInterval == newTimeInterval {
            selectedTimeInterval = 0
            decorateNormalHourButton(btn: btn1)
        } else {
            selectedTimeInterval = newTimeInterval
            decorateTappedHourButton(btn: btn1)
        }
        decorateNormalHourButton(btn: btn2)
        decorateNormalHourButton(btn: btn3)
    }
    
    @objc func tapHoursButton(btn: UIButton) {
        switch btn.tag {
        case 60:
            decorateHourButton(btn1: oneHourButton, btn2: threeHourButton, btn3: fiveHourButton, newTimeInterval: btn.tag)
        case 180:
            decorateHourButton(btn1: threeHourButton, btn2: oneHourButton, btn3: fiveHourButton, newTimeInterval: btn.tag)
        case 400:
            decorateHourButton(btn1: fiveHourButton, btn2: oneHourButton, btn3: threeHourButton, newTimeInterval: btn.tag)
        default:
            print("no item")
        }
        delegate?.onTouchToolbarButton(selectedTimeInterval: btn.tag)
    }
    
    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        if isHidenUpperToolbar {
            let rect = self.bounds
            return rect.contains(point)
        } else {
            var rect = self.bounds
            if rect.contains(point) {
                return rect.contains(point)
            }
            
            rect.origin.y -= 60
            return rect.contains(point)
        }
    }
    
    @IBAction func tapBellButton(_ sender: Any) {
        if isHidenUpperToolbar {
            UIView.animate(withDuration: 0.1, animations: {
                self.upperToolbar!.center.y -= 60
                self.isHidenUpperToolbar = false
                self.layoutIfNeeded()
            })
        } else {
            UIView.animate(withDuration: 0.1, animations: {
                self.upperToolbar!.center.y += 60
                self.isHidenUpperToolbar = true
                self.layoutIfNeeded()
            })
        }
    }
}

Commentaire

LowerToolbar.swift


    func loadNib(){
        let view = Bundle.main.loadNibNamed("LowerToolbar", owner: self, options: nil)?.first as! UIView
        view.frame = self.bounds
        self.addSubview(view)
        toolbar.clipsToBounds = true
        
        upperToolbar = UIView(frame: CGRect(x: 0, y: -1, width: self.frame.size.width, height: 61))
        upperToolbar?.backgroundColor = UIColor.toolbar
        self.addSubview(upperToolbar!)
        self.sendSubviewToBack(upperToolbar!)
        upperToolbarCenterY = upperToolbar!.center.y
    }

Lors de l'initialisation de la LowerToolbar, créez une UpperToolbar et cachez-la par addSubview et sendSubviewToBack pour la déplacer vers l'arrière.

LowerToolbar.swift


    @IBAction func tapBellButton(_ sender: Any) {
        if isHidenUpperToolbar {
            UIView.animate(withDuration: 0.1, animations: {
                self.upperToolbar!.center.y -= 60
                self.isHidenUpperToolbar = false
                self.layoutIfNeeded()
            })
        } else {
            UIView.animate(withDuration: 0.1, animations: {
                self.upperToolbar!.center.y += 60
                self.isHidenUpperToolbar = true
                self.layoutIfNeeded()
            })
        }
    }

Lorsque vous appuyez sur le bouton en forme de cloche, la barre d'outils supérieure est déplacée vers le haut et vers le bas de 60.

LowerToolbar.swift


    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        if isHidenUpperToolbar {
            //upperToolbar est masqué
            //Lorsque la barre d'outils inférieure est tapée
            let rect = self.bounds
            return rect.contains(point)
        } else {
            //Bien que la barre d'outils supérieure soit affichée
            //Lorsque upperToolbar est tapé
            var rect = self.bounds
            if rect.contains(point) {
                return rect.contains(point)
            }
            
            //Lorsque la barre d'outils inférieure est tapée
            rect.origin.y -= 60
            return rect.contains(point)
        }
    }

Le point est cette partie, car si vous déplacez la barre d'outils supérieure jusqu'à 60, elle s'étendra au-delà de la zone de cadre de la barre d'outils inférieure de la vue parent. Je ne pourrai pas recevoir l'événement du bouton sur la barre d'outils supérieure. Donc, remplacez override func point (inside point: CGPoint, with event: UIEvent?) -> Bool J'essaie de recevoir un événement lorsque la barre d'outils supérieure est activée.

Autres avis

Cette fois, j'ai généré une barre d'outils supérieure dans la barre d'outils inférieure et l'ai créée avec du code. C'est alors que j'ai utilisé la barre d'outils upperToolbar créée individuellement dans le storyboard, Cela est dû au fait que l'événement tapé à l'aide du délégué n'a pas pu être délégué à upperToolbar-> lowerToolbar-> CustomTableViewCell. (Je n'ai pas pu définir le délégué upperToolbar dans le lowerToolbar.)

Sommaire

Je pense que ce serait la mise en œuvre la plus simple si la hauteur de la barre d'outils pouvait être modifiée dynamiquement. Je ne pouvais pas changer la hauteur comme je m'y attendais, alors j'ai essayé une méthode différente. Comment l'implémentez-vous dans la véritable application de rappel d'Apple? Je suis curieux. J'espère que cela vous aidera.

Recommended Posts

[Swift] Comment modifier dynamiquement la hauteur de la barre d'outils sur le clavier
[Swift 5] Traitement pour fermer le clavier sur UITableView
[swift5] Comment changer la couleur de TabBar ou la couleur de l'élément de TabBar avec le code
[Ruby on Rails] Comment changer le nom de la colonne
[Swift] Comment changer l'ordre des éléments de barre dans le contrôleur de barre d'onglets [Débutant]
[Rails] Comment changer le nom de colonne de la table
[Swift] Comment obtenir l'ID de document Firebase
Comment changer dynamiquement le nom de la colonne acquis par MyBatis
Comment modifier la valeur de réglage de Springboot Hikari CP
Comment modifier le contenu du fichier jar sans décompresser
Comment changer la couleur d'arrière-plan de la barre de navigation, etc. dans Swift UI
[Swift5] Comment obtenir un tableau et un ensemble de différences entre les tableaux
Comment afficher 0 sur le côté gauche de la valeur d'entrée standard
[Rails / Heroku / MySQL] Comment réinitialiser la base de données de l'application Rails sur Heroku
[Rails] Comment changer le titre de la page du navigateur pour chaque page
[chown] Comment changer le propriétaire d'un fichier ou d'un répertoire
Comment déterminer le nombre de parallèles
Comment trier une liste de SelectItems
[Swift] Changer la couleur du nœud SCN
Comment modifier le nombre maximum et maximum de données POST dans Spark
Comment résoudre la construction de l'environnement local de Ruby on Rails (MAC)!
Comment changer la valeur d'une variable à un point d'arrêt dans intelliJ
Personnalisez la répartition du contenu de Recyclerview
Comment obtenir le jour d'aujourd'hui
Changer le fuseau horaire du conteneur https-portal en JST
Sortie de la façon d'utiliser la méthode slice
[Swift UI] Comment désactiver ScrollsToTop de ScrollView
Comment les microservices changent la façon de développer des applications
Comment afficher le résultat du remplissage du formulaire
[Java] Mémo sur la façon d'écrire la source
[Swift] Comment obtenir le nombre d'éléments dans un tableau (super basique)
Comment obtenir l'ID d'un utilisateur qui s'est authentifié avec Firebase dans Swift
[Ruby on Rails] Comment japonaisiser le message d'erreur de l'objet Form (ActiveModel)
[Java] Comment obtenir l'URL de la source de transition
Comment supprimer / mettre à jour le champ de liste de OneToMany
Comment écrire Scala du point de vue de Java
[Java] Comment obtenir la valeur maximale de HashMap
Comment changer le processus en fonction de la liste appuyée lorsqu'il y a plusieurs ListViews
À partir d'avril 2018 Comment installer Java 8 sur Mac
[Android] Comment obtenir la langue de réglage du terminal
[Rails] Comment obtenir le contenu des paramètres forts