Autolayout issues on using KOLODA library - ios

Am using KOLODA library,and i have issues in providing more than one xibs to display the cards,In that second view(Xib) size are not fit into the koloda's first xib.how to adjust the view layout,any solutions for that is much appreciated.
NOTE:The problem here is i need multiple xib's which have different formats.
//This is my code
self.contentView.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *width = [NSLayoutConstraint constraintWithItem:self.contentView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeWidth
multiplier:1.0
constant:0];
NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:self.contentView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeHeight
multiplier:1.0
constant:0];
NSLayoutConstraint *top = [NSLayoutConstraint constraintWithItem:self.contentView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:0];
NSLayoutConstraint *leading = [NSLayoutConstraint constraintWithItem:self.contentView
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeLeading
multiplier:1.0
constant:0];
[self addConstraints:#[width,height,top,leading]];

Related

UIButton constraints programmatically

I have created "first button" using storyboard and set its constraints for it, now I want to create another button programmatically and set it above the first button like this :
and I use this code to try and achieve this:
NSLayoutConstraint *xConstraint = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0];
NSLayoutConstraint *Yxonstraints = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.invoiceTextField attribute:NSLayoutAttributeTop multiplier:1.0 constant:0];
NSLayoutConstraint *width = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:200];
NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:200];
[self.view addConstraints:#[xConstraint,Yxonstraints,width,height]];
However the second button ends up in the middle and on the left and also smaller than its actual size, what am I doing wrong here?
You need
self.secondBu.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
self.secondBu.bottomAnchor.constraint(equalTo: self.firstBu.topAnchor, constant:-15)
self.secondBu.leadingAnchor.constraint(equalTo: self.firstBu.leadingAnchor),
self.secondBu.trailingAnchor.constraint(equalTo: self.firstBu.trailingAnchor),
self.secondBu.heightAnchor.constraint(equalTo: self.firstBu.heightAnchor)
])
but the easiest way is to insert firstBu inside UIStackView in storyboard , and then use 1 line
self.stackView.insertArrangedSubview(secondBu,at:0)
you may set stackView spacing property to 15 also in IB , also avoid using addConstraints as recommended by Apple and use NSLayoutConstraint.activate
NSLayoutConstraint *Yxonstraints = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.invoiceTextField attribute:NSLayoutAttributeTop multiplier:1.0 constant:0];
You don't want that. You want secondButton.top be space to firstButton.bottom :
NSLayoutConstraint *Yxonstraints = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.invoiceTextField attribute:NSLayoutAttributeBottom multiplier:1.0 constant:20];

IOS/Autolayout: When in lifecycle to set constraints for elements created in code

Most of my scene is in storyboard and uses autolayout. But I want to create a UITableView, label and view in code and constrain them within the overall autlayout. My question is where in the lifecycle should I create the constraints.
Right now, I create hidden versions of the elements in ViewDidLoad and then customize and display them in View Will Appear based on data. I don't think I can put the layout constraints in ViewDidLoad, because the compiler won't know where all the views from storyboard are located. On the other hand, I don't want to recreate these constraints everytime viewWillAppear fires. Most don't change and at most I might want to update one or two.
Should I place the constraints in viewWillAppear and condition creating them on some test whether they were already created? Or should I put them somewhere else such as viewDidlayoutSubviews or viewDidAppear?
Thanks for any suggestions.
This is the code that creates the constraints:
NSLayoutConstraint *contop = [NSLayoutConstraint constraintWithItem:_stepsTableView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_stepNames attribute:NSLayoutAttributeBottom multiplier:1 constant:12];
NSLayoutConstraint *contrail = [NSLayoutConstraint
constraintWithItem:_stepsTableView attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual toItem:self.scrollView
attribute:NSLayoutAttributeTrailing multiplier:1 constant:20];
NSLayoutConstraint *conlead = [NSLayoutConstraint
constraintWithItem:_stepsTableView attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual toItem:self.scrollView
attribute:NSLayoutAttributeLeading multiplier:1 constant:20];
NSLayoutConstraint *conbot = [NSLayoutConstraint
constraintWithItem:_stepsTableView attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual toItem:self.scrollView
attribute:NSLayoutAttributeBottom multiplier:1 constant:20];
NSLayoutConstraint *conheight = [NSLayoutConstraint constraintWithItem:_stepsTableView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:height];
[self.scrollView removeConstraint: _bottomConstraint];
[self.scrollView addConstraints:#[contop,contrail,conlead,conbot,conheight]];
[self.view layoutIfNeeded];
Any programmatically created constraints should be placed in viewDidLayoutSubviews and wraped with once bool value as the function is being called multiple times during launch of a viewController
-(void)viewDidLayoutSubviews
{
if(once){
once = NO;
_stepsTableView.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *contop = [NSLayoutConstraint constraintWithItem:_stepsTableView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_stepNames attribute:NSLayoutAttributeBottom multiplier:1 constant:12];
NSLayoutConstraint *contrail = [NSLayoutConstraint
constraintWithItem:_stepsTableView attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual toItem:self.scrollView
attribute:NSLayoutAttributeTrailing multiplier:1 constant:20];
NSLayoutConstraint *conlead = [NSLayoutConstraint
constraintWithItem:_stepsTableView attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual toItem:self.scrollView
attribute:NSLayoutAttributeLeading multiplier:1 constant:20];
NSLayoutConstraint *conbot = [NSLayoutConstraint
constraintWithItem:_stepsTableView attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual toItem:self.scrollView
attribute:NSLayoutAttributeBottom multiplier:1 constant:20];
NSLayoutConstraint *conheight = [NSLayoutConstraint constraintWithItem:_stepsTableView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:height];
[self.scrollView removeConstraint: _bottomConstraint];
[self.scrollView addConstraints:#[contop,contrail,conlead,conbot,conheight]];
[self.view layoutIfNeeded];
}
}

How to set View height as percentage of the screen height in Storyboards with XCode 7

I need to design the view like below image and I have tried with fixed heights and also tried compact width and regular height and regular width and compact height but those scenarios did not worked for me.
How can i set View height as percentage of the screen height in Storyboards?
I'm using Xcode 7
Basically you need to act on the multiplier property of an height equal constraint. To do that while pressing CTRL, drag from the view to its superview and select equal heights constraint, later edit this constraint in Size Inspector by setting its multiplier the desired value can be expressed also as 1:25, 1/25, 0,025. If it working on the contrary just reverse items as in the picture.
You can simply set the height of each one as a ratio of the UI height, 15% height would be;
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height * 0.15)
Programmatic version
- (void)overallViewConstratints {
_firstView = [[UIView alloc]init];
[_firstView setTranslatesAutoresizingMaskIntoConstraints:NO];
_firstView.backgroundColor = [UIColor grayColor];
[self.view addSubview:_firstView];
NSLayoutConstraint *firstViewTop = [NSLayoutConstraint constraintWithItem:_firstView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0];
NSLayoutConstraint *firstViewLeading = [NSLayoutConstraint constraintWithItem:_firstView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0.0];
NSLayoutConstraint *firstViewTrailing = [NSLayoutConstraint constraintWithItem:_firstView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0.0];
NSLayoutConstraint *firstViewHeight = [NSLayoutConstraint constraintWithItem:_firstView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeHeight multiplier:0.15 constant:0.0];
NSArray *firstViewConstraints = #[firstViewTop, firstViewLeading, firstViewTrailing, firstViewHeight];
[self.view addConstraints:firstViewConstraints];
_secondView = [[UIView alloc]init];
_secondView.backgroundColor = [UIColor darkGrayColor];
[self.secondView setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.view addSubview:_secondView];
NSLayoutConstraint *secondViewTop = [NSLayoutConstraint constraintWithItem:_secondView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_firstView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0];
NSLayoutConstraint *secondViewLeading = [NSLayoutConstraint constraintWithItem:_secondView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0.0];
NSLayoutConstraint *secondViewTrailing = [NSLayoutConstraint constraintWithItem:_secondView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0.0];
NSLayoutConstraint *secondViewHeight = [NSLayoutConstraint constraintWithItem:_secondView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeHeight multiplier:0.25 constant:0.0];
NSArray *secondViewConstraints = #[secondViewTop, secondViewLeading, secondViewTrailing, secondViewHeight];
[self.view addConstraints:secondViewConstraints];
_thirdView = [[UIView alloc]init];
_thirdView.backgroundColor = [UIColor lightGrayColor];
[_thirdView setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.view addSubview:_thirdView];
NSLayoutConstraint *thirdViewTop = [NSLayoutConstraint constraintWithItem:_thirdView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_secondView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0];
NSLayoutConstraint *thirdViewLeading = [NSLayoutConstraint constraintWithItem:_thirdView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0.0];
NSLayoutConstraint *thirdViewTrailing = [NSLayoutConstraint constraintWithItem:_thirdView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0.0];
NSLayoutConstraint *thirdViewHeight = [NSLayoutConstraint constraintWithItem:_thirdView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeHeight multiplier:0.40 constant:0.0];
NSArray *thirdViewConstraints = #[thirdViewTop, thirdViewLeading, thirdViewTrailing, thirdViewHeight];
[self.view addConstraints:thirdViewConstraints];
_fourthView = [[UIView alloc]init];
_fourthView.backgroundColor = [UIColor brownColor];
[_fourthView setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.view addSubview:_fourthView];
NSLayoutConstraint *fourthViewTop = [NSLayoutConstraint constraintWithItem:_fourthView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_thirdView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0];
NSLayoutConstraint *fourthViewLeading = [NSLayoutConstraint constraintWithItem:_fourthView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0.0];
NSLayoutConstraint *fourthViewTrailing = [NSLayoutConstraint constraintWithItem:_fourthView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0.0];
NSLayoutConstraint *fourthViewHeight = [NSLayoutConstraint constraintWithItem:_fourthView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeHeight multiplier:0.20 constant:0.0];
NSArray *fourthViewConstraints = #[fourthViewTop, fourthViewLeading, fourthViewTrailing, fourthViewHeight];
[self.view addConstraints:fourthViewConstraints];
}

NSLayoutConstraint inside UITableViewCell crashes app

I'm trying to position an image in the center of a UITableViewCell with NSLayoutConstraints. I'm using the code below for that:
NSLayoutConstraint *cn = [NSLayoutConstraint constraintWithItem:self.image
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:cell.contentView
attribute:NSLayoutAttributeWidth
multiplier:1
constant:200];
[self.image addConstraint: cn];
cn = [NSLayoutConstraint constraintWithItem:self.image
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:cell.contentView
attribute:NSLayoutAttributeHeight
multiplier:1
constant:200];
[self.image addConstraint:cn];
Also, I would like the image to be 80% of the UITableViewCells height and have the same width - so it's square. However, currently my app crashes and throws this error: Impossible to set up layout with view hierarchy unprepared for constraint.
What am I doing wrong?
As it turns out, I had to add the image to the cell.contentView, so that it was actually available as a subview.
This is the completed working code:
NSLayoutConstraint *cn = [NSLayoutConstraint constraintWithItem:self.image
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:cell.contentView
attribute:NSLayoutAttributeHeight
multiplier:0.7
constant:0];
[cell.contentView addConstraint: cn];
cn = [NSLayoutConstraint constraintWithItem:self.image
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:cell.contentView
attribute:NSLayoutAttributeHeight
multiplier:0.7
constant:0];
[cell.contentView addConstraint:cn];
NSLayoutConstraint *constraintX = [NSLayoutConstraint constraintWithItem:self.image attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:cell.contentView attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0];
NSLayoutConstraint *constraintY = [NSLayoutConstraint constraintWithItem:self.image attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:cell.contentView attribute:NSLayoutAttributeCenterY multiplier:1.0f constant:0];
[cell.contentView addConstraint:constraintX];
[cell.contentView addConstraint:constraintY];
Exactly what is "self.image" referring to? Is it a property of your View Controller (this would be definitely wrong)? Seems to me it should be "cell.image" where each of your cells should have it's own reference to an image.

Cannot modify constraints for UIToolbar managed by a UINavigationController

I am adding NSContraints to a Toolbar of of UINavigationController and I get this error:
Cannot modify constraints for UIToolbar managed by a UINavigationController
In ViewDidLoad:
self.navigationController.toolbarHidden = NO;
[self.navigationController.toolbar addSubview:_labelName];
[self.navigationController.toolbar addSubview:_labelAddress];
Then I call the method below:
NSLayoutConstraint *nameRight = [NSLayoutConstraint constraintWithItem:_labelName attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.navigationController.toolbar attribute:NSLayoutAttributeRight multiplier:1 constant:20];
NSLayoutConstraint *nameLeft = [NSLayoutConstraint constraintWithItem:_labelName attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.navigationController.toolbar attribute:NSLayoutAttributeLeft multiplier:1 constant:20];
NSLayoutConstraint *nameTop = [NSLayoutConstraint constraintWithItem:_labelName attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.navigationController.toolbar attribute:NSLayoutAttributeTop multiplier:1 constant:0];
NSLayoutConstraint *nameHeight = [NSLayoutConstraint constraintWithItem:_labelName attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.navigationController.toolbar attribute:NSLayoutAttributeHeight multiplier:.5 constant:0];
NSLayoutConstraint *addressRight = [NSLayoutConstraint constraintWithItem:_labelAddress attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.navigationController.toolbar attribute:NSLayoutAttributeRight multiplier:1 constant:20];
NSLayoutConstraint *addressLeft = [NSLayoutConstraint constraintWithItem:_labelAddress attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.navigationController.toolbar attribute:NSLayoutAttributeLeft multiplier:1 constant:20];
NSLayoutConstraint *addressTop = [NSLayoutConstraint constraintWithItem:_labelAddress attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_labelName attribute:NSLayoutAttributeBottom multiplier:1 constant:0];
NSLayoutConstraint *addressHeight = [NSLayoutConstraint constraintWithItem:_labelAddress attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.navigationController.toolbar attribute:NSLayoutAttributeHeight multiplier:.5 constant:0];
[self.navigationController.toolbar addConstraints:#[nameRight, nameLeft, nameTop, nameHeight, addressRight, addressLeft, addressTop, addressHeight]];
Should I create a UIView inside the toolbar of the navigation controller? and put the contraints inside it?
Autolayout constraints only work with UIViews and their subclasses.
Your alternative is to roll your own toolbar with widgets based only on UIViews.
Link : iOS Autolayout and UIToolbar/UIBarButtonItems
I hope this will resolve your issue.
The issue was you need to add the toolbar items to [self using setToolBarItem] not [self.navigationController.toolbar ..] even though techinically it is the same object.
It is like self.title, sets the navigation controller title, [self setToolbarItems set the toolbar items of the navigation controller toolbar
[self setToolbarItems:#[barButtonItem] animated:NO]; <-- Answer
[self.navigationController.toolbar setItems:#[barButtonItem]]; <-- BAD
For the NSLayout you do that inside a view in the BarButtonItem:
_toolBarView = [[UIView alloc] init];
[_toolBarView addSubview:_labelName];
[_toolBarView addSubview:_labelAddress];
barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:_toolBarView];
NSLayout code:
NSLayoutConstraint *nameRight = [NSLayoutConstraint constraintWithItem:_labelName attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:_toolBarView attribute:NSLayoutAttributeRight multiplier:1 constant:0];
NSLayoutConstraint *nameLeft = [NSLayoutConstraint constraintWithItem:_labelName attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:_toolBarView attribute:NSLayoutAttributeLeft multiplier:1 constant:0];
NSLayoutConstraint *nameTop = [NSLayoutConstraint constraintWithItem:_labelName attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_toolBarView attribute:NSLayoutAttributeTop multiplier:1 constant:0];
NSLayoutConstraint *nameHeight = [NSLayoutConstraint constraintWithItem:_labelName attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:_toolBarView attribute:NSLayoutAttributeHeight multiplier:0.5 constant:0];
NSLayoutConstraint *addressRight = [NSLayoutConstraint constraintWithItem:_labelAddress attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:_toolBarView attribute:NSLayoutAttributeRight multiplier:1 constant:0];
NSLayoutConstraint *addressLeft = [NSLayoutConstraint constraintWithItem:_labelAddress attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:_toolBarView attribute:NSLayoutAttributeLeft multiplier:1 constant:0];
NSLayoutConstraint *addressTop = [NSLayoutConstraint constraintWithItem:_labelAddress attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_labelName attribute:NSLayoutAttributeBottom multiplier:1 constant:0];
NSLayoutConstraint *addressHeight = [NSLayoutConstraint constraintWithItem:_labelAddress attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:_toolBarView attribute:NSLayoutAttributeHeight multiplier:0.5 constant:0];
[_toolBarView addConstraints:#[nameRight, nameLeft, nameTop, nameHeight, addressRight, addressLeft, addressTop, addressHeight]];
Hope this helps!

Resources