【问题标题】:Get position of UIView in respect to its superview's superview获取 UIView 相对于其父视图的父视图的位置
【发布时间】:2013-07-08 11:32:38
【问题描述】:

我有一个 UIView,我在其中安排了 UIButton。我想找到那些 UIButtons 的位置。

我知道buttons.frame 会给我职位,但它只会给我与其直接上级相关的职位。

相对于 UIButtons 超级视图的超级视图,有什么方法可以找到这些按钮的位置吗?

例如,假设有一个名为“firstView”的 UIView。

然后,我有另一个 UIView,“secondView”。这个“SecondView”是“firstView”的子视图。

然后我将 UIButton 作为“secondView”上的子视图。

->UIViewController.view
--->FirstView A
------->SecondView B
------------>Button

现在,我们有什么方法可以找到那个 UIButton 相对于“firstView”的位置?

【问题讨论】:

    标签: iphone ios uiview uibutton cgrect


    【解决方案1】:

    你可以用这个:

    Objective-C

    CGRect frame = [firstView convertRect:buttons.frame fromView:secondView];
    

    斯威夫特

    let frame = firstView.convert(buttons.frame, from:secondView)
    

    文档参考:

    https://developer.apple.com/documentation/uikit/uiview/1622498-convert

    【讨论】:

    • 要补充一点,如果您的视图并不总是在同一个视图中(例如,如果您在函数中使用它),您可以输入 '...fromView:[button superview]] ;'
    • 在 SwiftUI 中有没有办法做到这一点?
    【解决方案2】:

    虽然不是特定于层次结构中的按钮,但我发现这更容易可视化和理解:

    从这里:original source

    对象:

    CGPoint point = [subview1 convertPoint:subview2.frame.origin toView:viewController.view];
    

    斯威夫特:

    let point = subview1.convert(subview2.frame.origin, to: viewControll.view)
    

    【讨论】:

      【解决方案3】:

      为 Swift 3 更新

          if let frame = yourViewName.superview?.convert(yourViewName.frame, to: nil) {
      
              print(frame)
          }
      

      【讨论】:

        【解决方案4】:

        用于转换子视图框架的 UIView 扩展(灵感来自@Rexb 答案)。

        extension UIView {
        
            // there can be other views between `subview` and `self`
            func getConvertedFrame(fromSubview subview: UIView) -> CGRect? {
                // check if `subview` is a subview of self
                guard subview.isDescendant(of: self) else {
                    return nil
                }
                
                var frame = subview.frame
                if subview.superview == nil {
                    return frame
                }
                
                var superview = subview.superview
                while superview != self {
                    frame = superview!.convert(frame, to: superview!.superview)
                    if superview!.superview == nil {
                        break
                    } else {
                        superview = superview!.superview
                    }
                }
                
                return superview!.convert(frame, to: self)
            }
        
        }
        
        // usage:
        let frame = firstView.getConvertedFrame(fromSubview: buttonView)
        

        【讨论】:

        • 这是完美的解决方案!非常感谢!
        【解决方案5】:

        框架:(X,Y,宽度,高度)。

        因此,即使是超级超级视图,宽度和高度也不会改变。您可以通过以下方式轻松获取 X、Y。

        X = button.frame.origin.x + [button superview].frame.origin.x;
        Y = button.frame.origin.y + [button superview].frame.origin.y;
        

        【讨论】:

        • 但是为什么我得到如此高的 X、Y 值,就像我的 X 为 0,0 时那样,然后我得到你的代码行; 180224左右?
        【解决方案6】:

        如果有多个视图堆叠并且您不需要(或不想)知道您感兴趣的视图之间的任何可能视图,您可以这样做:

        static func getConvertedPoint(_ targetView: UIView, baseView: UIView)->CGPoint{
            var pnt = targetView.frame.origin
            if nil == targetView.superview{
                return pnt
            }
            var superView = targetView.superview
            while superView != baseView{
                pnt = superView!.convert(pnt, to: superView!.superview)
                if nil == superView!.superview{
                    break
                }else{
                    superView = superView!.superview
                }
            }
            return superView!.convert(pnt, to: baseView)
        }
        

        其中targetView 是按钮,baseViewViewController.view
        这个函数试图做的是:
        如果targetView没有超级视图,则返回当前坐标。
        如果targetView's 超级视图不是基本视图(即按钮和viewcontroller.view 之间还有其他视图),则检索转换后的坐标并将其传递给下一个superview
        它通过向 baseView 移动的视图堆栈继续执行相同的操作。
        一旦到达baseView,它就会进行最后一次转换并将其返回。
        注意:它不处理targetView 位于baseView 之下的情况。

        【讨论】:

          【解决方案7】:

          您可以通过以下方式轻松获得超级超级视图。

          secondView -> [按钮超级视图]
          firstView -> [[按钮超级视图] 超级视图]

          然后,你可以得到按钮的位置..

          你可以用这个:

          xPosition = [[button superview] superview].frame.origin.x;
          yPosition = [[button superview] superview].frame.origin.y;
          

          【讨论】:

          • 添加一些解释会使这个答案更有用。
          【解决方案8】:

          请注意,无论您需要在视图层次结构中定位的视图有多深(嵌套),以下代码都能正常工作。

          假设您需要myView 的位置,它位于myViewsContainer 内部并且在视图层次结构中非常深,只需按照以下顺序即可。

          let myViewLocation = myViewsContainer.convert(myView.center, to: self.view)
          
          • myViewsContainer:需要定位的视图所在的视图容器。

          • myView:您需要位置的视图。

          • self.view:主视图

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-01-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多