【问题标题】:iPhone - Get Position of UIView within entire UIWindowiPhone - 在整个 UIWindow 中获取 UIView 的位置
【发布时间】:2010-11-30 17:25:17
【问题描述】:

UIView 的位置显然可以由view.centerview.frame 等确定,但这只会返回UIView 相对于它的直接超级视图的位置。

我需要确定UIView 在整个 320x480 坐标系中的位置。例如,如果UIViewUITableViewCell 中,则它在窗口中的位置可能会发生巨大变化,而与超级视图无关。

任何想法是否以及如何实现?

干杯:)

【问题讨论】:

    标签: iphone cocoa-touch ios uiview uiwindow


    【解决方案1】:

    这很简单:

    [aView convertPoint:localPosition toView:nil];
    

    ... 将局部坐标空间中的一个点转换为窗口坐标。您可以使用此方法计算视图在窗口空间中的原点,如下所示:

    [aView.superview convertPoint:aView.frame.origin toView:nil];
    

    2014 年编辑:看看 Matt__C 评论的受欢迎程度,指出坐标似乎是合理的......

    1. 旋转设备时不要改变。
    2. 它们的原点始终位于未旋转屏幕的左上角。
    3. 窗口坐标:坐标系是由窗口边界定义的。屏幕坐标系和设备坐标系不同,不应与窗口坐标混淆。

    【讨论】:

    • awesome :) 我认为它应该很简单,但我感觉苹果不会那么容易......他们做到了。谢谢
    • 请注意,在 toView 参数中指定 nil 会为您提供设备坐标,如果您不处于纵向,这将不是您想要的。见convertpointtoview-in-landscape-mode-giving-wrong-values
    • 这个方法一直为我返回aView.frame.origin。我花了一段时间才意识到我的视图的超级视图本身没有超级视图。
    • 如果你的 superView 没有 superView 你的视图根本不应该被看到
    • 将 @Matt__C 链接解决方案适应您的情况,它将变为:[view.superview convertPoint:view.frame.origin toView:[UIApplication sharedApplication].keyWindow.rootViewController.view]
    【解决方案2】:

    在 Swift 中:

    let globalPoint = aView.superview?.convertPoint(aView.frame.origin, toView: nil)
    

    【讨论】:

      【解决方案3】:

      Swift 5+

      let globalPoint = aView.superview?.convert(aView.frame.origin, to: nil)
      

      【讨论】:

        【解决方案4】:

        Swift 3,带扩展:

        extension UIView{
            var globalPoint :CGPoint? {
                return self.superview?.convert(self.frame.origin, to: nil)
            }
        
            var globalFrame :CGRect? {
                return self.superview?.convert(self.frame, to: nil)
            }
        }
        

        【讨论】:

        • 有些时候superview是不够的先生
        【解决方案5】:

        这里是@Mohsenasm 的回答和@Ghigo 对 Swift 采用的评论的组合

        extension UIView {
            var globalFrame: CGRect? {
                let rootView = UIApplication.shared.keyWindow?.rootViewController?.view
                return self.superview?.convert(self.frame, to: rootView)
            }
        }
        

        【讨论】:

        • 简单又好看!
        • 尽其所能。谢谢
        【解决方案6】:

        对我来说,这段代码效果最好:

        private func getCoordinate(_ view: UIView) -> CGPoint {
            var x = view.frame.origin.x
            var y = view.frame.origin.y
            var oldView = view
        
            while let superView = oldView.superview {
                x += superView.frame.origin.x
                y += superView.frame.origin.y
                if superView.next is UIViewController {
                    break //superView is the rootView of a UIViewController
                }
                oldView = superView
            }
        
            return CGPoint(x: x, y: y)
        }
        

        【讨论】:

          【解决方案7】:

          这对我有用

          view.layoutIfNeeded() // this might be necessary depending on when you need to get the frame
          
          guard let keyWindow = UIApplication.shared.windows.first(where: { $0.isKeyWindow }) else { return }
          
          let frame = yourView.convert(yourView.bounds, to: keyWindow)
          
          print("frame: ", frame)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-03-02
            • 2013-12-12
            • 2023-04-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多