Reputation: 1617
There are tons of UIView centering questions and answers but I did not find one that matches my criteria. I have a UIImageView subclass that is the subview of another (the same) UIImageView subclass. I need to be able to "reset" my UIImageView subclass so that with user interaction it is centered in the screen (the view of the root view controller).
Just doing this:
- (void)reset {
[self setCenter: self.superview.center];
}
...does not work because the center point is in the coordinate system of the superview, NOT the root view. The superview can be dragged far from the center of the root view.
Initially I looped thru the superview hierarchy to find the root view but that still didn't work, again because of the different coordinate systems and variety of scale that the user could apply to each UIImageView subclass at each level of the nested views.
I did not find a complete solution on SO, so I wrote my own and posted it here. Hopefully it will save others some time and SO spelunking.
Upvotes: 0
Views: 189
Reputation: 1617
To center a UIView in "the screen", you need to center it relative to the view of the root view controller. This is very useful if you are subclassing UIView or it's subclasses (ImageView for example), programmatically, and your superview is not the view of a view controller. Here is a method to center your view in the root view, regardless of where it lies in the view hierarchy:
// center the view in the root view
- (void)centerInRootview:UIView *view {
UIView *rootview = UIApplication.sharedApplication.keyWindow.rootViewController.view;
// if the view hierarchy has not been loaded yet, size will be zero
if (rootview.bounds.size.width > 0 &&
rootview.bounds.size.height > 0) {
CGPoint rootCenter = CGPointMake(CGRectGetMidX(rootview.bounds),
CGRectGetMidY(rootview.bounds));
// center the view relative to it's superview coordinates
CGPoint center = [rootview convertPoint:rootCenter toView:view.superview];
[view setCenter:center];
}
}
This uses the UIView.convertPoint:toView
method to convert from the coordinate system of the root view to the coordinate system of the superview of your view.
I use this method in a UIView
category so that it is available from any UIView
subclass. Here is View.h
:
//
// View.h - Category interface for UIView
//
#import <UIKit/UIKit.h>
@interface UIView (View)
- (void)centerInRootview;
@end
And View.m:
//
// View.m - Category implementation for UIView
//
#import "View.h"
@implementation UIView (View)
// center the view in the root view
- (void)centerInRootview {
// make sure the view hierarchy has been loaded first
if (self.rootview.bounds.size.width > 0 &&
self.rootview.bounds.size.height > 0) {
CGPoint rootCenter = CGPointMake(CGRectGetMidX(self.rootview.bounds),
CGRectGetMidY(self.rootview.bounds));
// center the view in it's superview coordinates
CGPoint center = [self.rootview convertPoint:rootCenter toView:self.superview];
[self setCenter:center];
}
}
@end
And here is a simplistic example of how to use it from a UIImageView subclass. ImageView.h:
//
// ImageView.h - Example UIImageView subclass
//
#import <UIKit/UIKit.h>
@interface ImageView : UIImageView
- (void)reset;
@end
And ImageView.m:
#import "ImageView.h"
@implementation ImageView
- (void)reset {
self.transform = CGAffineTransformIdentity;
// inherited from UIImageView->UIView (View)
[self centerInRootview];
}
@end
Upvotes: 0