UIImagePickerController, custom UIButton and AutoLayout - ios

I'm trying to put a custom button into UIImagePickerController using auto layout constraints.
- (void)createTimerButtonFor:(UIImagePickerController*)picker
{
UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setTitle:#"Timer" forState:UIControlStateNormal];
NSLayoutConstraint* constraint1 = [NSLayoutConstraint constraintWithItem:picker.view attribute:NSLayoutAttributeCenterX relatedBy: NSLayoutRelationEqual toItem:button attribute:NSLayoutAttributeCenterX multiplier:1 constant:0];
NSLayoutConstraint* constraint2 = [NSLayoutConstraint constraintWithItem:picker.view attribute:NSLayoutAttributeTop relatedBy: NSLayoutRelationEqual toItem:button attribute:NSLayoutAttributeTop multiplier:1 constant:0];
NSLayoutConstraint *heightConstraint =
[NSLayoutConstraint constraintWithItem:button
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:100.0];
NSLayoutConstraint *widthConstraint =
[NSLayoutConstraint constraintWithItem:button
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:100.0];
[picker.view addSubview:button];
[picker.view addConstraint:constraint1];
[picker.view addConstraint:constraint2];
[button addConstraint:heightConstraint];
[button addConstraint:widthConstraint];
}
Is it even possible to do so? Am I doing something wrong?

Dzior, I think it would be quite hard to add the button to the picker view and let autolayout to position it for you. I guess maybe it is not fully using the auto layout.
I have tried to disable it from rotating but all the tricks for before iOS 8 is not working properly on iOS 8.
It will be easier to create an overlay view and put your button in the overlay view because you have full control of the overlay view class.

Related

How to draw a overlay view on top of UINavigation and UITabBar

I want to show a over lay view on top of the existing UINavigationBar and UITabBar items int he bottom.
I tried adding the overlay view's view on application window directly but wouldn't work any idea.
Here is my custom view with all constraints
-(void)showView{
animationOverlay=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 400, 400)];
animationOverlay.translatesAutoresizingMaskIntoConstraints=false;
UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom];
[btn setFrame:CGRectMake(0, 0, 100, 100)];
[btn setTitle:#"Go" forState:UIControlStateNormal];
[btn setTranslatesAutoresizingMaskIntoConstraints:false];
[animationOverlay setBackgroundColor:[UIColor redColor]];
NSLayoutConstraint *leftConstraint = [NSLayoutConstraint
constraintWithItem:animationOverlay attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual toItem:self.view attribute:
NSLayoutAttributeLeft multiplier:1.0 constant:0];
NSLayoutConstraint *rightConstraint = [NSLayoutConstraint
constraintWithItem:animationOverlay attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual toItem:self.view attribute:
NSLayoutAttributeWidth multiplier:1.0 constant:0];
NSLayoutConstraint *topConstraint = [NSLayoutConstraint
constraintWithItem:animationOverlay attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual toItem:self.view attribute:
NSLayoutAttributeTop multiplier:1.0 constant:0];
NSLayoutConstraint *bottomConstraint = [NSLayoutConstraint
constraintWithItem:animationOverlay attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual toItem:self.view attribute:
NSLayoutAttributeBottom multiplier:1.0 constant:0];
NSLayoutConstraint *centreXConstraint= [NSLayoutConstraint constraintWithItem:btn
attribute:NSLayoutAttributeCenterX
relatedBy:0
toItem:animationOverlay
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0];
NSLayoutConstraint *centreYConstraint= [NSLayoutConstraint constraintWithItem:btn
attribute:NSLayoutAttributeCenterY
relatedBy:0
toItem:animationOverlay
attribute:NSLayoutAttributeCenterY
multiplier:1
constant:0];
[self.view addSubview:animationOverlay];
[self.view addConstraint:leftConstraint];
[self.view addConstraint:rightConstraint];
[self.view addConstraint:topConstraint];
[self.view addConstraint:bottomConstraint];
[animationOverlay addSubview:btn];
[self.view addConstraint:centreXConstraint];
[self.view addConstraint:centreYConstraint];
}
-(void)hideView{
[animationOverlay removeFromSuperview];
}
right now I can do this inside a ViewController's view successfully
Any ideas on how to do this..
I couldn't think a way how to do this without breaking the constraints
any ideas,suggestions are welcome
Did you try to show the VC modally, I think that will cover the tabbar and navigationbar:
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion;
So put your overlay view inside another VC, and then present that VC from your current VC using presentViewController:

Adding UIButton To UITableView Programmatically Wrong Spot

I'm trying to get a UIButton added to a TableView, where it sits in the bottom right corner of the table view, 20 from the right edge, and 20 from the bottom. However, it ends up sticking the button at the top left edge. What am I doing wrong?
UIButton *goToTop = [UIButton buttonWithType:UIButtonTypeCustom];
[goToTop setImage:redGo forState:UIControlStateNormal];
[goToTop addTarget:self action:#selector(beginCampaign) forControlEvents:UIControlEventTouchUpInside];
[goToTop setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[goToTop.layer setBorderColor:[[UIColor redColor] CGColor]];
[self.tableView addSubview:goToTop];
goToTop.translatesAutoresizingMaskIntoConstraints = NO;
/* Leading space to superview */
NSLayoutConstraint *leftButtonXConstraint = [NSLayoutConstraint
constraintWithItem:goToTop attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual toItem:self.tableView attribute:
NSLayoutAttributeLeft multiplier:1.0 constant:20];
/* Top space to superview Y*/
NSLayoutConstraint *leftButtonYConstraint = [NSLayoutConstraint
constraintWithItem:goToTop attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual toItem:self.tableView attribute:
NSLayoutAttributeTop multiplier:1.0f constant:20];
/* Fixed width */
NSLayoutConstraint *widthConstraint = [NSLayoutConstraint constraintWithItem:goToTop
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:60];
/* Fixed Height */
NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem:goToTop
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:60];
/* 4. Add the constraints to button's superview*/
[self.tableView addConstraints:#[leftButtonXConstraint, leftButtonYConstraint, widthConstraint, heightConstraint]];
Here is how I would like it:
Here is how it appears:
You have set your constraints to the top left of the table view not the bottom right.
Change this:
/* Leading space to superview */
NSLayoutConstraint *leftButtonXConstraint = [NSLayoutConstraint
constraintWithItem:goToTop attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual toItem:self.tableView attribute:
NSLayoutAttributeLeft multiplier:1.0 constant:20];
/* Top space to superview Y*/
NSLayoutConstraint *leftButtonYConstraint = [NSLayoutConstraint
constraintWithItem:goToTop attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual toItem:self.tableView attribute:
NSLayoutAttributeTop multiplier:1.0f constant:20];
To this:
/* Leading space to superview */
NSLayoutConstraint *leftButtonXConstraint = [NSLayoutConstraint
constraintWithItem:goToTop attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual toItem:self.tableView attribute:
NSLayoutAttributeRight multiplier:1.0 constant:20];
/* Top space to superview Y*/
NSLayoutConstraint *leftButtonYConstraint = [NSLayoutConstraint
constraintWithItem:goToTop attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual toItem:self.tableView attribute:
NSLayoutAttributeBottom multiplier:1.0f constant:20];

How to add container view on scrollview using constraint with item formate

I am new for auto-layouts and i am trying to add one container view on ScrollView using auto-layouts "constraint with item" formate but I can't adding using my code.
I know how to add using visual formate but I want to do this process using constraint with item formate. Please help me!
My code:
#import "ViewController3.h"
#interface ViewController3 ()
{
UIScrollView * scrollView;
UIView * containerView;
}
#end
#implementation ViewController3
- (void)viewDidLoad {
[super viewDidLoad];
scrollView = [[UIScrollView alloc] init];
scrollView.backgroundColor = [UIColor lightGrayColor];
scrollView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:scrollView];
containerView = [[UIView alloc] init];
containerView.backgroundColor = [UIColor orangeColor];
containerView.translatesAutoresizingMaskIntoConstraints = NO;
[scrollView addSubview:containerView];
//Applying autolayouts for scrollview
NSLayoutConstraint * constraint1 = [NSLayoutConstraint constraintWithItem:scrollView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem: self.view attribute:NSLayoutAttributeTop multiplier:1.0f constant:0.0f];
[self.view addConstraint:constraint1];
constraint1 = [NSLayoutConstraint constraintWithItem:scrollView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.0f constant:0.0f];
[self.view addConstraint:constraint1];
constraint1 = [NSLayoutConstraint constraintWithItem:scrollView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1.0f constant:0.0f];
[self.view addConstraint:constraint1];
constraint1 = [NSLayoutConstraint constraintWithItem:scrollView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0f constant:0.0f];
[self.view addConstraint:constraint1];
//Applying autolayouts for containerview
NSLayoutConstraint * constraint2 = [NSLayoutConstraint constraintWithItem:containerView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem: scrollView attribute:NSLayoutAttributeTop multiplier:1.0f constant:0.0f];
[scrollView addConstraint:constraint2];
constraint2 = [NSLayoutConstraint constraintWithItem:containerView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeLeading multiplier:1.0f constant:0.0f];
[scrollView addConstraint:constraint2];
constraint2 = [NSLayoutConstraint constraintWithItem:containerView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTrailing multiplier:1.0f constant:0.0f];
[scrollView addConstraint:constraint2];
constraint2 = [NSLayoutConstraint constraintWithItem:containerView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeBottom multiplier:1.0f constant:0.0f];
[scrollView addConstraint:constraint2];
}
With Autolayout, you don't need to set scrollview's contentSize explicitly, but you have to provide enough clues to let Autolayout system infer what exactly your scrollview's contentSize is.
There are generally two ways to layout UIScrollView with Autolayout, mixed or pure Autolayout.Check this:https://developer.apple.com/library/ios/technotes/tn2154/_index.html.
If it is pure Autolayout, you can achieve that by your containerView's subviews, that is, your subviews do not rely on the scroll view to get their size. Or you can just tie your containerView's width and height to any view outside your scrollview, like self.view, or to a fixed value.
E.g,
You can add four more lines :
constraint2 = [NSLayoutConstraint constraintWithItem:containerView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:1 constant:0];
[self.view addConstraint:constraint2];
constraint2 = [NSLayoutConstraint constraintWithItem:containerView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeHeight multiplier:1 constant:0];
[self.view addConstraint:constraint2];

Strange navigation controller behavior

I have a view that is pushed onto navigation stack like this:
FriendsDetailViewController *detail = [[FriendsDetailViewController alloc] init];
detail.user = selectedUser;
[self.navigationController pushViewController:detail animated:YES];
Inside a view controller, I have two elements: my custom controls view, that is a view with two buttons and a label inside, and a table view. I am setting constraints to them as shown:
-(void)setupView {
self.tableView = [[UITableView alloc] init];
self.tableView.dataSource = self;
self.tableView.translatesAutoresizingMaskIntoConstraints = NO;
self.tableView.backgroundColor = [UIColor lightGrayColor];
[self.view addSubview:self.tableView];
self.controlsView = [[ControlsView alloc] init];
self.controlsView.player = self.player;
self.controlsView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.controlsView];
[self setControlsViewConstraints];
[self setTableViewConstraints];
}
-(void)setTableViewConstraints {
NSLayoutConstraint *topConstraint = [NSLayoutConstraint constraintWithItem:self.tableView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.controlsView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0];
NSLayoutConstraint *leadingConstraint = [NSLayoutConstraint constraintWithItem:self.tableView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0];
NSLayoutConstraint *trailingConstraint = [NSLayoutConstraint constraintWithItem:self.tableView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0];
NSLayoutConstraint *bottomConstraint = [NSLayoutConstraint constraintWithItem:self.tableView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0];
[self.view addConstraints:#[topConstraint, leadingConstraint, trailingConstraint, bottomConstraint]];
}
-(void)setControlsViewConstraints {
NSLayoutConstraint *top = [NSLayoutConstraint constraintWithItem:self.controlsView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.topLayoutGuide attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0];
NSLayoutConstraint *leading = [NSLayoutConstraint constraintWithItem:self.controlsView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0];
NSLayoutConstraint *trailing = [NSLayoutConstraint constraintWithItem:self.controlsView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0];
NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:self.controlsView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:30];
[self.view addConstraints:#[top, leading, trailing, height]];
}
But by the end I get unexpected result.
Firstly, my custom controls view is black, although in code the background color is set to white. Secondly, custom controls view is situated just as I expected, but my table View is messed up. Somehow it does not sit on the bottom of my controls view.
I have other view controller without an embedded navigation controller, and the layout is just fine.
It seems like I don't catch how navigation view is embedded in my view controller. I do the whole project without Interface builder, and this strange behavior is really confusing.
Since iOS7, view controllers set scrollViews insets if there's a navigation bar, to make the content go behind the blurred bar (see https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/index.html#//apple_ref/occ/instp/UIViewController/automaticallyAdjustsScrollViewInsets)
so to fix your tableView you just need to set self.automaticallyAdjustsScrollViewInsets = NO
For the color of the other view, it's weird, but nothing in the code you posted changes the backgroundColor, are you sure you're setting it somewhere else?

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.

Resources