Swift - Atualizar barra UITabBarController personalizada

Jan 08 2021

Eu tenho um TabBar personalizado, com um botão do meio em relevo, acima do TabBar. Quando o usuário não concluiu uma tarefa diária, o setupIncompleteMiddleButton () deve aparecer, indicando isso. No entanto, depois que o usuário concluir a tarefa, gostaria que setupCompleteMiddleButton () apareça, indicando que concluiu a tarefa. Não sei como fazer isso - não devo chamar viewDidLoad () no controlador e, ao chamá-lo, ele não faz nada para atualizar a visualização. Atualizar o TabBar não faz nada.

Este é o meu controlador TabBar:

class TabBarController: UITabBarController, UITabBarControllerDelegate {

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)!
}

override func viewDidLoad() {
    super.viewDidLoad()

    // This is where I currently decide which button to show the "complete" one if the task is done, and the incomplete one if not. 
    self.delegate = self
    if UserData.hasCompletedDailyTask() == true {
        setupCompleteMiddleButton()
    } else {
        setupIncompleteMiddleButton()
    }
}

// Incomplete button 
func setupIncompleteMiddleButton() {
    let middleButton = UIButton(frame: CGRect(x: (self.view.bounds.width / 2) - 25, y: -20, width: 50, height: 50))
    
    middleButton.backgroundColor = UIColor.systemYellow
    middleButton.setImage(UIImage(systemName: "sun.max.fill"), for: .normal)
    middleButton.imageView?.tintColor = UIColor.white
    middleButton.layer.cornerRadius = middleButton.frame.width / 2
    middleButton.clipsToBounds = true
    
    self.tabBar.addSubview(middleButton)
    middleButton.addTarget(self, action: #selector(self.middleButtonAction), for: .touchUpInside)
    self.view.layoutIfNeeded()
}

// Complete button
func setupCompleteMiddleButton() {
    let middleButton = UIButton(frame: CGRect(x: (self.view.bounds.width / 2) - 25, y: -20, width: 50, height: 50))

    middleButton.backgroundColor = UIColor.systemGreen
    middleButton.setImage(UIImage(systemName: "checkmark"), for: .normal)
    middleButton.imageView?.tintColor = UIColor.white
    middleButton.layer.cornerRadius = middleButton.frame.width / 2
    middleButton.clipsToBounds = true

    self.tabBar.addSubview(middleButton)
    middleButton.addTarget(self, action: #selector(self.middleButtonAction), for: .touchUpInside)
    self.view.layoutIfNeeded()
}

@objc func middleButtonAction(sender: UIButton) {
    self.selectedIndex = 1  
}
}

Obrigada!

Respostas

1 yankitPatel Jan 08 2021 at 17:11

Você pode tentar isso para um único objeto de botão globalmente e apenas alterar a imagem sempre que a tarefa for concluída ou não.

class TabBarController: UITabBarController, UITabBarControllerDelegate {

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)!
}

// TabbarController hode this button
var middleButton: UIButton!

override func viewDidLoad() {
    super.viewDidLoad()
    setupButton()
    // This is where I currently decide which button to show the "complete" one if the task is done, and the incomplete one if not.
    self.delegate = self
    // taskCompletion is a call back when UserData finish its task
    if UserData.taskCompletion {
        setupCompleteMiddleButton()
    } else {
    setupIncompleteMiddleButton()
    }
}

func setupButton() {
    middleButton = UIButton(frame: CGRect(x: (self.view.bounds.width / 2) - 25, y: -20, width: 50, height: 50))
    middleButton.backgroundColor = UIColor.systemYellow
    middleButton.layer.cornerRadius = middleButton.frame.width / 2
    middleButton.clipsToBounds = true
    self.tabBar.addSubview(middleButton)
    middleButton.addTarget(self, action: #selector(self.middleButtonAction), for: .touchUpInside)
    self.view.layoutIfNeeded()
}
//  Incomplete button
func setupIncompleteMiddleButton() {
  middleButton.backgroundColor = UIColor.systemYellow
    middleButton.setImage(UIImage(systemName: "sun.max.fill"), for: .normal)
    
}

// Complete button
func setupCompleteMiddleButton() {
    // change button color and image
    middleButton.backgroundColor = UIColor.systemGreen
    middleButton.setImage(UIImage(systemName: "checkmark"), for: .normal)
}

@objc func middleButtonAction(sender: UIButton) {
    self.selectedIndex = 1
}
EthanKwan Jan 08 2021 at 16:59

Talvez você possa tentar isto:

import UIKit

class TabBarController: UITabBarController, UITabBarControllerDelegate {
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
    }
    
    // TabbarController hode this button
    var middleButton: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // This is where I currently decide which button to show the "complete" one if the task is done, and the incomplete one if not.
        self.delegate = self
        // taskCompletion is a call back when UserData finish its task
        if UserData.taskCompletion {
            setupCompleteMiddleButton()
        }
        setupIncompleteMiddleButton()
    }
    
    //  Incomplete button 
    func setupIncompleteMiddleButton() {
        // initialize button  
        middleButton = UIButton(frame: CGRect(x: (self.view.bounds.width / 2) - 25, y: -20, width: 50, height: 50))

        middleButton.backgroundColor = UIColor.systemYellow
        middleButton.setImage(UIImage(systemName: "sun.max.fill"), for: .normal)
        middleButton.imageView?.tintColor = UIColor.white
        middleButton.layer.cornerRadius = middleButton.frame.width / 2
        middleButton.clipsToBounds = true
        self.tabBar.addSubview(middleButton)
        middleButton.addTarget(self, action: #selector(self.middleButtonAction), for: .touchUpInside)
        self.view.layoutIfNeeded()
    }
    
    // Complete button
    func setupCompleteMiddleButton() {
        // change button color and image
        middleButton.backgroundColor = UIColor.systemGreen
        middleButton.setImage(UIImage(systemName: "checkmark"), for: .normal)
    }
    
    @objc func middleButtonAction(sender: UIButton) {
        self.selectedIndex = 1
    }
}