I pass in an image view to an init method that needs the size of the image view. Then call convertRect:toView:
- (id) initWithImageView:(UIImageView*) imageView {
self = [super init];
if (self) {
CGRect imageViewFrame = [[imageView superview] convertRect: imageView.frame toView: self.view];
}
}
Which was called with:
MyViewController *viewController = [[MyViewController alloc] initWithImageView:imageView];
viewController.delegate = self;
[self.tabBarController presentViewController:viewController animated:NO completion:nil];
imageViewFrame is then
(origin = (x = 0, y = -120.22867049625003), size = (width = 750, height = 750))
the imageView has a frame of
frame = (0 -60.1143; 375 375);
and it's super view is has a frame of
frame = (0 0; 375 254.5);
Why would it be scaled up x2 ?
Further testing on iPhone 6 plus (3x) simulator makes imageViewFrame
(origin = (x = 0, y = -199.30952358000002), size = (width = 1242, height = 1242))
The first tests were done on iPhone 6 simulator (2x). Why is convertRect:toView: working in pixels and not points?
In your -initWithImageView:
, your self.view
has not been generated yet, you can try to cache the imageView
temporary, and do the rect converting action in -viewDidLoad
instead:
// If you don't user Interface Builder
- (void)loadView
{
CGRect frame = <your_view_frame>;
UIView * view = [[UIView alloc] initWithFrame:frame];
self.view = view;
}
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect imageViewFrame = [[imageView superview] convertRect:imageView.frame toView:self.view];
...
}
As the doc said for -convertRect:toView:
's view param:
The view that is the target of the conversion operation. If view is nil, this method instead converts to window base coordinates. Otherwise, both view and the receiver must belong to the same UIWindow object.
If you persist in doing in -initWithImageView
method, declare a custom view iVar, alloc & init in your -initWithImageView
method, then in -loadView
, assign the iVar to self.view
. And of course, the way you used to convert rect in -initWithImageView
should be
CGRect frame = <your_view_frame>;
_iVarView = [[UIView alloc] initWithFrame:frame];
CGRect imageViewFrame = [[imageView superview] convertRect:imageView.frame
toView:_iVarView];
In -loadView
:
- (void)loadView
{
self.view = _iVarView;
}
But it's not recommend to do it in this way, I suggest you init UI in the right methods of view's life loop.
Here is a correct method: SWIFT:
extension UIView {
func convertRectCorrectly(rect: CGRect, toView view: UIView) -> CGRect {
if UIScreen.mainScreen().scale == 1 {
return self.convertRect(rect, toView: view)
}
else if self == view {
return rect
}
else {
var rectInParent = self.convertRect(rect, toView: self.superview)
rectInParent.origin.x /= UIScreen.mainScreen().scale
rectInParent.origin.y /= UIScreen.mainScreen().scale
let superViewRect = self.superview!.convertRectCorrectly(self.superview!.frame, toView: view)
rectInParent.origin.x += superViewRect.origin.x
rectInParent.origin.y += superViewRect.origin.y
return rectInParent
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With