I have a tablview that populates cells. When a cell is clicked I pragmatically populate textfields My question is how do I get the y coordinate so that I can position the UITextField based on where the user is currently located in the bounds? Or either make it so that I set the UITextField as a fixed position so that if you were to scroll down in the tableview the UITextField would always remain in the same place.
I don't mind either option but what would be the best approach to this?
UPDATE:
Okay here is what I am asking. When you populate a tablview with cells and it exceeds the screens physical seeing bounds you would scroll down to view the other cells right? So If i use:
float width = [[UIScreen mainScreen] bounds].size.width;
self.cardnameTextField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, width, 25)];
0 = the y position. So that will populate at the top of my UiTableview at the 0,0 position which will be located at the top most left of the UITableView. Now what I am asking is lets say I scroll down to select a cell that exceeded the bounds of the physical screen and I selected the cell, it would populate the UITextField at the top most left of the UITableView 0,0 rather than the top most left of the physical screen. How do I get the physical screens y coordinate so I can position the UITextField so that the user will always see it.
Okay I just figured it out.
So when you execute [self.viewaddSubview:self.cardnameTextField]; this will position it within the UITableView which I would than have to find the y coordinate of the actual screens most top position. But if I run [self.view.window addSubview:self.cardnameTextField]; it sets it to the actual window giving it a almost CSS functionality of position:fixed; Which was exactly what I was looking for.
Even with your comment, it isn't very clear what you are asking.
If you are asking how to convert a cell's position to screen coordinates, it's pretty easy. UIView has a whole family of methods for converting coordinates from one view's coordinate system to another. They work as long as the 2 views are part of the same view hierarchy. You might take the cell's contentView.bounds.origin (which will be in the content view's coordinate system and) convert the position to the view controller content view's coordinate system:
CGPoint cellOrigin = cell.contentView.bounds.origin;
cellOrigin = [self.view convertPoint: cellOrigin fromView: cell.contentView];
The above code would give you the coordinates of a cell's origin, in the coordinates of the view controller's content view.
If that's NOT what you're asking then you will need to update your question to make it clear WHAT you are asking.
Related
I've got a stack view and I'm wanting when the user clicks on one of the buttons a little "bar" view centers underneath it (the view is outside of the stack view). I had this working before I layed out the buttons with autolayout by just setting
movableView.center.x = newView.center.x
and animating it. Now with the buttons in the stack view the movableView's center X does not line up with the buttons' center x's. It's like 1/3 way off centered.
The movable view itself has no autolayout on it.
What is the cause of this and how can I align the center x of views that have auto layout in play?
Without more information this is my best guess as to what the issue may be.
The center attribute is based on the view's frame, which means that it is using the superview (in this case the UIStackView) coordinate system. If your UIStackView's frame.origin.x is not at 0, which is how it appears in your screenshot, you will need to adjust your movableView.center.x accordingly. This could be as simple as:
movableView.center.x = newView.center.x + stackView.frame.origin.x
Another option would be to convert the center to the main view's coordinate system, like this:
movableView.center.x = newView.convert(newView.center, to: self.view).x
I am trying to retrieve rect value of a class in ViewDidAppear. The button is in UITableViewCell. All values return correct except frame.origin.y. It returns -1.5. I am wondering what might cause that.
CGRect customRect = CGRectMake(self.favoriteButton.frame.origin.x, self.favoriteButton.frame.origin.y, self.favoriteButton.frame.size.height, self.favoriteButton.frame.size.width) ;
Origin.y is defined in an unintuitive.
First, moving down is positive and up is negative (aka larger numbers means the view will appear lower on the screen).
Second, the origin is relative to the top left corner of the immediate parent view (in your case the cell). If origin.y really is -1.5 then the top of your button is just one and a half points above the top of your table view cell, (which sounds likely). If your origin.y really should be 400-ish points it means for it to appear in your UITableViewCell your tableViewCell would have to be over 400 points tall.
This could be the case but I'm wondering if what you're looking for is not origin.y, but how far bellow the top of the root view (self.view in your view controller) the top of your button is. If so try:
CGPoint originInRootview = [self.view convertPoint:CGPointZero fromView:self.favoriteButton];
CGFloat theNumberIThinkYouWant = originInRootview.y
There are two things
1-) You said that it is in TableViewCell so it returns correct. Because you put button inside a view(TableViewVell container view), button gets it coordinates from container view not from superview.
2-) If TableViewCell is big enough and starts from y=0 and you are sure it is wrong and must be something like 400. Try to get the rect value at viewDidLayoutSubviews
All values return correct except frame.origin.y. It returns -1.5. I am wondering what might cause that.
Applying a transform to the view can cause it's frame property to be invalid. From the documentation for UIView's frame property:
Warning
When the value of this property is anything other than the identity
transform, the value in the frame property is undefined and should be
ignored.
So, if you're not seeing what you expect, compare your view's transform to CGAffineTransformIdentity.
I'm rather new to Objective-C programming and I'm making an app that requires the Table View to load from the bottom to the top, similar to messaging apps. I've tried searching on Google about this but I'm still a bit confused about the code used. Thanks in advance!
UITableView polls its dataSource for cells based on what is visible on the screen. So, the key to your problem is you want to show the bottom of the table first.
In order to do that, you can call [tableView setContentOffset:CGPointMake(0, CGFLOAT_MAX)];, which will scroll the UITableView to the bottom.
Keep in mind that where you place that call may vary based on whether or not you are using Autolayout.
See How to scroll to the bottom of a UITableView on the iPhone before the view appears for more information
Here's what I did when I designed a chatbot:
1 - Add a UItableView in IB and set its constraints.
2 - When I added a new cell (message), I would change the Y position of the UITableView. For example, when the first message was added to the data source array, I would calculate the height of that cell, so if the height of that cell was 50, I would set the Y position of my UITableView as the current height of the UITableView minus the height of the cell that is being added. This makes it look like the messages are being added from the bottom.
3 - Repeat the above cycle in step 2, until the Y position of your UITableView is just below the top of the screen (or the required position), in that case you no longer have to set the subtracted value as the Y position (otherwise the tableview would go off screen). Add a if condition that checks if the calculated values is lower than the required position, if it is then just set the Y position yourself (So the table is pinned at the top).
4 - Also make sure that you always scroll to the last cell of your UITableView using scrollToRowAtIndexPath.
Hope this helps.
An alternative way to solve this is by flipping UITableView’s Y axis
taken from: Igor Kulman
The best solution I found is to flip the UITableView’s Y axis. It gives you all the advantages of the previous solution, but you do not have to handle the scrollbar. It stays in the right place because only the content is flipped.
So flip the UITableView
tableView.transform = CGAffineTransform(scaleX: 1, y: -1)
and flip your cells in the same way
cell.contentView.transform = CGAffineTransform(scaleX: 1, y: -1)
I'm trying to zoom in and out an UIView, and rearrange it content to look similar for both states: zoomed and normal.
This picture shows the default state (the view that I'm going to zoom has orange color and has 5 UIImageViews) :
When I press "Zoom in" button I change orange view frame:
_page.frame = self.view.bounds;
And I'm getting the following result:
But the goal that I want to achieve is something similar to this (same result if I would scale the view):
It means that I must change frames for each subview, but it could be complicated when view would have many objects on it.
What I'm asking for are some hints or methods how can I get desired result without accessing subviews.
There are be hacks to do this, but the proper way would be to use auto layout. You don't have to access any subviews and will be able to do it in the storyboard/IB.
If you use auto layout, you can actually create constraints which will pin the following attributes of the subviews:
Pin the top subview's top space and leading space to the container
Pin the all but the last subviews' vertical distance to its nearest neighbour and leading space to container
Pin the last subview's top vertical space to its nearest neighbour and bottom space to container and leading space to container
Set constraints for height and width but set the priority to low
In addition to setting the frame (which just changes the size of the view) you want to change the transform (scale the view) Try something like:
_page.transform = CGAffineTransformMakeScale(2.0, 2.0)
You'll probably want to calculate the scale factor based on the old view size and the new size.
My app is built on a UIScrollview with a UIImageView subview and various other subviews. When I rotate to landscape, I change the contentSize of the scroll view and resize the image view proportionally to take advantage of the increased horizontal width. The means the height increases as well to maintain the proportions.
My question is, in the case of the blue subview shown, what do I need to do to reposition it such that it maintains it relative position after rotation, given that it's superview is no longer the same size? I have experimented with convertRect:toView: and converPoint:toView:, but I can't seem to get it quite right.
Are you using auto layout? If so, in many cases, the judicious use of constraints can keep that subview in the right place and right size, even as you go from landscape to portrait. But you'd have to share more details about what else is on this view for us to be more specific.
If not using auto layout, you generally can set the view's autosizing mask so it moves to the correct location for you. But in the case of a scroll view subview, you might have your view controller can respond to viewWillLayoutSubviews, updating the contentSize of the scroll view and the frame of the subview to move, accordingly:
- (void)viewWillLayoutSubviews
{
// update the contentSize of the scroll view for the width of the root view, but I'm assuming the
// height won't change
self.scrollView.contentSize = CGSizeMake(self.view.bounds.size.width, self.scrollView.contentSize.height);
// adjust the frame of the subview you want to move so that it is a certain offset from the bottom
// left corner of the scroll view's `contentSize` (in this case, 10 points from bottom, 10 points from right)
self.subviewToMove.frame = CGRectMake(self.scrollView.contentSize.width - self.subviewToMove.frame.size.width - 10,
self.scrollView.contentSize.height - self.subviewToMove.frame.size.height - 10,
self.subviewToMove.frame.size.width, self.subviewToMove.frame.size.height);
}
The specifics vary based upon details of (a) whether you're using autolayout or not; (b) whether you're creating this subview programmatically or not; and (c) what other content you have in your view and whether the change from portrait to landscape and back results in any change in the vertical height of the scroll view.
To reposition a view, you update its frame. The frame property is of type CGRect, which is a combination of size (CGSize) and origin (CGPoint). If size of your blue view doesn't change, then only origin should be updated.
iOS coordinate system starts from top left corner:
For your blue view you calculate it's origin from the bottom right corner, that is
origin = contentSize - blueViewSize - padding
Do this separately for x and y coordinate, make CGRect with updated origin, and update blue view's frame.
UP: This is how you do it manually, but you can (and better should) let UIKit reposition subviews for you automatically -- learn about autoresizing and autolayout in Xcode's Interface Builder, and Developer manuals