I have following hierarchy: Controller.view [tableView, overlayView]. Table view has top inset of 16 points from parent view via constraint, overlay view - not.
Inside table cell content view I have another view responder and I want to show it's image on view overlayView.
If I use this code (inside overlay view):
CGRect frame;
CGPoint origin = [responder convertPoint:responder.frame.origin toView:self];
// FIXME origin.y -= 16;
frame.origin = origin;
frame.size = responder.frame.size;
_imageView.frame = frame;
UIGraphicsBeginImageContextWithOptions(responder.bounds.size, NO, 0);
[responder drawViewHierarchyInRect:responder.bounds afterScreenUpdates:YES];
_imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
I get imageView with 16 points offset from responder origin and image not fit into original view. So I have to use line with FIXME mark to have origin points equal. Why converting don't work?
You should be converting the point from the responder's superview, not the responder itself. Change your second line to this:
CGPoint origin = [responder.superview convertPoint:responder.frame.origin toView:self];
Related
I have a UIView inside a UIScrollView and am using a CAShapeLayer with several sublayers to draw in the view. In some cases the layer is not visible and I'd like to scroll the view so that the layer becomes visible. To scroll I'm using:
[self.scrollView setContentOffset: CGPointMake(0, offset) animated: NO];
I'm having a hard time to figure out what the offset is. I've tried to get the enclosing rect, but that always has the origin at (0,0).
How can I calculate the position of the layer to use in offset?
UPDATE:
This seems to work to get the enclosing rect for all sublayers:
- (CGRect) enclosingLayerRect
{
CGRect rect = CGRectZero;
if (self.sublayers.count)
{
CAShapeLayer *layer = self.sublayers[0]; // need to get the first one, otherwise the origin will be (0,0)
rect = CGPathGetBoundingBox(layer.path);
for (CAShapeLayer *layer in self.sublayers)
{
CGRect layerRect = CGPathGetBoundingBox(layer.path);
rect = CGRectUnion(rect, layerRect);
}
}
return rect;
}
Feel free to comment if there is a better, easier way to do this.
Use the convertRect:toView: method to convert the frame to the scroll view's coordinate system, and the resulting rect should give you the required content offset.
I am doing objective-C app and I want create a UIView with my custom values and there is a problem that i can not fix.
This code works fine:
CGRect rect;
rect.origin.x = 10; rect.origin.y = 20;
rect.size.width = 30; rect.size.height = 40;
NSLog(#" %#",NSStringFromCGRect(rect));
But this one in NSLOG returns origin point to (0,0) and width and height fine:
UIView* aux = [[UIView alloc] initWithFrame:CGRectMake(10,20,30,40)];
NSLog(#" %#",NSStringFromCGRect(aux.bounds));
Is there any problem in initialization of UIView with CGRectMake?
Thanks
You are printing view.bounds, but not view.frame.
Just change it to:
NSLog(#" %#",NSStringFromCGRect(aux.frame));
First a recap on the question: frame, bounds and center and theirs relationships.
Frame A view's frame (CGRect) is the position of its rectangle in the superview's coordinate system. By default it starts at the top left.
Bounds A view's bounds (CGRect) expresses a view rectangle in its own coordinate system.
Center A center is a CGPoint expressed in terms of the superview's coordinate system and it determines the position of the exact center point of the view.
You need to use:
NSLog(#" %#",NSStringFromCGRect(aux.frame));
The origin of the bounds of a view are always (0, 0). You have to change your code to
NSLog(#" %#",NSStringFromCGRect(aux.frame));
See Apple's documentation for an explanation here
The bounds of an UIView is the rectangle, expressed as a location (x,y) and size (width,height) relative to its own coordinate system (0,0).
The frame of an UIView is the rectangle, expressed as a location (x,y) and size (width,height) relative to the superview it is contained within.
So you need to use view.frame in your log method as-
NSLog(#" %#",NSStringFromCGRect(aux.frame));
I have a view containing a UITableView. On view did load, I set the table's tableFooterView to be a view I create by hand (a UIView containing a button). When the view appears, I adjust the frame of the tableFooterView:
CGRect tableFrame = self.myTableView.frame;
CGRect originalFrame = self.tableFooter.frame;
CGSize imageSize = CGSizeMake(40.0f, 40.0f);
CGRect footerFrame = CGRectMake(originalFrame.origin.x, originalFrame.origin.y, tableFrame.size.width, imageSize.height);
self.tableFooter.frame = footerFrame;
CGRect nextFrame = CGRectMake((footerFrame.size.width - imageSize.width) / 2.0f, 0.0f, imageSize.width, imageSize.height);
self.tableFooterButton.frame = nextFrame;
On iOS7, this works the way I want -- when I scroll to the bottom of the table, I see my footer view. On iOS6, when I scroll to the bottom of the table, the footer view is still offscreen (I can pull the scroll view and see it, but it resets offscreen when I release).
What should I do differently?
After change the frame of table footer, try this:
self.myTableView.tableFooterView = nil ;
self.myTableView.tableFooterView = self.tableFooter ;
how to get the absolute position of a section header in tableview?
I have already used the tableView:viewForHeaderInSection: to get the header's view.But now i need to get the absolute position of this view in the screen.
the return value's frame is not the absolute position in the screen.I also tried to call superview,but it seems not work.
tableView:viewForHeaderInSection: is a UITableViewDelegate method for creating a header view for display. This means, however, that the view has not been added to the view hierarchy, rendering it's frame meaningless for your purposes.
Try
UIView *headerView = [tableView headerViewForSection:sectionIndex];
instead. From there you can try the following methods on the returned view to get the rect of the view in any other view's coordinate system:
[headerView convertRect:[headerView bounds] toView:[headerView window]];
Assuming that your top-level view directly contains table view which in turn contains header:
- (CGRect) getHeaderAbsoluteFrame : (UIView *)headerview :(UIView *)tableview
{
CGRect frame = headerview.frame;
CGRect tableFrame = tableview.frame;
float x = tableview. origin.x + headerview.frame.origin.x;
float y = tableview.frame.origin.y + headerview.frame.origin.y;
CGRect rect = CGRectMake (x,y,headerview.frame.size.width, headerview.frame.size.height);
return rect;
}
I always had the impression the origin of a View defines its position inside a parent view. But in my application the Origin is 0,0 no matter where I move my view on the Interface.
This is the code I use:
- (void)drawRect:(CGRect)rect
{
float orginX = rect.origin.x;
float orginY = rect.origin.y;
NSLog(#"X-Origin %f.", orginX);
NSLog(#"Y-Origin %f.", orginY);
Where is my mistake?
The rect passed in to drawRect: is the view's bounds, not it's frame, so its origin will be 0,0.
I believe the drawRect method is passed the frame relative to the view's origin, i.e. the origin will always be 0,0. This is because you should draw your view without knowing or caring where it is in relation to its superview.