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.
Wenn Sie auf die Glockentaste in der Symbolleiste tippen, wird eine Schaltfläche zur Auswahl des Benachrichtigungszeitintervalls einen Schritt höher angezeigt.

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