咨询:如何获取UIStackView内UIButton被点击时的正确中心点
嘿,太懂你这种在StackView里拿按钮中心点踩坑的感觉了!自动布局容器的坐标逻辑确实容易绕晕,我给你梳理几个靠谱的解决思路:
1. 先搞清楚坐标系的核心问题
你直接拿到的button.center,是**相对于它的父视图(也就是UIStackView)**的坐标,如果你要在按钮本身上面绘制内容,这个值其实不是你需要的——因为绘制操作是基于按钮自身的坐标系的。这时候应该用按钮自身bounds的中点:
@IBAction func buttonTapped(_ sender: UIButton) { // 按钮自身坐标系的中心点(绘制内容时用这个最准确) let buttonInnerCenter = CGPoint(x: sender.bounds.midX, y: sender.bounds.midY) print("按钮内部中心点:\(buttonInnerCenter)") }
2. 转换到你需要的目标坐标系
如果你要的是相对于控制器主View、或者其他父视图的中心点,就得用convert(_:to:)方法做坐标转换,别直接用center:
@IBAction func buttonTapped(_ sender: UIButton) { // 把按钮相对于StackView的中心点,转换成相对于主View的坐标 let centerInMainView = sender.convert(sender.center, to: self.view) print("相对于主View的中心点:\(centerInMainView)") }
小提醒:点击事件触发时,布局理论上已经完成,但如果还是拿到错误值,可以先调用
sender.layoutIfNeeded()强制刷新布局,再获取坐标。
3. 排查布局异常的小技巧
如果还是不对,建议打印几个关键值排查问题,看看是不是StackView的布局属性搞的鬼:
@IBAction func buttonTapped(_ sender: UIButton) { print("按钮的frame:\(sender.frame)") print("StackView的frame:\(sender.superview?.frame ?? .zero)") print("按钮相对于StackView的center:\(sender.center)") }
比如StackView如果设置了layoutMargins或者alignment属性,可能会让子视图的位置偏移,通过这些打印值就能快速定位问题。
4. 避免在布局未完成时获取坐标
虽然你是在点击事件里操作,但如果之前有异步布局或者动画的情况,也可能导致布局没完成。这种情况下,在获取坐标前加一句sender.layoutIfNeeded(),强制让视图完成布局再拿值,就不会出错了。
总结一下:如果是在按钮上绘制内容,优先用bounds.midX/midY;如果需要外部坐标系的位置,就用convert方法转换坐标,基本就能解决问题啦!
内容的提问来源于stack exchange,提问作者Tarvo Mäesepp
相关产品推荐
相关产品推荐

