0

I need to get a label's center.x directly aligned with the image inside a tabBar's imageView. Using the below code the label is misaligned, instead of the label's text "123" being directly over the bell inside the tabBar, it's off to the right.

enter image description here

guard let keyWindow = UIApplication.shared.windows.first(where: { $0.isKeyWindow }) else { return }

guard let fourthTab = tabBarController?.tabBar.items?[3].value(forKey: "view") as? UIView else { return }

guard let imageView = fourthTab.subviews.compactMap({ $0 as? UIImageView }).first else { return }

guard let imageViewRectInWindow = imageView.superview?.superview?.convert(fourthTab.frame, to: keyWindow) else { return }

let imageRect = AVMakeRect(aspectRatio: imageView.image!.size, insideRect: imageViewRectInWindow)

myLabel.text = "123"
myLabel.textAlignment = .center // I also tried .left
myLabel.center.x = imageRect.midX
myLabel.center.y = UIScreen.main.bounds.height - 74
myLabel.frame.size.width = 50
myLabel.frame.size.height = 21

print("imageViewRectInWindow: \(imageViewRectInWindow)") // (249.99999999403948, 688.0, 79.00000000298022, 48.0)
print("imageRect: \(imageRect)") // (265.4999999955296, 688.0, 48.0, 48.0)
print("myLabelRect: \(myLabel.frame)") // (289.4999999955296, 662.0, 50.0, 21.0)
Lance Samaria
  • 17,576
  • 18
  • 108
  • 256
  • Does this your answer https://stackoverflow.com/a/65367010/14733292 ? – Raja Kishan Jan 22 '21 at 13:11
  • That is my question and that’s your answer that I upvoted, lol. – Lance Samaria Jan 22 '21 at 13:13
  • I’m using superView., that part works fine. – Lance Samaria Jan 22 '21 at 13:15
  • Why don't you try by setting constraints – Luca Sfragara Jan 22 '21 at 14:58
  • @LucaSfragara How do you constraints from the image inside the imageView? – Lance Samaria Jan 22 '21 at 14:59
  • I meant constraint, using NSLayoutconstraint.activate, the "123" label position to be relative to the one of the bell Icon. And also, it might be silly but check that the problem is not that the bell in the image is simply not centered in the image itself. – Luca Sfragara Jan 22 '21 at 15:04
  • @LucaSfragara I was thinking that the bell in the image isn't centered but Xcode is acting up and the Debug View Hierarchy isn't working. The thing is, even if the bell isn't centered, as long I get the the correct coordinates of the bell image itself, the label should center.x should align. Actually I have to coordinates, why they aren't matching up is the problem – Lance Samaria Jan 22 '21 at 15:08
  • Yes, the problem is that it may already be aligned to the imageView.centerX. But the imageView.image might be a bell with more space to the right, thus not centered. However, if you are using icons, this problem should be avoided. – Luca Sfragara Jan 22 '21 at 15:10
  • the guy below was correct, I just moved the same exact code that I have to the cell's `layoutSubviews()` and it worked. Thanks for the suggestions! – Lance Samaria Jan 22 '21 at 15:12

2 Answers2

0

It might be a layout issue, as in, setting the coordinates before everything is laid out. Where do you call the code from? I was able to get it to work with the following, but got strange results with some if the functions you use, so cut out a couple of them. Using the frame of the tabview worked for me, and calling the coordinate setting from the view controller's viewDidLayoutSubviews function.

class ViewController: UIViewController {

    var myLabel: UILabel = UILabel()

    var secondTab: UIView?

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        self.view.addSubview(myLabel)
        myLabel.textColor = .black
        myLabel.text = "123"
        myLabel.textAlignment = .center // I also tried .left
        myLabel.frame.size.width = 50
        myLabel.frame.size.height = 21

        secondTab = tabBarController?.tabBar.items?[1].value(forKey: "view") as? UIView
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

        guard let secondTab = secondTab else {
            return
        }

        myLabel.center.x = secondTab.frame.midX
        myLabel.center.y = UIScreen.main.bounds.height - 70
    }
}
James
  • 459
  • 1
  • 3
  • 10
  • I kept all of the code that I had the same. What you was correct about was moving the code to `layoutSubviews()` (I'm using a cell). Thanks for the help! – Lance Samaria Jan 22 '21 at 15:14
0

Try below code to return a centreX by tabbar item index.

extension UIViewController {

    func centerX(of tabItemIndex: Int) -> CGFloat? {
        guard let tabBarItemCount = tabBarController?.tabBar.items?.count else { return nil }
        let itemWidth = view.bounds.width / CGFloat(tabBarItemCount)
        return itemWidth * CGFloat(tabItemIndex + 1) - itemWidth / 2
    }
}
Wei Lu
  • 1,069
  • 9
  • 6