Search code examples
iosswiftuinavigationcontrolleruilabel

UILabel Won't Pin To Bottom of NavBar


Is there a way to get the label to pin to the bottom instead of the top?

    var timeLabel: UILabel = {
        let label = UILabel()
        label.backgroundColor = .clear
        label.textColor = .gray
        label.font = UIFont.systemFont(ofSize: 15, weight: .bold)
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

    func setTitle(subtitle:UILabel) -> UIView {
        
        let navigationBarHeight = Int(self.navigationController!.navigationBar.frame.height)
        let navigationBarWidth = Int(self.navigationController!.navigationBar.frame.width)

        let titleView = UIView(frame: CGRect(x: 0, y: 0, width: navigationBarWidth, height: navigationBarHeight))
        titleView.addSubview(subtitle)

        return titleView

    }

then in viewDidLoad

self.navigationItem.titleView = setTitle(subtitle: timeLabel)

Image

UPDATE

Image3


Solution

  • Set your label with text alignment to right:

    var timeLabel: UILabel = {
        let label = UILabel()
        label.backgroundColor = .clear
        label.textColor = .gray
        label.textAlignment = .right
        label.font = UIFont.systemFont(ofSize: 15, weight: .bold)
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    

    now in viewDidLoad add the label to nav bar and set constraints:

    if let navigationBar = self.navigationController?.navigationBar {
       timeLabel.text = "FRIDAY, SEPTEMBER 18" // set here your string date
       navigationBar.addSubview(timeLabel)
       timeLabel.leadingAnchor.constraint(equalTo: navigationBar.leadingAnchor, constant: 150).isActive = true // set the constant how do you prefer
       timeLabel.trailingAnchor.constraint(equalTo: navigationBar.trailingAnchor, constant: -20).isActive = true
       timeLabel.bottomAnchor.constraint(equalTo: navigationBar.bottomAnchor, constant: 0).isActive = true
       timeLabel.heightAnchor.constraint(equalToConstant: 50).isActive = true
     }
    

    UPDATE FOR TABLE VIEW SCROLLING

    Add UIScrollViewDelegate to your controller, after that implement scrollViewWillBeginDragging and tableView willDisplay method like this:

    func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
        if scrollView.contentSize.height > 0 && ((scrollView.contentOffset.y + scrollView.safeAreaInsets.top) == 0) {
            timeLabel.alpha = 0
        }
    }
    
    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        if tableView.contentOffset.y <= 0 {
            timeLabel.alpha = 1
        }
    }
    

    BONUS

    for a cool effect when the timeLabel show again add animation in tableView willDisplay like that:

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        if tableView.contentOffset.y <= 0 {
            UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseOut) {
                self.timeLabel.alpha = 1
            } completion: { (_) in
                print("visible TimeLabel")
            }
        }
    }
    

    this is the result

    enter image description here

    UPDATE FOR GILL

    This explained above is not the rule but just a trick, I advise you to consider putting the date in the header so you would no longer have problems with the title: delete scrollViewWillBeginDragging and tableView willDisplay function and add viewForHeaderInSection, to do this delete existent timeLabel constraints and declare viewForHeaderInSection:

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let v = UIView()
        v.backgroundColor = UIColor(red: 0.9018846154, green: 0.9020112157, blue: 0.9018446803, alpha: 1)
        v.addSubview(timeLabel)
        // declare here your timeLabel constraints
        timeLabel.topAnchor.constraint(equalTo: v.topAnchor).isActive = true
        timeLabel.trailingAnchor.constraint(equalTo: v.trailingAnchor).isActive = true
        timeLabel.leadingAnchor.constraint(equalTo: v.leadingAnchor).isActive = true
        timeLabel.bottomAnchor.constraint(equalTo: v.bottomAnchor).isActive = true
        return v
    }
    

    now set the hight of your header:

    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 50
    }
    

    and this is the result:

    enter image description here