View disappears when I set `translatesAutoresizingMaskIntoConstraints` to `NO` - ios

I don't know if this is a bug or I'm doing something wrong:
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIWindow *window = [self window];
UIViewController *main = [[UIViewController alloc] init];
UIViewController *vc1 = [[UIViewController alloc] init];
UIViewController *vc2 = [[UIViewController alloc] init];
[main addChildViewController:vc1];
[main addChildViewController:vc2];
UIView *mainView = [main view];
UIView *v1 = [vc1 view];
UIView *v2 = [vc2 view];
[v1 setBackgroundColor:[UIColor redColor]];
[v2 setBackgroundColor:[UIColor blueColor]];
[v1 setTranslatesAutoresizingMaskIntoConstraints:NO];
[v2 setTranslatesAutoresizingMaskIntoConstraints:NO];
[v1 setClipsToBounds:YES];
[v2 setClipsToBounds:YES];
[mainView setBackgroundColor:[UIColor yellowColor]];
[mainView addSubview:v1];
[mainView addSubview:v2];
NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:v1
attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual
toItem:mainView attribute:NSLayoutAttributeTop multiplier:1.0
constant:0.0];
[mainView addConstraint:constraint];
constraint = [NSLayoutConstraint constraintWithItem:v1
attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual
toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0
constant:240.0];
[mainView addConstraint:constraint];
constraint = [NSLayoutConstraint constraintWithItem:v2
attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual
toItem:v1 attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0];
[mainView addConstraint:constraint];
[window setRootViewController:main];
[window setBackgroundColor:[UIColor greenColor]];
[window makeKeyAndVisible];
[main release];
[vc1 release];
[vc2 release];
return YES;
}
v1 and v2 appears nowhere when I launch the app.
If I comment out:
[v1 setTranslatesAutoresizingMaskIntoConstraints:NO];
[v2 setTranslatesAutoresizingMaskIntoConstraints:NO];
Cocoa wouldn't be able to satisfy my constraints because of the autoresizing mask that was translated into constraints.

You don't have any horizontal constraints and the height constraint for v2 is missing. Using the visual format language you need something like |-[v1]-|, |-[v2]-| and V:[v2]-|
NSArray *constraints;
constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"|-[v1]-|" options:0 metrics:nil views:#{#"v1": v1}];
[mainView addConstraints:constraints];

Related

Change Frame of Subview in Superview

I have a ViewController that adds an UIView, SpeciesImageView as a subview in viewDidLoad and set constraints in viewWillLayoutSubviews.
SpeciesImageView does not have a nib file. When we create speciesImageView in viewDidLoad, it calls initWithFrame in SpeciesImageView class.
This works fine (in both landscape and portrait) until the phone rotates. I tried setting the constraints as speciesImageView.frame.size.width, but that doesn't work because initWithFrame isn't called when the orientation changes, so the height/width of the speciesImageView remains unchanged.
On the other hand, using screenRect doesn't change the actual size of the UIView, it changes its size within the superview. So in other words, I haven't found a way to change the size of the actual speciesImageView on orientation change.
And for reasons lost to me, it gets completely messed up when you rotate it back to the original position.
- (void)viewDidLoad
{
self.tabBarController.tabBar.hidden=YES;
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
self.navigationController.navigationBar.hidden = NO;
//self.navigationController.navigationBar.translucent = YES;
UIImage *plantinfo;
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
plantinfo = [UIImage imageNamed:#"plantinfo_frame.png"];
} else {
plantinfo = [UIImage imageNamed:#"plantinfo.png"];
}
UIBarButtonItem *tempButton = [[UIBarButtonItem alloc] initWithImage:plantinfo
style:UIBarButtonItemStylePlain
target:self
action:#selector(toggleText:)];
self.navigationItem.rightBarButtonItem = tempButton;
[tempButton release];
self.title = theSpecies.scientificName;
//[self.navigationItem.backBarButtonItem setTitle:#""];
self.navigationItem.backBarButtonItem.title = #"";
infoViewSegmentedControl.backgroundColor = [UIColor blackColor];
webView.backgroundColor = [UIColor blackColor];
_activityIndicator.hidden = YES;
[webView setOpaque:YES];
webView.delegate = self;
// Do double justification
[webView loadHTMLString:[self formatHTML:theSpecies] baseURL:nil];
showingInfoView = NO;
//
// Resize containerView, infoview according to iphone 5 screen size.
//
infoView.autoresizingMask = UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight;
CGPoint screenOrigin = [[UIScreen mainScreen] bounds].origin;
CGSize viewSize = [[UIScreen mainScreen] bounds].size;
CGPoint origin = infoView.frame.origin;
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
infoView.frame = CGRectMake(screenOrigin.x,
screenOrigin.y + statusBarFrame.size.height,
viewSize.width,
viewSize.height - origin.y - statusBarFrame.size.height);
speciesImageView = [[SpeciesImageView alloc]
initWithFrame:CGRectMake(screenOrigin.x,
screenOrigin.y,
viewSize.width,
viewSize.height)];
} else {
infoView.frame = CGRectMake(screenOrigin.x,
screenOrigin.y,
viewSize.width,
viewSize.height - origin.y - statusBarFrame.size.height);
speciesImageView = [[SpeciesImageView alloc]
initWithFrame:CGRectMake(screenOrigin.x,
screenOrigin.y,
viewSize.width,
viewSize.height - statusBarFrame.size.height)];
}
speciesImageView.delegate = self;
[containerView addSubview:speciesImageView];
managedObjectContext = [(LeafletAppDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext];
[self parseImageURLArray];
}
-(void)viewWillLayoutSubviews{
if(speciesImageView.window != nil){
CGRect screenRect = [[UIScreen mainScreen] bounds];
speciesImageView.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *widthConst = [NSLayoutConstraint
constraintWithItem:speciesImageView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:screenRect.size.width];
NSLayoutConstraint *heightConst = [NSLayoutConstraint
constraintWithItem:speciesImageView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:screenRect.size.height];
NSLayoutConstraint *rightConstraint = [NSLayoutConstraint
constraintWithItem:speciesImageView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0];
NSLayoutConstraint *bottomConstraint = [NSLayoutConstraint
constraintWithItem:speciesImageView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:0.0];
[self.view addConstraints:#[widthConst, heightConst, bottomConstraint, rightConstraint]];
}
}
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
imageScrollView = [[UIScrollView alloc] initWithFrame:frame];
imageScrollView.delegate = self;
imageScrollView.backgroundColor = [UIColor blackColor];
[self addSubview:imageScrollView];
imageScrollView.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *widthConst = [NSLayoutConstraint constraintWithItem:imageScrollView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:imageScrollView.frame.size.width];
NSLayoutConstraint *heightConst = [NSLayoutConstraint constraintWithItem:imageScrollView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:imageScrollView.frame.size.height];
NSLayoutConstraint *rightConstraint = [NSLayoutConstraint
constraintWithItem:imageScrollView
attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeRight
multiplier:1.0
constant:0.0];
NSLayoutConstraint *bottomConstraint = [NSLayoutConstraint
constraintWithItem:imageScrollView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:0.0];
[self addConstraints:#[widthConst, heightConst, bottomConstraint, rightConstraint]];
}
return self;
}
If you want your views to adjust to the size of the superview,
then you need something like this (set the margin to whatever you like):
CGFloat margin = 0;
NSString * visualFormatH = [NSString stringWithFormat:#"|-(%f)-[speciesImageView]-(%f)-|", margin, margin];
[self.containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:visualFormatH
options:0
metrics:Nil
views:#{#"speciesImageView": speciesImageView}]];
NSString * visualFormatV = [NSString stringWithFormat:#"V:|-(%f)-[speciesImageView]-(%f)-|", margin, margin];
[self.containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:visualFormatV
options:0
metrics:Nil
views:#{#"speciesImageView": speciesImageView}]];
Now speciesImageView will adjust its frame whenever the superview frame changes.
Here is a generic example:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIView * sampleView = [UIView new];
sampleView.backgroundColor = [UIColor redColor];
sampleView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:sampleView];
CGFloat margin = 0;
NSString * visualFormatH = [NSString stringWithFormat:#"|-(%f)-[sampleView]-(%f)-|", margin, margin];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:visualFormatH
options:0
metrics:Nil
views:#{#"sampleView": sampleView}]];
NSString * visualFormatV = [NSString stringWithFormat:#"V:|-(%f)-[sampleView]-(%f)-|", margin, margin];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:visualFormatV
options:0
metrics:Nil
views:#{#"sampleView": sampleView}]];
}
Auto Layout Getting Started
Auto Layout Visual Format Documentation

iOS - navigation bar displayed when UISearchController is active

I programatically created a UISearchController and added it to my UIView A. I also have a UITableView in the same UIView. I use UISearchController to search through my UITableView. When you click on a cell, UIView B gets pushed. Both UIView A and UIView B have UINavigationBar set to HIDDEN.
When I simply click on a UITableViewCell WITHOUT searching, everything happens perfectly, and UIView B is displayed without UINavigationBar.
But when I am searching using the UISearchController and I click on a UITableViewCell, the UINavigationBar is displayed on UIView B, even though I set it to hidden in the viewDidAppear method.
Here is my code:
BarsSearchController = [[UISearchController alloc] initWithSearchResultsController:nil];
BarsSearchController.searchResultsUpdater = self;
BarsSearchController.dimsBackgroundDuringPresentation = NO;
BarsSearchController.searchBar.delegate = self;
BarsSearchController.searchBar.barTintColor = [UIColor whiteColor];
BarsSearchController.searchBar.searchBarStyle = UISearchBarStyleMinimal;
[searchBarView addSubview:BarsSearchController.searchBar];
[searchBarView addConstraint:[NSLayoutConstraint constraintWithItem:BarsSearchController.searchBar
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:searchBarView
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:0.0]];
[searchBarView addConstraint:[NSLayoutConstraint constraintWithItem:BarsSearchController.searchBar
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:searchBarView
attribute:NSLayoutAttributeLeading
multiplier:1.0
constant:0.0]];
[searchBarView addConstraint:[NSLayoutConstraint constraintWithItem:BarsSearchController.searchBar
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:searchBarView
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:0.0]];
[searchBarView addConstraint:[NSLayoutConstraint constraintWithItem:BarsSearchController.searchBar
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:searchBarView
attribute:NSLayoutAttributeTrailing
multiplier:1.0
constant:0.0]];
[searchBarView layoutIfNeeded];
self.definesPresentationContext = YES;
[BarsSearchController.searchBar sizeToFit];
What am I missing here?
BarsSearchController.hidesNavigationBarDuringPresentation = YES;
I have the same problem, to fix it, I hide back button and background in viewDidLoad :
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.hidesBackButton = YES;
[[[self navigationController] navigationBar] setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
[[[self navigationController] navigationBar] setShadowImage:[UIImage new]];
[[[self navigationController] navigationBar] setTranslucent:YES];
}
and I hide navigationBar in viewDidAppear :
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[[self navigationController] setNavigationBarHidden:YES];
}

Custom UIView Subclass background color not being set with Autolayout enabled

I am creating a subclass of UIView with AutoLayout and cannot get it's background color to change for the life of me. Can someone take a look at the simple code and verify I am doing everything that needs to be done in the subclass of the UIView(PCCGenericRatingView). I read on SO that setting the background color only works if the frame is set. Shouldn't it be setting my frame to something other than CGRectZero after evaluating the constraints? I am printing out the view's frame in the viewDidAppear: lifecycle method, but it appears to be CGRectZero.
Edit:
When the frame is passed in to the views initWithFrame initializer, the background color is shown. Otherwise, it is now shown.
PCCGenericRatingView.h file:
#import <UIKit/UIKit.h>
#interface PCCGenericRatingView : UIView
#property (nonatomic, strong) UILabel *titleLabel;
#property (nonatomic, strong) UILabel *messageLabel;
- (instancetype)initWithTitle:(NSString *)title andMessage:(NSString *)message;
+ (instancetype)genericRatingViewWithTitle:(NSString *)title andMessage:(NSString *)message;
#end
PCCGenericRatingView.m file:
#import "PCCGenericRatingView.h"
#implementation PCCGenericRatingView
- (instancetype)initWithTitle:(NSString *)title andMessage:(NSString *)message {
if (self = [super init]) {
self.titleLabel = [[UILabel alloc] init];
self.messageLabel = [[UILabel alloc] init];
_titleLabel.text = title;
_messageLabel.text = message;
[self customizeView];
}
return self;
}
- (void)customizeView {
[self addSubview:_titleLabel];
[self addSubview:_messageLabel];
[_titleLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[_messageLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[_titleLabel setBackgroundColor:[UIColor yellowColor]];
[_messageLabel setBackgroundColor:[UIColor yellowColor]];
[_messageLabel setNumberOfLines:0];
[_messageLabel setTextAlignment:NSTextAlignmentCenter];
[_titleLabel setTextAlignment:NSTextAlignmentCenter];
[_titleLabel setFont:[UIFont fontWithName:#"HelveticaNeue-Bold" size:24.0f]];
[_messageLabel setFont:[UIFont fontWithName:#"HelveticaNeue-Thin" size:18.0f]];
}
+ (instancetype)genericRatingViewWithTitle:(NSString *)title andMessage:(NSString *)message {
return [[PCCGenericRatingView alloc] initWithTitle:title andMessage:message];
}
+ (BOOL)requiresConstraintBasedLayout {
return YES;
}
- (BOOL)translatesAutoresizingMaskIntoConstraints {
return NO;
}
-(void)updateConstraints {
CGRect windowRect = [UIScreen mainScreen].bounds;
NSDictionary *metrics = #{
#"height" : #(windowRect.size.height),
#"width" : #(windowRect.size.width)
};
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(self);
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:[self(==width)]" options:0 metrics:metrics views:viewsDictionary]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[self(==height)]" options:0 metrics:metrics views:viewsDictionary]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:_titleLabel
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeTop
multiplier:1.0f
constant:35.0f]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:_titleLabel
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeCenterX
multiplier:1.0f
constant:0.0f]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:_titleLabel
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeWidth
multiplier:1.0f
constant:0.0f]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:_titleLabel
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0f
constant:30.0f]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:_messageLabel
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeBottom
multiplier:1.0f
constant:-40.0f]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:_messageLabel
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeCenterX
multiplier:1.0f
constant:0.0f]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:_messageLabel
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeWidth
multiplier:1.0f
constant:0.0f]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:_messageLabel
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0f
constant:50.0f]];
[super updateConstraints];
}
#end
Parent View Controller:
#import "PCCLeaveRatingViewController.h"
#import "PCCGenericRating.h"
#import "PCCSliderRatingView.h"
#interface PCCLeaveRatingViewController ()
#end
#implementation PCCLeaveRatingViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.dataSource = #[ [[PCCGenericRating alloc] initWithTitle:#"Easiness"
andMessage:#"WHAT A JOKERRRR"
andVariatons:#[ #"very easy", #"easy", #"moderate", #"hard", #"very hard"]],
];
[self initView];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
- (void)initView {
[self setupConstraints];
[self addViewController];
}
- (void)setupConstraints {
CGRect windowFrame = [[UIApplication sharedApplication].delegate window].frame;
CGFloat windowWidth = windowFrame.size.width * self.dataSource.count;
[self.containerView addConstraint:[NSLayoutConstraint constraintWithItem:self.containerView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0f
constant:windowWidth]];
[self.containerView addConstraint:[NSLayoutConstraint constraintWithItem:self.containerView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0f
constant:windowFrame.size.height]];
}
- (void)addViewController {
PCCGenericRating *rating = self.dataSource[0];
PCCGenericRatingView *view = [PCCGenericRatingView genericRatingViewWithTitle:rating.title andMessage:rating.message];
[view setBackgroundColor:[UIColor yellowColor]];
const CGFloat viewWidth = [UIScreen mainScreen].bounds.size.width;
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(view);
NSDictionary *metrics = #{ #"viewWidth" : #(viewWidth) };
[_containerView addSubview:view];
[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:[view(==viewWidth)]" options:0 metrics:metrics views:viewsDictionary]];
[self.containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[view]|" options:0 metrics:nil views:viewsDictionary]];
}
#end
print out the view property to trace whether it is pointing the view which you are referring or other [view setBackgroundColor:[UIColor yellowColor]]

Can't remove/hide recently added view from self.navigationcontroller.view

I have a Navigationviewcontroller with a tableview in it. I am adding a UIView to self.navigationcontroller.view and constraints for Auto Layout. When I try to remove it from superview or to hide it, nothing happens.
Any ideas?
How I create the View and Constraints
-(void)doneWithTraining{
//Create Backgroundview
UIView *groupView = [[UIView alloc] init];
[groupView setTranslatesAutoresizingMaskIntoConstraints:NO];
groupView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.7];
groupView.tag = 999;
groupView.alpha = 0.0;
[self.navigationController.view addSubview:groupView];
[self.navigationController.view addConstraint:[NSLayoutConstraint constraintWithItem:groupView
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:self.navigationController.view
attribute:NSLayoutAttributeLeft
multiplier:1.0
constant:0]];
[self.navigationController.view addConstraint:[NSLayoutConstraint constraintWithItem:groupView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.navigationController.view
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:0.0f]];
[self.navigationController.view addConstraint:[NSLayoutConstraint constraintWithItem:groupView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self.navigationController.view
attribute:NSLayoutAttributeWidth
multiplier:1.0
constant:0.0]];
[self.navigationController.view addConstraint:[NSLayoutConstraint constraintWithItem:groupView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self.navigationController.view
attribute:NSLayoutAttributeHeight
}
multiplier:1.0
constant:0.0]];
//Animate View
[UIView animateWithDuration:0.2 animations:^(void) {
groupView.alpha = 1.0;
}];
How I try to remove the View
- (void)closeFinishAlert{
UIView *grouView = [self.navigationController.view viewWithTag:999];
grouView.hidden = YES;
NSLog(#"Check if closeFinishAlert is called");
//[self.navigationController popViewControllerAnimated:YES];
}
What I also tried
This removes the view an its content, but after this there is no user interaction possible. It looks like a crash, but Xcode tells me that the app is still running.
- (void)closeFinishAlert{
UIView *groupView = [self.navigationController.view viewWithTag:999];
for (UIView *subview in groupView.subviews) {
subview.hidden = YES;
[subview removeFromSuperview];
}
[_groupView removeFromSuperview];
//[self.navigationController popViewControllerAnimated:YES];
}
If you are actually just presenting a view which you will remove for sure later on,
then its better to create a ViewController class for your view and present it modally using :
[self presentViewController:yourViewControllerObject animated:NO completion:nil];
you can later on remove this view using:
[self dismissViewControllerAnimated:NO completion:nil];
hope this helps !
Thanks to "GoGreen" green I found a solution which works for me.
Create Viewcontroller from ViewDidAppear
- (void)viewDidAppear:(BOOL)animated{
if (executedExercises.count == [_fetchedResultsController.fetchedObjects count] && self.groupView == FALSE) {
[self performSelector:#selector(doneWithTraining) withObject:nil afterDelay:0.0];
}
}
Header file
#property (strong, nonatomic) UIViewController *groupView;
Creating the Viewcrontroller and its content
-(void)doneWithTraining{
_groupView = [[UIViewController alloc] init];
[self presentViewController:_groupView animated:YES completion:nil];
_groupView.view.backgroundColor = [UIColor whiteColor];
//SubTitle
UILabel *subTitleLabel = [[UILabel alloc] init];
[subTitleLabel setFont:[UIFont fontWithName:#"HelveticaNeue-Light" size:18.0]];
subTitleLabel.textColor = [BackgroundLayer gray];
[subTitleLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
subTitleLabel.numberOfLines = 5;
subTitleLabel.adjustsFontSizeToFitWidth = YES;
subTitleLabel.textAlignment = NSTextAlignmentCenter;
[_groupView.view addSubview:subTitleLabel];
subTitleLabel.text = subTitleText;
[_groupView.view addConstraint:[NSLayoutConstraint constraintWithItem:subTitleLabel
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationLessThanOrEqual
toItem:_groupView.view
attribute:NSLayoutAttributeWidth
multiplier:0.0
constant:300.0f]];
[_groupView.view addConstraint:[NSLayoutConstraint constraintWithItem:subTitleLabel
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:_groupView.view
attribute:NSLayoutAttributeHeight
multiplier:0.0
constant:140]];
[_groupView.view addConstraint:[NSLayoutConstraint constraintWithItem:subTitleLabel
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:_groupView.view
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0]];
[_groupView.view addConstraint:[NSLayoutConstraint constraintWithItem:subTitleLabel
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:_groupView.view
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0.0]];}
Removing ViewController
- (void)closeFinishAlert{
[_groupView dismissViewControllerAnimated:NO completion:nil];
[self.navigationController popViewControllerAnimated:YES];
}

Issue with autoLayout and constraints

I have an issue with iOS and AutoLayout...it is a testing application where I have replicated the problem. It consists in a simple view controller, containing a fixed UIButton; when user clicks this button, the delegate have to create a custom view, apply it positioning constraints; the view has then a method to build his content views, and the child views are placed with constraints too.
Here is the code:
//MyViewController.m
#implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIButton *start_but = [[UIButton alloc] initWithFrame:CGRectMake(10, 10, 100, 40)];
[start_but setTitle:#"Draw" forState:UIControlStateNormal];
[start_but setTitleColor:[UIColor yellowColor] forState:UIControlStateNormal];
[start_but addTarget:self action:#selector(clickAction:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:start_but];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)clickAction: (id)sender
{
localView = [[MyView alloc] initWithFrame:CGRectMake(0, 0, 400, 300)];
UIView *superview = (UIView*)localView;
superview.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:localView];
NSLayoutConstraint *constr = [NSLayoutConstraint constraintWithItem:localView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:100.0];
[self.view addConstraint:constr];
constr = [NSLayoutConstraint constraintWithItem:localView
attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeRight
multiplier:1.0
constant:-50.0];
[self.view addConstraint:constr];
[localView CreateGuiInterface];
}
#end
//MyView.m
#implementation MyView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
// Initialization code
}
return self;
}
-(void)CreateGuiInterface
{
UIView *superview = self;
self.backgroundColor = [UIColor redColor];
UIButton *but1 = [[UIButton alloc] init];
[but1 setTitle:#"Button" forState:UIControlStateNormal];
[but1 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
but1.backgroundColor = [UIColor yellowColor];
but1.translatesAutoresizingMaskIntoConstraints = NO;
[superview addSubview:but1];
NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:but1
attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual
toItem:superview
attribute:NSLayoutAttributeRight multiplier:1.0
constant:-20.0];
[superview addConstraint:constraint];
constraint = [NSLayoutConstraint constraintWithItem:but1
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:superview
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:50.0];
[superview addConstraint:constraint];
UILabel *label = [[UILabel alloc] init];
label.text = #"Label";
label.backgroundColor = [UIColor greenColor];
label.textColor = [UIColor blackColor];
label.translatesAutoresizingMaskIntoConstraints = NO;
[superview addSubview:label];
constraint = [NSLayoutConstraint constraintWithItem:label
attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual
toItem:but1
attribute:NSLayoutAttributeLeft
multiplier:1.0
constant:-40.0];
[superview addConstraint:constraint];
constraint = [NSLayoutConstraint constraintWithItem:label
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:but1
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:20.0];
[superview addConstraint:constraint];
}
#end
So, the problem is that when i click iOS seems to have problem to draw the view background color. It is strange, 'cause if i don't use superview.translatesAutoresizingMaskIntoConstraints = NO and put the view in a fixed place (with initWithFrame:CGRect(100,200,300,400) for example) without using constraints, it works fine: can there be problems using constraints in child and parent views? AppleDoc said that the constraints cannot pass throughout the view barrier; so i've written my app with local-view oriented constraints....
can somebody help me?
thanks in advice
The intent with autoLayout is to never have to setFrame on any of your views. If you want to place your view programatically within your superview, you will provide constraints for that. The changes I made you will see the background red as intended. I didn't change your MyView implementation (simply added -(void)CreateGuiInterface;
within MyView.h). The changes I made to demonstrate are within your MyViewController implementation.
Try the following code in place of your viewController:
#interface MyViewController ()
#property (nonatomic, strong) MyView* localView;
#end
#implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIButton *start_but = [[UIButton alloc] init];
start_but.translatesAutoresizingMaskIntoConstraints = NO;
[start_but setTitle:#"Draw" forState:UIControlStateNormal];
[start_but setTitleColor:[UIColor yellowColor] forState:UIControlStateNormal];
[start_but addTarget:self action:#selector(clickAction:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:start_but];
// The following constraints simply place the initial start button in the top left
NSDictionary* views = NSDictionaryOfVariableBindings(start_but);
NSString* format = #"H:|-[start_but]";
NSArray* constraints = [NSLayoutConstraint constraintsWithVisualFormat:format
options:0
metrics:nil
views:views];
[self.view addConstraints:constraints];
format = #"V:|-[start_but]";
constraints = [NSLayoutConstraint constraintsWithVisualFormat:format
options:0
metrics:nil
views:views];
[self.view addConstraints:constraints];
}
- (void)clickAction: (id)sender
{
self.localView = [[MyView alloc] init];
UIView *superview = (UIView*)self.localView;
superview.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.localView];
// Here I'm placing your parent view (MyView) 50 points on right of the superview with
// a width of 400 points
NSDictionary* views = NSDictionaryOfVariableBindings(superview);
NSString* format = #"H:[superview(==400)]-(50)-|";
NSArray* constraints = [NSLayoutConstraint constraintsWithVisualFormat:format
options:0
metrics:nil
views:views];
[self.view addConstraints:constraints];
// Vertically 100 points from the top of the superview with a height of 300 points
format = #"V:|-(100)-[superview(==300)]";
constraints = [NSLayoutConstraint constraintsWithVisualFormat:format
options:0
metrics:nil
views:views];
[self.view addConstraints:constraints];
[self.localView CreateGuiInterface];
}
#end

Resources