[Swift] So ändern Sie dynamisch die Höhe der Symbolleiste auf der Tastatur

Einführung

Wenn Sie auf die Schaltfläche in der Leiste in der Symbolleiste der Tastatur tippen, die von UITextField oder UITextView angezeigt wird, wird eine weitere Leiste angezeigt. Als Bild ist die Symbolleiste zur Auswahl der Erinnerungszeit und des Gebietsschemas, die in der echten iOS-Erinnerungs-App implementiert ist, dieselbe. Ich sehe oft die grundlegende Möglichkeit, eine Symbolleiste auf der Tastatur mit textView.inputAccessoryView = toolbar festzulegen. Ich konnte keinen Weg finden, die Höhe der Leiste dynamisch zu ändern, also hoffe ich, dass es hilft.

Vollständiges Bild

Wenn Sie auf die Glockentaste in der Symbolleiste tippen, wird eine Schaltfläche zur Auswahl des Benachrichtigungszeitintervalls einen Schritt höher angezeigt. RocketSim Recording - iPhone 12 Pro Max - 2020-11-13 16.39.07.gif

Implementierungsmethode

Zuerst habe ich versucht, die Höhe des Symbolleistensatzes mit "textView.inputAccessoryView = toolbar" dynamisch zu ändern, aber ich konnte es nicht gut machen. .. .. (Bitte lassen Sie mich wissen, wenn Sie wissen, wie man es implementiert!) Blenden Sie diesmal die untergeordnete Ansicht mit "addSubview" und "sendSubviewToBack" auf der Rückseite der Symbolleiste aus, die mit "textView.inputAccessoryView = toolbar" festgelegt wurde. Das Display wird durch Auf- und Abbewegen umgeschaltet.

Dieses Mal habe ich eine CustomTableViewCell in der UITableView erstellt und die UITextView in der Zelle platziert. Bewirkt, dass die Tastatur für die UITextView in der CustomTableViewCell sichtbar ist und die Symbolleiste auf der Tastatur angezeigt wird.

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

Hier ist der Inhalt der oben festgelegten unteren Werkzeugleiste

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

Kommentar

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
    }

Wenn Sie die LowerToolbar initialisieren, erstellen Sie eine UpperToolbar und blenden Sie sie durch "addSubview" und "sendSubviewToBack" aus, um sie nach hinten zu verschieben.

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

Wenn Sie auf die Glockentaste tippen, wird die obere Symbolleiste um 60 nach oben und unten verschoben.

LowerToolbar.swift


    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        if isHidenUpperToolbar {
            //Die obere Werkzeugleiste ist ausgeblendet
            //Wenn die untere Werkzeugleiste angetippt ist
            let rect = self.bounds
            return rect.contains(point)
        } else {
            //Obwohl die obere Symbolleiste angezeigt wird
            //Wenn die obere Werkzeugleiste angetippt ist
            var rect = self.bounds
            if rect.contains(point) {
                return rect.contains(point)
            }
            
            //Wenn die untere Werkzeugleiste angetippt ist
            rect.origin.y -= 60
            return rect.contains(point)
        }
    }

Der Punkt ist dieser Teil, denn wenn Sie die obere Werkzeugleiste auf 60 verschieben, erstreckt sie sich über den Rahmenbereich der unteren Werkzeugleiste der übergeordneten Ansicht hinaus. Ich kann das Ereignis der Schaltfläche in der oberen Symbolleiste nicht empfangen. Überschreiben Sie also func point überschreiben (Innenpunkt: CGPoint, mit Ereignis: UIEvent?) -> Bool Ich versuche, ein Ereignis zu empfangen, wenn auf die obere Werkzeugleiste getippt wird.

Andere Hinweise

Dieses Mal habe ich eine obere Werkzeugleiste in der unteren Werkzeugleiste generiert und mit Code erstellt. Zu diesem Zeitpunkt habe ich die im Storyboard individuell erstellte obere Symbolleiste verwendet. Dies liegt daran, dass das mit delegate abgegriffene Ereignis nicht an UpperToolbar-> LowerToolbar-> CustomTableViewCell delegiert werden konnte. (Ich konnte den UpperToolbar-Delegaten nicht in der LowerToolbar festlegen.)

Zusammenfassung

Ich denke, es wäre die einfachste Implementierung, wenn die Höhe der Symbolleiste dynamisch geändert werden könnte. Ich konnte die Höhe nicht wie erwartet ändern, also habe ich eine andere Methode ausprobiert. Wie implementieren Sie es in Apples echter Erinnerungs-App? Ich bin neugierig. Ich hoffe, Sie finden es hilfreich.

Recommended Posts

[Swift] So ändern Sie dynamisch die Höhe der Symbolleiste auf der Tastatur
[Swift 5] Verarbeitung zum Schließen der Tastatur in UITableView
[swift5] So ändern Sie die Farbe der TabBar oder die Farbe des TabBar-Elements mit Code
[Ruby on Rails] So ändern Sie den Spaltennamen
[Swift] So ändern Sie die Reihenfolge der Balkenelemente in Tab Bar Controller [Anfänger]
[Rails] So ändern Sie den Spaltennamen der Tabelle
[Swift] So erhalten Sie die Firebase-Dokument-ID
So ändern Sie dynamisch den von MyBatis erfassten Spaltennamen
So ändern Sie den Einstellwert von Springboot Hikari CP
So ändern Sie den Inhalt der JAR-Datei, ohne sie zu dekomprimieren
So ändern Sie die Hintergrundfarbe der Navigationsleiste usw. in der Swift-Benutzeroberfläche
[Swift5] So erhalten Sie ein Array und eine Reihe von Unterschieden zwischen Arrays
So zeigen Sie 0 auf der linken Seite des Standardeingabewerts an
[Rails / Heroku / MySQL] So setzen Sie die Datenbank der Rails-App auf Heroku zurück
[Schienen] So ändern Sie den Seitentitel des Browsers für jede Seite
[chown] So ändern Sie den Eigentümer einer Datei oder eines Verzeichnisses
So bestimmen Sie die Anzahl der Parallelen
So sortieren Sie eine Liste von SelectItems
[Swift] Ändern Sie die Farbe des SCN-Knotens
So ändern Sie die maximale und maximale Anzahl von POST-Daten in Spark
So lösen Sie die lokale Umgebungskonstruktion von Ruby on Rails (MAC)!
So ändern Sie den Wert einer Variablen an einem Haltepunkt in IntelliJ
Passen Sie an, wie der Inhalt von Recyclerview aufgeteilt wird
Wie komme ich zum heutigen Tag?
Ändern Sie die Zeitzone des https-Portal-Containers in JST
Ausgabe der Verwendung der Slice-Methode
[Swift UI] So deaktivieren Sie ScrollsToTop von ScrollView
Wie Microservices die Art und Weise der Anwendungsentwicklung verändern
So zeigen Sie das Ergebnis des Ausfüllens des Formulars an
[Java] Memo zum Schreiben der Quelle
[Swift] So ermitteln Sie die Anzahl der Elemente in einem Array (Super Basic)
So erhalten Sie die ID eines Benutzers, der sich in Swift bei Firebase authentifiziert hat
[Ruby on Rails] So japanisieren Sie die Fehlermeldung des Formularobjekts (ActiveModel)
[Java] So erhalten Sie die URL der Übergangsquelle
So löschen / aktualisieren Sie das Listenfeld von OneToMany
Wie schreibe ich Scala aus der Perspektive von Java
[Java] So erhalten Sie den Maximalwert von HashMap
So ändern Sie den Prozess in Abhängigkeit von der Liste, die gedrückt wird, wenn mehrere ListViews vorhanden sind
Stand April 2018 So installieren Sie Java 8 auf einem Mac
[Android] So erhalten Sie die Einstellungssprache des Terminals
[Rails] So erhalten Sie den Inhalt starker Parameter