Mam UIView, w którym ułożyłem UIButtons. Chcę znaleźć pozycje tych przycisków UIB.
Zdaję sobie sprawę, że buttons.frame
da mi to pozycje, ale da mi pozycje tylko w odniesieniu do bezpośredniego superwizji.
Czy jest jakiś sposób, abyśmy mogli znaleźć pozycje tych przycisków, z poszanowaniem superviewu UIButtons?
Na przykład załóżmy, że istnieje UIView o nazwie „firstView”.
Następnie mam inny UIView, „secondView”. Ten „SecondView” jest podziałem widoku „firstView”.
Następnie mam UIButton jako podwidok na „secondView”.
->UIViewController.view
--->FirstView A
------->SecondView B
------------>Button
Czy jest jakiś sposób, abyśmy mogli znaleźć pozycję tego UIButton w odniesieniu do „firstView”?
Chociaż nie jest to specyficzne dla przycisku w hierarchii, zgodnie z pytaniem, łatwiej to wizualizować i zrozumieć:
Stąd: oryginalne źródło
CelC:
CGPoint point = [subview1 convertPoint:subview2.frame.origin toView:viewController.view];
Szybki:
let point = subview1.convert(subview2.frame.origin, to: viewControll.view)
źródło
Zaktualizowano dla Swift 3
if let frame = yourViewName.superview?.convert(yourViewName.frame, to: nil) { print(frame) }
źródło
Rama: (X, Y, szerokość, wysokość).
Stąd szerokość i wysokość nie zmienią się nawet w super-super widoku. Możesz łatwo uzyskać X, Y w następujący sposób.
X = button.frame.origin.x + [button superview].frame.origin.x; Y = button.frame.origin.y + [button superview].frame.origin.y;
źródło
Jeśli istnieje wiele widoków nałożonych na siebie i nie potrzebujesz (lub nie chcesz) znać żadnych możliwych widoków między widokami, które Cię interesują, możesz to zrobić:
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) }
gdzie
targetView
byłby przycisk,baseView
byłobyViewController.view
.Ta funkcja próbuje wykonać następujące czynności:
Jeśli
targetView
nie ma super widoku, zwracana jest aktualna współrzędna.Jeśli
targetView's
super widok nie jest widokiem baseView (tj. Między przyciskiem a znajdują się inne widokiviewcontroller.view
), przekonwertowana współrzędna jest pobierana i przekazywana do następnegosuperview
.Nadal robi to samo przez stos widoków przesuwających się w kierunku baseView.
Gdy osiągnie
baseView
, wykonuje ostatnią konwersję i zwraca ją.Uwaga: nie obsługuje sytuacji, w której
targetView
jest umieszczony podbaseView
.źródło
Rozszerzenie UIView do konwersji ramki subview (inspirowane odpowiedzią @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: buttons.frame)
źródło
Możesz łatwo uzyskać super-super widok w następujący sposób.
secondView -> [button
superview ] firstView -> [[button superview ] superview]
Następnie możesz uzyskać położenie przycisku.
Możesz użyć tego:
xPosition = [[button superview] superview].frame.origin.x; yPosition = [[button superview] superview].frame.origin.y;
źródło