Adding subview to tableview using autolayout - objective-c

I was trying to add a subview to tableview using autolayout, but I get this Assertion failure when I do so.
" * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Auto Layout still required after executing -layoutSubviews. UITableView's implementation of -layoutSubviews needs to call super.'"
My code
UIView *view = [[UIView alloc] init];
[view setBackgroundColor:[UIColor redColor]];
[parentView addSubview:view];
[view setTranslatesAutoresizingMaskIntoConstraints:NO];
NSLayoutConstraint *c1 = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:parentView attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0.0];
NSLayoutConstraint *c2 = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:parentView attribute:NSLayoutAttributeLeft multiplier:0.0 constant:10.0];
NSLayoutConstraint *c3 = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:parentView attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0.0];
NSLayoutConstraint *c4 = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:parentView attribute:NSLayoutAttributeTop multiplier:1.0 constant:50.0];
[parentView addConstraint:c1];
[parentView addConstraint:c3];
[parentView addConstraint:c2];
[parentView addConstraint:c1];
but if I set frame to the view without any autolayout constraint, it works fine.
I couldn't figure out what I am missing.

Related

Xcode version to 9, iOS11 and works fine except iPhone x. UI got collapsed

I have Created Two UIView one headerview and second is UICollectionView both subview of UIScrollView and I have hidden my NavigationBar entire app.
Now I have added below code for set "SafeAreaLayoutGuides" in iOS11 but here application crass due to superview nil found.
I have added below code.
UIView *parentView = self.view.superview;
UIView *childView = scrollViewMain.superview;
childView.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *topConstraint;
NSLayoutConstraint *bottomConstraint;
if (#available(iOS 11, *)) {
topConstraint = [NSLayoutConstraint constraintWithItem:childView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:parentView.safeAreaLayoutGuide attribute:NSLayoutAttributeTop multiplier:1.0 constant:0];
bottomConstraint = [NSLayoutConstraint constraintWithItem:childView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:parentView.safeAreaLayoutGuide attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0];
} else {
topConstraint = [NSLayoutConstraint constraintWithItem:childView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:parentView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0];
bottomConstraint = [NSLayoutConstraint constraintWithItem:childView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:parentView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0];
}
[parentView addConstraint:topConstraint];
[parentView addConstraint:bottomConstraint];
If parentView is nil (because self.view.superview is nil), then that means that self.view hasn't been added to the view hierarchy yet.
Make sure that whatever view contains this one has called self.addSubview(childView); that'll fix the "nil superview" issue.

UIImageView inside a scrollView with screen rotation

Its been 2 days working on this problem and i just can't figure it out.
I have a UIScrollView stretched in all my view and i am adding to it as subViews a random number of UIImageViews, and i am enabling paging so it will look like a gallery app.
My problem is when i rotate the screen, the images frames stays the same (this is probably because of the constraints) so i tried to give the images constraints and it worked they would rotate perfectly but then a problem appeared where the scroll view wont scroll anymore and the images are on top of each other ..
This is my code :
-(void)setupScrollView
{
for(int i = 0 ; i < [_arrayOfImages count] ; i++)
{
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(self.view.frame.size.width*i, 0, self.view.frame.size.width, self.view.frame.size.height)];
[imageView setImage:[[_arrayOfImages objectAtIndex:i] getImageForImageView:imageView]];
[imageView setUserInteractionEnabled:YES];
[imageView setContentMode:UIViewContentModeScaleAspectFit];
[imageView setTranslatesAutoresizingMaskIntoConstraints:NO];
[_scrollView addSubview:imageView];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.f constant:0.f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1.f constant:0.f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.f constant:0.f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.f constant:0.f]];
}
[_scrollView setContentSize:CGSizeMake(self.view.frame.size.width*[_arrayOfImages count], self.view.frame.size.height)];
}
Can anyone help me please ? thanks
You need to change the frame of UIScrollView and the UIImageViews in Autorotate delegate methods. After that you have to change the ContentSize of UIScrollView.
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientat‌​ion{}
//ios 7
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrient‌​ation{}
duration:(NSTimeInterval)duration -
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOri‌​entation{}
//ios 8
-(void)viewWillTransitionToSize:(CGSize)size
withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator{
if (size.width > size.height) {
// Positions for Landscape
} else {
// Positions for Portrait
}
}
I'am not really sure, because I need to see all application, but you can try following code
-(void)setupScrollView
{
for(int i = 0 ; i < [_arrayOfImages count] ; i++)
{
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(self.view.frame.size.width*i, 0, self.view.frame.size.width, self.view.frame.size.height)];
[imageView setImage:[[_arrayOfImages objectAtIndex:i] getImageForImageView:imageView]];
[imageView setUserInteractionEnabled:YES];
[imageView setContentMode:UIViewContentModeScaleAspectFit];
[imageView setTranslatesAutoresizingMaskIntoConstraints:NO];
[_scrollView addSubview:imageView];
[imageViewArray addObject:imageView]
if (i == 0) {
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.f constant:0.f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1.f constant:0.f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.f constant:0.f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.f constant:0.f]];
} else {
UIImageView * previousView = [imageViewArray objectAtIndex:i-1];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:previousView attribute:NSLayoutAttributeLeading multiplier:1.f constant:0.f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:previousView attribute:NSLayoutAttributeTrailing multiplier:1.f constant:0.f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:previousView attribute:NSLayoutAttributeTop multiplier:1.f constant:0.f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:previousView attribute:NSLayoutAttributeBottom multiplier:1.f constant:0.f]];
}
}
[_scrollView setContentSize:CGSizeMake(self.view.frame.size.width*[_arrayOfImages count], self.view.frame.size.height)];
}
Also, you need to declare imageViewArray as NSMutableArray:
add to #interface:
NSMutableArray * imageViewArray;
and in viewDidLoad:
imageViewArray = [[NSMutableArray alloc] init];

How to add UIView and cover entire screen

I am trying to add a gray uiview overlay using autolayouts so that when you rotate the device it automatically still covers the entire screen. How would this be done programatically?
It is easy, you need 4 constraints to do that - top, bottom, left and right:
NSLayoutConstraint *topConstraint = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeTop multiplier:1.0f constant:0.0f];
NSLayoutConstraint *bottomConstraint = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeBottom multiplier:1.0f constant:0.0f];
NSLayoutConstraint *leftConstraint = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeLeft multiplier:1.0f constant:0.0f];
NSLayoutConstraint *rightConstraint = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeRight multiplier:1.0f constant:0.0f];
Try this:
UIView *greyView = [UIView new];
[self.view addSubview:greyView];
greyView.translatesAutoresizingMaskIntoConstraints = NO;
NSDictionary *viewDictionary = #{#“greyView”:greyView};
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-0-[myView]-0-|“ options:0 metrics:nil views:viewDictionary]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#“H:|-0-[myView0]-0-|” options:0 metrics:nil views:viewDictionary]];

How to align UIImageView to the centre of the view controller?

I want an imageview to appear centre at the bottom,i added the imageview to another imageview in the view controller.the result is imageview is appearing at the bottom but not exactly at centre, can any one suggest what is wrong in my code?
-(void)viewWillAppear:(BOOL)animated
{
UIImageView *imgView=[[UIImageView alloc]init];
[imgView setTranslatesAutoresizingMaskIntoConstraints:NO];
UIImageView *mspimgvw=[[UIImageView alloc]init];
[mspimgvw setTranslatesAutoresizingMaskIntoConstraints:NO];
mspimgvw.image=[UIImage imageNamed:#"msplogo.jpg"];
[self.imgView addSubview:mspimgvw];
[self.view addSubview:imgView];
CGFloat bottom=0;
[imgView addConstraint:[NSLayoutConstraint constraintWithItem:mspimgvw attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:imgView attribute:NSLayoutAttributeBottom multiplier:1 constant:bottom-40]];
[imgView addConstraint:[NSLayoutConstraint constraintWithItem:mspimgvw attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:imgView attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:bottom-40]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[imgView]|" options:0 metrics: 0 views:dicViews]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[imgView]|" options:0 metrics: 0 views:dicViews]];
}
I want image to appear to the centre of the view controller.What to change in my code?
Here you go:
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1.f
constant:0.f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeBottom
multiplier:1.f
constant:0.f]];

Positioning UIView in UIViewController using NSLayoutConstraints causes aliased UILabel?

I'm trying to manually animate in a UIView, contained in a UIViewController, from the top of the screen. This view will have a height of 150px.
I setup layout constraints for when it's "collapsed" and when it's "expanded" (shown). I animate between the two constraints when I want to hide/show, respectively.
I setup the view contained in this UIViewController in IB with a simple UILabel in the upper-left of the view.
CGFloat closeUpViewHeight = 150.f;
self.closeUpViewController = [[[CloseUpViewController_Phone alloc] initWithNibName:#"CloseUpViewController_Phone"
bundle:nil]
autorelease];
[self addChildViewController:self.closeUpViewController];
[self.view addSubview:self.closeUpViewController.view];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.closeUpViewController.view
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeHeight
multiplier:0.f
constant:closeUpViewHeight]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.closeUpViewController.view
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeWidth
multiplier:1.f
constant:0.f]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.closeUpViewController.view
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1.f
constant:0.f]];
self.expandedCloseUpViewConstraint = [NSLayoutConstraint constraintWithItem:self.closeUpViewController.view
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeTop
multiplier:0.f
constant:0.f];
self.collapsedCloseUpViewConstraint = [NSLayoutConstraint constraintWithItem:self.closeUpViewController.view
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeTop
multiplier:1.f
constant:-1.f];
Anyone know why the resulting UILabel has aliasing problems?
Fixed my problem, pretty dumb mistake.
Inside the setup for my view controller, I added a drop shadow to the UIView and accidentally had carried over this:
self.view.layer.masksToBounds = NO;
self.view.layer.shadowOffset = CGSizeMake(0, 2);
self.view.layer.shadowRadius = 3;
self.view.layer.shadowOpacity = 0.8;
self.view.layer.shouldRasterize = YES; //<--- Don't rasterize.
Removing the shouldRasterize line fixes the issue here.