Object frames scale at runtime, but retain constant values, making placing items programmatically difficult/inaccurate
I'm building an iPhone app for devices running iOS 8 and above, so the app has to be compatible with all iPhones since the 4S.
First, in the storyboard file, I created a view that is the same size as the 4S screen. On that view, I added a grid of 3 rows of 4 rectangles each. I added Autolayout constraints, and everything is playing nicely for the time being. There are no errors or warnings related to misplaced views or conflicting constraints, etc. The rectangles are scaling nicely on all the iPhone simulators.
My problem comes when I try to create and place a button programmatically. The squares in my grid are placeholders where these buttons need to be placed. So, when I create a new button and set it's frame, I'm setting it equal to the frame of one of the rectangles on my grid. When I run the app on the 4S simulator, it works fine, but on every other simulator (with a larger screen), the button is not appearing in the proper place.
What appears to be happening is that each of the rectangles has a set X and Y value in the storyboard editor, and when the app runs in any of the simulators, the X and Y values are remaining constant, even though the view itself is scaling.
To put it more clearly, let's say that slot #2 has an x value of 150 and a y value of 200. Whenever I try to place the button in slot #2 by setting the button's frame equal to slot #2's frame and then run the app, the button's X and Y values are ALWAYS being set to 150 and 200 respectively, instead of being scaled to compensate for the change in size of the device screen. Slot #2 itself is scaling properly, but the button set to Scale #2's frame is being placed at 150/200 regardless.
Has anybody ever experienced this, and if so, do you know how I would get the button's frame to scale with the other elements on the screen?
Let me know if I haven't been clear. Perhaps I can post some pictures to illustrate what I'm getting at.
Edit: Adding some images:
This is on the 6+ Simulator. As you can see, the card appears basically exactly where it would if I were running it on the 4S simulator. When I created it, though, I set it's frame equal to the frame of the second square on the grid.
You need to use auto layout to position / size things, so that they will have the same relative arrangement no matter how big the screen is. "Set the frame" is the opposite of auto layout. Don't set any frames; use auto layout throughout.
Alternatively you can use frames, but then timing becomes crucial. You need to wait until after viewDidLayoutSubviews, because only then does the grid have the size it will actually have when it appears. If you do set a card's frame too early (e.g. in viewDidLoad), you will be using the nib grid size, not the runtime grid size.
You should not set the frame instead of it use the auto layout constraint. Create the place card button and addsubview it on any Rectangles button/view then add constraints programmatically. Try the KVConstraintExtensionsMaster library.
By Using KVConstraintExtensionsMaster library, put the below code from where you want to place new card upon Ractangle Buttons either UIButton *placeCardButton = [UIButton prepareNewViewForAutoLayout]; [placeCardButton setBackgroundColor:[UIColor redColor]]; [self.secondRactangleButton prepareViewForAutoLayout]; // here self.secondRactangleButton is IBOutlet reference. [self.secondRactangleButton addSubview:placeCardButton]; // now adding all required constraints on the button [placeCardButton applyConstraintFitToSuperview]; Or Direct Without using library UIButton * placeCardButton = [UIButton new]; [placeCardButton setTranslatesAutoresizingMaskIntoConstraints:NO]; [placeCardButton setBackgroundColor:[UIColor redColor]]; [self.secondRactangleButton addSubview:placeCardButton]; [self.secondRactangleButton addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[placeCardButton]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(placeCardButton)]]; [self.secondRactangleButton addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[placeCardButton]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(placeCardButton)]];