ios autolayout does not change button frame position - ios

I have one view, and I set this view on autolayout. When I change the button frame/position in 4s iphone, I am not able to change it. How to change the button position in ios 4s
note without changing the autolayout property ?
Here is my code :
CGRect screenBounds = [[UIScreen mainScreen] bounds];
if (screenBounds.size.height == 568)
{
// NSLog(#"Our App is running in iPhone5");
}
else
{
//NSLog(#"Our App is running in iPhone 3GS, 4, 4S");
[btn_next setFrame:CGRectMake(12,100,120,45) ];
[getTime setFrame:CGRectMake(151,361,89,162) ];
[picker_AMPM setFrame:CGRectMake(245,304,55,162)];
[img_blowline setFrame: CGRectMake(0,418,320,6)];
}

You can do it by :
Set translatesAutoresizingMaskIntoConstraints = YES, then calls to setFrame: at runtime are automatically translated into new constraints.
translatesAutoresizingMaskIntoConstraints will also cause new constraints to be added based on the view's autoresizingMask.
More details are in the section "Adopting Auto Layout" in Cocoa Auto Layout Guide.

This is because you need to change the constraints of the button, not it's frame. To do this you need to make an outlet for your constraint and change it in code and changing the constant property of the constraint. The code would be something like this:
self.myConstraintX.constant=newX;
self.myConstraintY.constant=newY;
[self.view layoutSubviews];
[self.containerView layoutSubviews];
One important thing to note is to make sure this code is not repeated.

Related

UITableView frame size strange behaviour

I try to set frame size to my table view programmatically after viewDidLoad:
[_tableView setFrame:CGRectMake(0, topHeight,
[[UIScreen mainScreen] bounds].size.width,
[[UIScreen mainScreen] bounds].size.height - topHeight)];
Default size is 200x200 with origin Y 100:
Scene hierarchy:
Implementation of UITableView shows when setFrame was called:
#implementation MainTableView
- (void)setFrame:(CGRect)frame {
NSLog(#"setFrame: %f %f", frame.size.width, frame.size.height);
[super setFrame:frame];
}
#end
All is fine but table's frame resizes to default when I press any cell without printing log messages from setFrame. Small explanation video: http://youtu.be/JUW_rHvCS2I
I don't understand why my table size becomes default (200x200) after cell click. Even if I try to set size inside viewWillAppear (after return from cell detail view) it doesn't work.
Any ideas?
I can't really tell why your tableView isn't resizing properly since you haven't provided much code to look around. Though I recommend setting some constraints or resizing rules for the tableView, probably something like this:
http://i.imgur.com/N9fvvIB.png (if not using Auto Layout)
http://i.imgur.com/3Uz8e5e.png (if using Auto Layout)
Now if you really need to make this work only trough code I suggest throwing up some NSLog's containing the tableView's frame width and height before and after setting it up.
Try _tableView.translatesAutoresizingMaskIntoConstraints = NO.

Positioning views dependent on device height in iOS

I'm switching to autolayout and I'd like to position views relatively to height of device. How should I setup constraints to satisfy such condition.
I have nice layout for iPhone 5 but for iPhone 6Plus I'd like to move "red" to position of "gray":
All my current constrains:
One idea might be to place the username, password and login items on a uiView with a clearBackground and then create a constraint for that view and its superview and create an outlet to it. You could then detect which phone you are using in code and modify the constraints programatically in willLayoutSubviews.
if ((int)[[UIScreen mainScreen] bounds].size.height == 736)
{
// This is iPhone 6+ screen
myConstraint.constant = 150;
} else if ((int)[[UIScreen mainScreen] bounds].size.height == 568) {
// This is iPhone 5s screen
frameRateLabelHeightConstraint.constant = 100;
}
There will be a better way to do this in Autolayout no doubt but I do find it a bit confusing so I have used this method in the past.
Here is a sample project uploaded # One Drive. Here are the sample outputs on various versions of iPhone Simulators...
As I see you want to put your form to the center of view. So I think the best solution will be to put your form elements on another transparent view and add to this view centerX aligment constraint and centerY aligment constraint.
you can check another way here

How can a get the auto layout size of the UICollectionViewCells in iOS 8? (systemLayoutSizeFittingSize returns size with zero height in iOS 8)

Since iOS 8 [UIColletionViewCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize] returns a size with height of 0.
Here's what the code does:
To determine the size for cell in a UICollectionView in iOS 7 I use systemLayoutSizeFittingSize: on a cell defined in a xib file using auto layout. The size depends on the font size of an UILabel being a subview of the UICollectionViewCell in my xib file. The label's font is set to UIFontTextStyleBody. So basically the cell's size depends on the font size setting made in iOS 7.
Here is the code itself:
+ (CGSize)cellSize {
UINib *nib = [UINib nibWithNibName:NSStringFromClass([MyCollectionViewCell class]) bundle:nil];
// Assumption: The XIB file only contains a single root UIView.
UIView *rootView = [[nib instantiateWithOwner:nil options:nil] lastObject];
if ([rootView isKindOfClass:[MyCollectionViewCell class]]) {
MyCollectionViewCell *sampleCell = (MyCollectionViewCell*)rootView;
sampleCell.label.text = #"foo"; // sample text without bar
[sampleCell setNeedsLayout];
[sampleCell layoutIfNeeded];
return [sampleCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
}
return CGSizeZero;
}
It works perfectly fine in iOS 7 but not in iOS 8. Unfortunately I have no clue why.
How can I get the auto layout size of the UICollectionViewCells in iOS 8?
PS: Using
return [sampleCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
instead of
return [sampleCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
as somebody might suggest, doesn't make any difference.
What you need to do is wrap all of your content in a container view, then call:
return [sampleCell.containerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
Your cell should look like this: cell -> containerView -> sub views
This works on both ios7 & ios8.
Supposedly on ios8, all you have to do is set the estimateSize & cell will automatically auto size on its own. Apparently that's not working as of beta 6.
Looks like this officially a bug: I filed a report that was closed as a duplicate of this one
Will report back when Beta 6 is out.
[Update: working properly in the GM seed of iOS 8, and the bug has been closed by Apple.]
We're using a work-around for now, copied below. Hopefully, these issues will be resolved before iOS 8 release and we can remove this. (The kludge assumes knowledge of Apple's implicit contentView behavior, and we have to hack IB outlet references to any constraints we transfer.)
We notice they're also removing all autoresizingMasks from storyboards/NIBs during upgrade, which makes sense given it's supposed to be auto-layout, but collection views still throwback to springs & struts. Perhaps this has been overlooked in the purge?
--Dan
/**
Kludge around cell sizing issues for iOS 8 and deployment to iOS 7 when compiled for 8. Call this on the collection view cell before it is used, such as in awakeFromNib. Because this manipulates top-level constraints, any references to such initial constraints, such as from IB outlets, will be invalidated.
Issue 1: As of iOS 8 Beta 5, systemLayoutSizeFittingSize returns height 0 for a UICollectionViewCell. In IB, cells have an implicit contentView, below which views placed in IB as subviews of the cell are actually placed. However, constraints set between these subviews and its superview are placed on the cell, rather than the contentView (which is their actual superview). This should be OK, as a constraint among items may be placed on any common ancestor of those items, but this is not playing nice with systemLayoutSizeFittingSize. Transferring those constraints to be on the contentView seems to fix the issue.
Issue 2: In iOS 7, prior to compiling against iOS 8, the resizing mask of the content view was being set by iOS to width+height. When running on iOS 7 compiled against iOS 8 Beta 5, the resizing mask is None, resulting in constraints effecting springs for the right/bottom margins. Though this starts out the contentView the same size as the cell, changing the cell size, as we do in the revealing list, is not tracked by changing it's content view. Restore the previous behavior.
Moving to dynamic cell sizing in iOS 8 may circumvent this issue, but that remedy isn't available in iOS 7.
*/
+ (void)kludgeAroundIOS8CollectionViewCellSizingIssues:(UICollectionViewCell *)cell {
// transfer constraints involving descendants on cell to contentView
UIView *contentView = cell.contentView;
NSArray *cellConstraints = [cell constraints];
for (NSLayoutConstraint *cellConstraint in cellConstraints) {
if (cellConstraint.firstItem == cell && cellConstraint.secondItem) {
NSLayoutConstraint *parallelConstraint = [NSLayoutConstraint constraintWithItem:contentView attribute:cellConstraint.firstAttribute relatedBy:cellConstraint.relation toItem:cellConstraint.secondItem attribute:cellConstraint.secondAttribute multiplier:cellConstraint.multiplier constant:cellConstraint.constant];
parallelConstraint.priority = cellConstraint.priority;
[cell removeConstraint:cellConstraint];
[contentView addConstraint:parallelConstraint];
} else if (cellConstraint.secondItem == cell && cellConstraint.firstItem) {
NSLayoutConstraint *parallelConstraint = [NSLayoutConstraint constraintWithItem:cellConstraint.firstItem attribute:cellConstraint.firstAttribute relatedBy:cellConstraint.relation toItem:contentView attribute:cellConstraint.secondAttribute multiplier:cellConstraint.multiplier constant:cellConstraint.constant];
parallelConstraint.priority = cellConstraint.priority;
[cell removeConstraint:cellConstraint];
[contentView addConstraint:parallelConstraint];
}
}
// restore auto-resizing mask to iOS 7 behavior
contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
}
This is a bug in xCode6 and iOS 8 SDK running on iOS7 devices :)
It almost waisted my day. Finally it worked with the below code in the UICollectionViewCell sub class. I hope this will be fixed with the next version
- (void)setBounds:(CGRect)bounds {
[super setBounds:bounds];
self.contentView.frame = bounds;
}
I had the same issue for UITableViewCells and iOS 7 (ios8 works perfectly), but "Triet Luong" solution worked for me:
return [sampleCell.containerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
This is not a bug, I have been grappling with this issue now for some time and have tried different things, I am giving below the steps that's worked for me:
1) use contentView [sampleCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
2) you can create your own contentView and have the subViews added to the contentView, don't forget to pin the top, bottom and left and right of the contentView if you are using a custom contentView to the superView, if you don't do this then height will be 0, here also depending upon your requirements you can for. e.g not pin the bottom of the contentView to the superView so that the height of the view can vary, but pinning is important and pinning which one depends on your requirements.
3) set the constraints properly in interface builder depending upon your requirements, there are certain constraints that cannot be added in interface builder, but then you can add them in viewDidLoad of the viewController.
So my 2 cents input is that constraints have to be set properly in the interface builder for systemLayoutSizeFittingSize:UILayoutFittingCompressedSize to return correct dimensions, this is the solution guys.
maybe you have some wrong constrain, you should specify both virtical top space and bottom space between your UIView and contentView, i also had this issue before, that is because i just specified the virtical top space, and didn't specfied the virtical bottom space to contentView
It was a bug in iOS 8 beta versions. Finally it is fixed with for iOS 8 GB (Build 12A365). So for me now it works with the same code I wrote for iOS 7. (see the question)

Resizing a UIImageView programmatically

I have tried several different solutions to this problem with no success.
I have a UIImageView (created on the Storyboard) that has multiple Gesture Recognizers on it. I have trying to resize this UIImageView based on screen size to take advantage of the 4 inch display.
It appears that since the Imageview was built using the storyboard, I can't change it programmatically???
My current code looks like this:
//determine screen size, set scoring button width based on device size.
CGFloat lCurrentHeight = self.view.bounds.size.height;
if (lCurrentHeight == 568.0) {
CGRect _redHeadImageFrame = _redHeadImage.frame;
_redHeadImageFrame.size.width = 220;
[_redHeadImage setFrame:_redHeadImageFrame];
}
Any ideas??? Thanks.
If you are using autolayout you have to change withConstraint of the image, because manual changing of the frame will not work in this case.
EDIT
You can create IBOutlet for the width constraint as you do it for other controls - just select constraint in IB and move it with right button to your header file. Than in code change constraint:
[self.imageWidthConstraint setConstant:100.0];
yes you need to use like this,
CGFloat lCurrentHeight = [[UIScreen mainScreen] bounds].size.height; //it will give 568
CGFloat lCurrentHeight = self.view.bounds.size.height;//it will give 548,in your case that condition failed.
There's no difference in resizing UIViews created by code or by the storyboard. It's exactly the same: setting the frame of the view, as you are doing.
What might be happening:
Your if condition it's never true. Have you checked with a breakpoint if the code inside it is even called? Maybe there's some error in the float direct comparation. See this.
Also, see this for a better understanding on how to check if it's 4 inch display.
If the setFrame: code is actually called, check if you are using auto-layout in your view. Maybe there's a constraint in the UIImageView. In this case, you should play with this constraint, in order to resize the view correctly..

Autolayout UIImageView with programatic re-size not following constraints

Sorry for the bother but I'm trying to lazy load several imageViews and then resize it proportionately to the content in a UITableView. I'm also trying (Unwisely perhaps?) to use Autolayout basically for the first time. And I'm not understanding why the constraints aren't working in this case. Here's the code that I'm using to resize the UIImageView after I've loaded the proper image into it.
// Scale the image view and return it.
- (UIImageView *) scaleImageViewForScreenWidth:(UIImageView *)imageView {
UIImage *imgFromView = [imageView image];
CGRect newFrame = CGRectMake(0, 0, imgFromView.size.width, imgFromView.size.height);
float imgFactor = newFrame.size.height / newFrame.size.width;
newFrame.size.width = [[UIScreen mainScreen] bounds].size.width;
newFrame.size.height = newFrame.size.width * imgFactor;
[imageView setFrame:newFrame];
return imageView;
}
As far as constraints are concerned. I'm trying to attach a Label and UIImageView with a shadow to the bottom of the main imageview. Here are the constraints that I'm applying to a bottom shadow in the imageview. The bottom shadow constraints are:
Height Equals: 83
Align Bottom to: Background Image View
LeadingSpace to: Table View Cell
I'm not getting what I want though. Any ideas? I feel like I'm fighting autolayout.
As requested! Here's some guidelines for using Autolayout that should help a lot.
The first thing is that the ideal approach is for you to set things up in Interface Builder so that no further programming is required. So, if - for example - the bounds of your view change, then your view will adjust itself automatically as required.
If that doesn't do the business, then you may have to update the constraints programmatically. Now, the golden rules as I mentioned is that you update the constraints. Resist the temptation to update the underlying UIView frame!
So, you'll do something like:
_myWidthConstraint.constant = 300.f;
The next thing to note is that you should do this in a specific place, and that is in your UIView subclass method updateConstraints:
- (void)updateConstraints
{
[super updateConstraints];
_myWidthConstraint.constant = 300.f;
}
How do you trigger that? By invoking:
[self setNeedsUpdateConstraints];
Hope this helps! For further info check Ole Begemann's excellent article 10 Things You Need To Know About Cocoa Autolayout.
Don't forget the WWDC videos. These are essential!
Also, now there's a book iOS Auto Layout Demystified . Although I've bought it, I haven't had a chance to read it yet. It does look pretty good though.
I was also facing the same issue. the image inside the imageview was too big for the imageview and the contentMode was set to AspectFill.
I solved this by unchecking 'Autoresize Subviews".

Resources