Auto layout show button round without fixing height and width - ios

I am very new to iOS development and have never done auto layout before ,I have actually seven buttons on a view controller that needs to look round on every screen without fixing height and width....I have looked many tutorials but couldn't understand that how I can add constraints on those round buttons and show them at same position on every screen. I want the buttons to actually increase size when screen increase and decrease when screen size decreases.Please help and show which constraints should be added.!this shows how buttons are added on my view controller

If you want perfect round buttons(circle) then width and height should be same. For that set the aspect constraint with multipler 1:1 so that width and height will become equal.
Based on the the screenshot you have provided, see below how the constraints should look like:

Well, two points:
Position: Well, you need understand accurately ‘same position in every screen’, I guess you know view.frame = CGRectMake(10, 20, 50, 50)but same code not lead to 'same position' in different screen, important thing is which way you want. Think about a increasing screen, you have a square on it, what do you want this square change? Different change style lead to different code.
Size: You said you want square increasing or decreasing with screen, the basic way is let square.width && square.height changing with screen, if use frame layout you may write view.frame = CGRectMake(10, 20, SCWidth * 0.0666, SCHeight * 0.0833), certainly autoLayout support scale calculate, I recommend you use Masonry to add layout, sample code like:
[square mas_remakeConstraints:^(MASConstraintMaker *make) {
make.width.equalTo(self.mas_width).multipliedBy(0.0083);
}];
of course if you use xib to do it, you can see constraints have multiplier property to fix problem.

Use this code to make round button..
You can programmatically get the current height of Button and then assign the half of height to corner radius to make it round.
[self.view layoutIfNeeded];
[self.view setNeedsLayout];
self.yourButton.layer.cornerRadius = self.yourButton.frame.size.height/2;
self.yourButton.clipsToBound = YES;

Related

Why do my controls get squished inside a scroll view?

I'm building an iOS app and every time I use a scroll view and put other views and controls inside of it this happens:
How do I prevent this from happening? I tried putting the scroll view in a UIView and putting a UIView inside a scroll view and putting other controls inside of the nested views but the same thing still happens. Any ideas on how to fix this?
After you add something inside scrollView, it doesn't know what width and height it will have. Thus, it is unable to correctly display its subviews.
There are some major solutions:
You need to specify correct sizes AND distances both vertically and horizontally.
E.g. scrollView will have 1 label. Then you should specify something like this:
label 1:
leading = 20, trailing = 20, width = 100 (this will solve horizontal dimension)
top = 20, height = 100, bottom = 20 (this will solve vertical dimension)
Of course, labels are self-sizing. So if you specify the text/font/number of lines, you don't need to set fixed width and height.
You can add some view (if your layout allows that) which will take the whole width of the screen. In this case you set leading and trailing to 0, and instead of setting fixed width (which varies on different screen sizes), you need to center that view horizontally inside the scrollView.
This will solve the horizontal dimension.
Instead of using constraints use the autoresizing feature. The controls resize depending on the way they were placed on screen and what the settings on the Autoresizing is.
Autoresizing

Xcode 8.3.3 Auto Layout on Random Positioned UI Buttons

I am currently making an UI that involves multiple UIButtons in random positions. Please see the photos, I basically want the buttons to stay at where they are suppose to be (aka Pikachu's ear, Pikachu's cheek...) But when I change to a smaller device such as the iPhone SE, the buttons aren't at where I want.
I know that Auto Layout is probably the way out, and I tried adding leading, trailing, top and bottom constraints, but they never work out. I also tried setting suggested constraints, did not work. Some buttons were stretched after setting constraints...
So it really caused headache for me. Can anyone please help?
Desired Layout
UPDATE:
I have found a really easy way to achieve such layout. By unclicking default autoresizing and only select the inner constraints, the buttons can now be at where I want them to be.
Storyboard Edit
You need to add as minimum constraints like
1.) Leading
2.) Top
3.) Height, Width
The key is to change the values either programmatically.
For example,
Suppose, the screen is 320 * 480 and the button Position is to be at (100,250),
the ratios we get will be PositionX = 100/320 = 0.3125
& PositionY = 250/480 = 0.520 then programmatically set
leadingConstraint.constant = 0.312 * self.view.bounds.size.width
topConstraint.constant = 0.520 * self.view.bounds.size.height
You need to calculate these values for each button and set them accordingly.

AutoLayout Equal Heights hides Subviews

I have a UIView buttonView and gave it an equal heights constraint to the super UIView with a 0.4 multiplier. The frame is adjusted correctly but the subviews of buttonView are not visible. However, when I click on the position where the buttons are supposed to be then the actions triggers.
This does not happen when I change the buttonViews constraint to be a fixed height.
I can get more into details if you want but has anyone run into something similar?
EDIT
There should be two buttons where the white space underneath the label is. When I click on the white space the timer runs but the button is not visible.
I took a look at the project and the issue I saw in a couple places was that auto layout and manual frame transformations are both used, which can be tricky. A couple specific things I saw that you will probably need to modify in order for the view to adapt and render correctly at different sizes / orientations:
1) The CustomAudioLearn view loads a view from a xib and adds it as a subview. However, it does not set constraints on this subview to make sure that the subview always hugs the edges of the parent view. So changing the size of the CustomAudioLearn view through auto layout in the storyboard results in the the xib-based subview always staying the same size. You should either add constraints to the subview or override layoutSubviews() in CustomAudioLearn and include self.customView.frame = self.bounds and self.customViw.layoutIfNeeded() in there. Also, I would suggest removing the line self.customView.translatesAutoresizingMaskIntoConstraints = false
2) Similarly, the RecordButtonView sets its corner radius on awakeFromNib(), but after layout happens, that's no longer the right radius. So you should again consider overriding layoutSubviews() or similar location to adjust the radius every time the layout is updated.
3) Lastly, the superview of the RecordButtonView in the storyboard is set to a height constraint of 70 with a priority of 1000. If you want the RecordButtonView to expand for the space available, you should reduce the priority of that height constraint so that the proportional width of the RecrodButtonView and the 1:1 aspect ratio take priority in determining the height of the superview. Otherwise, it will always be 70 points, or there will be conflicting constraints.
The problem was that I set the rounded corners to half of my frame's width. The radius got so big that it completely hide the view. I changed it so that after the bounds are set I change the corner radius. Sorry for confusion but thanks for any help!

Change the label width dynamically inside a UITableViewCell

I am trying to build up an custom table view.
As you can see in the picture, I set the width of the label by default as 160 point in side the story board and change the width on the fly when the table is loaded. I am implementing this by modifying "cellForRowAtIndexPath" delegate method.
So based on the length of the date, I am setting the width of Label1 to maximum utilise the real estate on the phone screen.
CGFloat timeStampWidth = [cell.timestamp.text sizeWithFont:cell.timestamp.font].width;
CGFloat ksCompanyNameLableMaxWidth = 235;
NSLog(#"timeStampWidth:%f", timeStampWidth);
CGSize companyNameLableSize = CGSizeMake((ksCompanyNameLableMaxWidth - timeStampWidth), cell.companyNameLabel.frame.size.height);
CGRect newFrame = cell.companyNameLabel.frame;
newFrame.size = companyNameLableSize;
cell.companyNameLabel.frame = newFrame;
But when I load the app, all the label1s are set as 160 point as set in the storyboard although by debugging I have seen my code get executed for each cell.
To my surprise, if I scroll down and scroll back up again. The block of code is getting called again and the label is set as I wish.
Moreover, if I switch between the tabs, the label is restored to the abnormal status again.
This sounds like a consequence of auto layout -- when using it, you shouldn't set frames at all, instead you should adjust the constraints. You can make an IBOutlet to the width constraint of your label, and adjust its constant value in code.
If you are using auto layout, you can just set the x and y position, and then nothing for the height and width, and the label will correctly size itself to fit its contents. One caveat if you are using Xibs or Storyboards, don't put any text in your label in the storyboard, or it will want to size to that text. So delete the placeholder text from the storyboard, set the constraints and then you will be good to go.
You can also create and position the UILabel programatically, this way the iOS auto-layout will not interfere with your frame change.

Working with AutoLayout in Portrait and Landscape

Auto Layout, as good as it is, driving me crazy with constraints. I have the portrait mode designed in IB but I can't get the desired landscape orientation to work.
Notice that when the orientation changes to landscape, the spacing between the UIImageView blocks decreases and the text alignment of SAMPLE TEXT changes to right aligned.
Currently, I have added a few constraints for it to work. However, I need to keep the space between UIImageView blocks fixed, as a result of which it looks cramped up in portrait and fine in landscape. I need it to be spread out evenly in portrait and compress in landscape (like in image above). Similarly, currently my constraints bring up the text but it doesnot keep it at the center of screen and right aligned.
Is this possible at all with Auto Layout? If so, how? Help greatly appreciated.
There are several ways to approach this. One way is to enclose your 3 image views in a UIView. Give the top and bottom image views constraints to the top and bottom respectively, and give the middle one a centerY constraint. Give this enclosing view a fixed height and width, and a constraint to the top of the controller's view. Make an IBOutlet to the height constraint for this enclosing view, and change it on rotation. In the example below, I gave it a height of 350 in portrait:
-(void)updateViewConstraints {
[super updateViewConstraints];
if (self.view.bounds.size.height < self.view.bounds.size.width) {
self.heightCon.constant = self.view.bounds.size.height;
}else{
self.heightCon.constant = 350;
}
}
As for the label, the easiest way is to remove the constraints you have (bottom and centerX), and add trailing and centerY on rotation.
Yes, it can be done with Auto Layout. If you want the spacing between views to increase and/or decrease depending on orientation, you can use the Less Than or Equal or Greater Than or Equal relation (instead of Equal) for the constraint, which allows a distance to grow or shrink:
Play around with that and you should be able to get what you want.
Yes, it is definitely possible to do this with Auto Layout. Through a series of steps, that I think might be too long to post as an answer, you can retain the spacing between your ImageViews and keep the alignment of the text the same.
Essentially, you will have to pin a corner of each ImageView and remove some constraints so that it doesn't automatically compress the spacing when you change the orientation.
Full explanation on how to do this (pretty much exactly what you are asking for) is explained in this tuorial. You can find it about halfway through the page.
Hope this is what you were looking for.

Resources