Resizing UIButton Frame While Using Size Classes Requires Auto Layout - uibutton

I have used storyboard to layout a custom cell in a tableview. I have a UI button in this custom cell that has an initial x,y size of 60x7. This UI button (as with all objects in the storyboard) use auto layout with size classes.
When the user clicks on an edit button in the view, I would like to change the size of the UIButton in each cell to be 60x60. Various StackOverflow solutions for changing the UIButton size do something like the following:
CGRect buttonFrame = cell.button1Left.frame;
buttonFrame.size = CGSizeMake(60, 60);
cell.button1Left.frame = buttonFrame;
But the solutions also warn that this will not work unless you turn off auto layout. However, when I try to turn off auto layout for this UIButton in the custom cell, I get the following warning:
This warning scares me. If I disable size classes, will this mess up my layout, disable my segues, and make future changes more difficult? If so, is there any other way to accomplish what I am trying?
Bonus question: is it possible to animate the resizing of the UIButton (i.e. so that it appears to stretch to the larger size)?

Try this:
1) add 2 constraints to your Button in storyboard;
2) create properties for them :
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *btnHeight;
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *btnWidth;
3) add action to button click:
- (IBAction)buttonPressed:(id)sender {
UIButton *btn = (UIButton *)sender;
btn.titleEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 0);
self.btnHeight.constant +=50;
self.btnWidth.constant +=50;
[UIView animateWithDuration: 0.7 animations:^{
[self.view layoutIfNeeded];
}];
}
P.S. If your button is in the center of cell, you need also create top and left constraints and if you make height and width for 50 bigger you need to make top and left for 25 smaller.

I decided that the best solution for me was to create another UIButton that was already the desired size. When the user presses an edit button for the view, I hide the collapsed UIButton that was 60x7. Then I unhide the full size UIButton that is 60x60. To animate the transition so that it looks more natural, I did the following:
[UIView transitionWithView:cell.pencilButtonLeft
duration:0.6
options:UIViewAnimationOptionTransitionFlipFromBottom
animations:NULL
completion:NULL];
cell.pencilButtonLeft.hidden = NO;
As for the warning message when I tried to turn off autosizing, I decided to not turn off autoresizing and not to disable size classes. In reading it closely, I might have been ok as long as I did not have an intention of running the app on a device other than an iPhone. Thanks to #Ptah for the suggestion on the animation.

Related

Autolayout - UIView animation from the bottom of the screen

I am using autolayout in my application. I have a UIPicker at the bottom of screen. What I want to do is I want to open UIPicker from the bottom of screen on click of UIButton as shown in image below
I want to know
which kind of constraint I have to set initially
which kind of constraint I have to implement programmatically and how it will be implemented?
How to get back to its original position?
Initially pin top of pickerView to bottom of SuperView and then when you want it to show you can pin bottom of pickerView to bottom of superView.
OR
You can do higher animation by pinning bottom of pickerView to bottom of superView and set height to 0 and when you want to show set height constant to whatEver height is recquired.
follow the below step.
applied this constraint on your object.
after that select vertical space constraint and create IBOutlet for it.
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *TopHeight;
set your desire top margin using below code.it will set new top margin for your object with animation.
self.TopHeight.constant = 400;
[self.view setNeedsUpdateConstraints];
[UIView animateWithDuration:0.5 animations:^{
[self.view layoutIfNeeded];
}];
What I have done is, I have set 3 constraint for pickerView as follows.
Then I set outlet of the bottom space to my view.
#property (strong, nonatomic) IBOutlet NSLayoutConstraint *bottomConstraint;
after then on click of botton I write following logic and my work is done.
- (IBAction)showPicker:(id) sender{
self.bottomConstraint.constant = 0;
[self.picker setNeedsUpdateConstraints];
[UIView animateWithDuration:0.3f animations:^{
[self.view layoutIfNeeded];
}];
}

UIVIew from XIB with Autolayout to UItableView Header

I am writing because I have a problem with the Auto Layout.
I'm trying to create a simple view in InterfaceBuilder with Auto Layout I want to load code and enter as a header of a table (not as header section). I explain briefly what are the characteristics.
The imageView must be square and must be as wide as the screen.
The space under the picture to the bottom of view that contains the button and label must be high 50 points.
Between image and button has to be a fixed distance of 12 points.
Between image and label must be a fixed distance of 13 points.
All these features are able to get them with Auto Layout. I added a constraint to the aspect ratio of the image (1: 1) and the various constraints for distances. all right.
The real problem is that by launching the app on iphone 6+ simulator (414 points of width), the image (with the label and button) goes above the cells.
Enabling various transparencies I noticed that the superView of Image View, only increase the width. It does not increase its height! How do I fix?
This is the code:
- (void)viewDidLoad{
//...
PhotoDetailsHeaderView *hView = (PhotoDetailsHeaderView *)[[[NSBundle mainBundle] loadNibNamed:#"PhotoDetailsHeaderView" owner:self options:nil] objectAtIndex:0];
hView.delegate = self;
self.tableView.tableHeaderView = hView;
//...
}
This is how I create the xib:
and this is how it is on the simulator, the green box is Uiimageview and the yellow box (under green box) is the mainview (or superview):
How can fix it?
Many thanks to all!
You'll need to add a property to store your PhotoDetailsHeaderView:
#property (nonatomic, strong) PhotoDetailsHeaderView *headerView;
Then calculate its expected frame in viewDidLayoutSubviews. If it needs updating, update its frame and re-set the tableHeaderView property. This last step will force the tableView to adapt to the header's updated frame.
- (void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
CGRect expectedFrame = CGRectMake(0.0,0.0,self.tableview.size.width,self.tableView.size.width + 50.0);
if (!CGRectEqualToRect(self.headerView.frame, expectedFrame)) {
self.headerView.frame = expectedFrame;
self.tableView.tableHeaderView = self.headerView;
}
}
The problem is probably that in iOS you have to reset the header of the table view manually (if it has changed its size). Try something along these lines:
CGRect newFrame = imageView.frame;
imageView.size.height = imageView.size.width;
imageView.frame = newFrame;
[self.tableView setTableHeaderView:imageView];
This code should be in -(void)viewDidLayoutSubviews method of your view controller.

Programmatically remove UILabel that has autolayout from View

I parse Json data and I set it on some UILabels, What I want is that when there's no text for a specific label It has to be removed from the UIView, I tried with 2 methods but with no results because the labels has constraints.
What I tried is:
Set their frame to 0 and the height constraint to 0
CGRect noFrame = _prepTime.frame;
noFrame.size.width = 0;
noFrame.size.height = 0;
[_prepTime setFrame:noFrame];
prepTimeHeight = 0;
But the height of the UILabel still remains,
The I tried with:
[_prepTime removeFromSuperView];
With this one the UILabel gets removed but the interface changes since it has constraints and by removing the UILabel I destroy the layout.
Is there any method to remove the UILabel from the view even if it has constraints?
You can set hidden if you don't want to affect all other subviews.
When using layout constraint it's not a good idea to edit the frame of your element. Instead you should add a IBOutlet property for your NSLayoutConstraint and link it to the height constraint of your label in your storyboard, then edit the constant value of the NSLayoutConstraint.
Someting like that in your viewcontroller #implementation:
#property IBoutlet NSLayoutConstraint *myLabelHeightConstraint;
and later when you want to hide your label :
self.myLabelHeightConstraint.constant = 0;
[self.view layoutIfNeeded];

Animation and UILabel change text

I have an UIImageView and an UILabel in a view of my storyboard. I created 2 corresponding IBOutlet and an NSTimer in the controller.
Each 0.01 seconds, the timer call the following method which moves the image:
-(void) update{
CGRect rect = myImageOutlet.frame;
rect.origin.x += 1;
myImageOutlet.frame = rect;
}
It works well. Now I would also like to change the text of the label in this method in order to display the current elapsed time (to do so I initialize an NSDate in the viewDidLoad and I use on it the method timeIntervalSinceNow)
Now the text of the label changes correctly but the image stays at it's original place.
I found a workaround by adding programmatically to my controller a subview and putting the label in this subview.
What is strange is that I tried to do the same by adding an UIView and an UILabel through the object library in the storyboard (and not programmatically), and it does not work.
Do you have any idea why ?
(and if you also know why the image is not moving if I change the label text I am interested)

UIView height before a table section

I'm trying to add a view with hight of 50 before table sections, i added the view in interface builder and resize it to 50 and everything looks good in interface builder but once i test it on a device or simulator the view show up with a maximum screen height and it doesn't seem that i can control its height whatever value i use the view takes all the screen hight
How can i force the view height to 50?
Try to use autolayout and set a height constant.
Uncheck "Autoresize Subview" attribute for the parent view in which these view added and check the output. This might solve the problem if some constraint tries to resize the view which was added.
If you want add and UIView before a table section, this view will be before the tableView also. And At least you do by code this view won't be scrolled.
You must change you TabelViewController to a ViewController and adding the tableView Protocols delegate. And no sure but you must have something like that:
#interface TestTableViewController : UITableViewController
And you should be:
#interface TestTableViewController : UIViewController <UITableViewDataSource,UITableViewDelegate>
Then: In Storyboard add the View and the tableview (Both should have in the same level). Add constrains, connect delegates, and create a IBOutlet for both:
#property (nonatomic,strong) IBOutlet UIView *superHeader;
#property (nonatomic, strong) IBOutlet UITableView *tableView;
With this two outlet if you want you can code to the superHeader disappear when you scrolling until a point, here an example (Remember tableView is a scrollView son).
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (scrollView.contentOffset.y > 100)
{
[UIView animateWithDuration:0.3 animations:^{
// Be carfuly if you are navigationBar (64 ptos) and depens of transparency property
self.tableView.frame = CGRectMake(0, -50, self.view.bounds.size.width, 50);
self.tableView.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
}];
} else if(scrollView.contentOffset.y < 80) {
[UIView animateWithDuration:0.3 animations:^{
// Be carfuly if you are navigationBar (64 ptos) and depens of transparency property
self.tableView.frame = CGRectMake(0, 0, self.view.bounds.size.width, 50);
self.tableView.frame = CGRectMake(0, 50, self.view.bounds.size.width, self.view.bounds.size.height - 50);
}];
}
}
How did you add the view to the UITableView in Interface Builder?
Do you want to have the view displayed before every section?
Then you can add it as a header view for each sections using
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section.
You can specify the height for it using
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
These are both UITableViewDelegate methods.
If you don't want it for every section but rather need one view that is displayed at the top of the TableView, then you can try the tableHeaderView property of UITableView.
You can set any UIView as the header using this property.
See this StackOverflow thread: Adding iOS UITableView HeaderView (not section header)
If you want 50 fixed height then add a constraint to the view "fixed height : 50"
The reason for unchanged frame is the auto layout. SetFrame will work fine when you disable the auto layout.
Hope this will help you
I feel you are not using the prototypecell of tableViewcontroller. Try to add the customisation into that. It may work.