Changing size of UIButton while using Autolayout? - ios

I'm pretty new to ios. I'm working on a project which is going to frequently use a certain UIView class throughout the application. This class is simply an image that does some transparency stuff with the background color. This works fine so far. This class sometimes exists as a lone UIView, and sometimes as a button subview.
When I add this UIView to a UIButton as a subview, the full contents of the UIView are displayed at full size, but the clickable area of the button remains the size defined in the xib unless Use Autolayout is turned off (even if I manually try to set the button's frame.)
I would like to put a UIButton on the xib as a placeholder, and then later define its size/clickable area based on the size of the overlay image which the UIView that was initialized with.
Should this be possible, or am I misinterpreting the usage of xib files/autolayout?
under ViewDidLoad I have...
- (void)viewDidLoad{
[theButton addSubview:_theView];
CGRect buttonFrame = theButton.frame;
buttonFrame.size = CGSizeMake(_theView.getSize.width,_theView.getSize.height);
[theButton setFrame:buttonFrame];
}
However, the frame stays the same size when I print the button info before and after I try calling setFrame.
(note that '_theView.getSize' was added by me)

Under Autolayout, views don't have frames at viewDidLoad. Try your code in viewWillAppear: or viewDidLayoutSubviews.
Under Autolayout, you don't set frames. You edit constraints instead. Setting a frame will work until the next layout pass, when your layout will revert to that described by your constraints.
To size a button to fit a subview, you can try something like this (in visual format language): |-[theView]-| but it would depend what constraints are in place from your xib.

Related

Resize UIImageView with autolayout

I've got a view with a UIButton in it. I've got some animations that, among others, scale the button down.
The problem is that the button is actually scaling well following the constraints when it only has text, but when I set an image either as its image or its backgroundImage, the button is not scaling anymore.
I've tried playing with contentModes of both the UIButton and its inner imageView with no results (I've tried, literally, all the possible answers of this, this, this and this stackoverflow questions).
Any hint? Thank you all in advance
UPDATE
I've noticed that the issue is with UIImageViews, not UIButtons (the problem with the button was due to the imageView inside it).
I think your UIButton does resize, but the ImageView inside does not. The ImageView of the UIButton is always displaying normal image size.
The only possibility I found is to put another UIImageView below the Button with constraints top/bottom/left/right to the Button. This one can be perfectly adjusted.
I use subclassed buttons for that with their own ImageView inside. There you need to be careful to put userInteractionEnabled = false on the ImageView.
Finally I've got it.
In both cases (UIButton and UIImageView), you have to adjust Content Compression Resistance Priority to let the view to scale down. In my case, setting it to 749 was enough.

Autolayout causing UI Elements to "snap" into place at runtime?

I have a UIView with a UIImageView at the very top, a UILabel below it, a UIButton below that, and a UISegmentedControl that determines what determines what embedded UIview to display at the bottom (which also a choice to not show any at all).
I've run into the problem where I've set up all of my constraints in the interface builder, and everything seems to be fine when I switch between screen sizes in the storyboard. However when I actually run the project on a device or emulated, the UIimage at the top is briefly stretched before "snapping" into a size the fits the constraints. Also, it seems as if the label disappears for a brief second and reappears after the image has snapped into a size. After the "snap" has occurred, everything is in place and there are no problems.
This snapping occurs both when testing on a 4 and 3.5 inch display. I find this odd because I've designed the UI for the 4inch screen perfectly.
Does anyone know why this is happening?
Edit
Here's whats the constraints look like in IB.
This is potentially due to adjustments that you might be making to your UI elements (or constraints) from the view controller in code. For example, if you are programmatically setting a different UIImage into your UIImageView, and this code is happening too late in the view lifecycle (for example, in viewDidAppear) after a layout pass has already calculated view positions and sizes, then you will see a visible snap as views take on new positions based on the new intrinsic content size of the image view.
This could be caused by other adjustments such as injecting a localized string into a UILabel in code, which causes the label to have a smaller or larger intrinsic content size, which in turn affects the layout based on your constraints.
If you are making adjustments to your UI in code, make sure they are happening in viewDidLoad or viewWillAppear: so that they occur before the view's initial layout pass (and the view's animation onscreen).
If you're still seeing issues, you can try explicitly forcing an immediate layout pass to occur on the view controller's view at the end of viewWillAppear: by doing the following:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.view setNeedsLayout];
[self.view layoutIfNeeded]; // forces an immediate layout pass
}
Spacing between the UIElements might be the problem . Specially when using Pickers
Got it, You have applied constraint for Picker to adjust along with segmented control. So when app runs on 4 inch screen , picker automatically fits properly, but for 3.5 Inch picker always starts from bottom of the screen and picker will push segmented control upwards and hence segmented control will push rest control automatically.
Remove picker and segmented control constraint.

The frame of uitableview is not changing programmatically

I have 2 UITableView in my UIViewController. one of them is in the right side of the screen till center of screen. The other is from center till left bound.
User can hide the right UITableview by pressing one a button on the navigation bar.
I use this code to make left UITableview full screen:
self.rightTableView.hidden= YES;
self.leftTable.frame= CGRectMake(0,
self.dataTableView.frame.origin.y,
self.view.frame.size.width,
self.dataTableView.frame.size.height);
But it is not working.
I even put this code on the viewdidload and viewDidAppear methods but the frame not changing.
Try self.leftTable.translatesAutoresizingMaskIntoConstraints = YES, then call to frame resize at runtime is automatically translated into new constraints.
But, translatesAutoresizingMaskIntoConstraints will also cause new constraints to be added based on the view's autoresizingMask. So make sure other constraints are working properly.
When using autolayout, modifying the frame will have no effect.
Instead, you should modify the constraints.
You can do this by creating outlets for your constraints and connecting then in the interface builder.

How does sizeToFit determine appropriate size?

I have an app where the user can add what I call palettes at will. Items (UIViews) can be dragged from one palette to another. I thought I could use the sizeToFit method to automatically resize the palettes when items were added ore removed, but no resizing seems to be happening.
The documentation states that the method resizes to the most appropriate size to fit the subviews. Does that not include UIViews that I add programmatically?
I'd really not have to write my own sizeToFit method if I can get the built-in one to work for me. But it seems to be doing nothing. Here's the code I've tried:
CGPoint oldCenter = self.pieceBeingMoved.center;
CGPoint newCenter = [self.pieceBeingMoved.superview convertPoint:oldCenter toView:destinationView];
[destinationView addSubview:self.pieceBeingMoved];
self.pieceBeingMoved.center = newCenter;
if (destinationView.tag == 20000) {
NSLog(#"DestinationView is a palette, so resize it from %#",NSStringFromCGRect(destinationView.frame));
[destinationView sizeToFit];
NSLog(#"DestinationView resized to %#",NSStringFromCGRect(destinationView.frame));
}
The size is identical before and after the subview is added. The subview being added is the only subview at the time I ran this test, and the size of the subview is about 5% the size of the palette it is being moved to. So why isn't the view being resized? Do I need to do it myself?
The sizeToFit method just calls sizeThatFits: and then resizes the view accordingly. The default implementation of the UIView class returns the current size so you don’t see any effect. You will have to write your own sizeThatFits: method to do your calculation.
Here's an idea. Don't call sizeToFit. Just set the frame to the frame you actually want.

Adjusting UIButton's imageView properties

I'm having trouble figuring out how much I can adjust the imageView property of a UIButton. In the docs, it says:
Although this property is read-only, its own properties are read/write. Use these properties to configure the appearance and behavior of the button’s view.
I'm hoping to perform a transition where I shrink the size of the button in an animation, and I'd like the button's image to also shrink accordingly. However, I find that I have no control over the size of that image. If I modify either the frame or the bounds of UIButton's imageView property, nothing seems to happen. The image seems to want to retain it's standard dimensions. Changing autolayout properties on the imageView or contentMode properties on the button don't seem to help either.
In fact, the only thing that seems to work at all is to use UIEdgeInsetsMake to "squish" the image from all sides, but that isn't animatable.
I'd prefer not to use the backgroundImage property either, since I'm already using that to style the button in the first place.
You could add an own UIImageView as subview to the UIButton instead of using the "embedded" imageView.
You can set the frame of "your" image view as usually relative to the surrounding UIButton. You will have full control on it's position and you will also be able to animate it.

Resources