Sorry for the title if it's not the best but I really don't know how to explain this in a few words.
So, what I have is a view with a label and a image. There are two casses. One in which I don't need the image, just the label(the most ussual one). And one where I need both the image and the label and at some point I have to remove the image through an animation(this one is handled).
Now. for the one where I need just the label I was thinking to play with the constraints. I want to have the spacing for the left 15 and the constraint to go to the superview, but also when there is a image I want the constraint to go to the image. I'll add a image to make it more clear. How can I accomplish this?
Actually you can do the same thing from the XIB also.
Select the leadingConstraint outlet from the XIB and create the outlet for the constraint.
It will create a property of type NSLayoutConstraint, then set the value to 0 in case where you don't want to show ImageView
self.imageViewLeadingConstraint.constant = 0;
Repeat the same process for ImageView Width also.
For that you should bind (Take #IBOutlet) UIImageView's width constrains AND leading constrains and you need to manage it in cellForRowAtIndexPath like
if isOnlyLabel { // "isOnlyLabel" it's just for understanding
// Here you have only label not image
// Set image with constraint = 0 and leading = 0
}
else {
// Here you have label + image
// Set image with constraint = 60 and leading constraint = 15 Or as you want
}
Related
I'm trying to get a rounded UIImageView but it seems to render differently on different devices;
Looks like this on an iPhone Xr:
Looks like this on an iPhone 7:
I have a height constraint of 60 and the following code:
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
self.userAvatar.layer.cornerRadius = self.userAvatar.frame.height / 2
self.userAvatar.layer.masksToBounds = false
self.userAvatar.clipsToBounds = true
self.userAvatar.layer.borderWidth = 0
}
Any ideas?
It seems to me that you have given the image leading and trailing constraints instead of a fixed width.
To achieve a circle give image view width equal to height.
This happens due to different widths of devices.
If you're managing this view using Interface Builder (i.e. Storyboard or XIB), you can enforce a square shape (which becomes a circle when combined with the rounded corners you already have) for the view directly from there by defining a constraint for its Aspect Ratio. No need to code anything.
Control-drag (like you do to create Outlets, Actions, etc.) from the image view to itself, and the following popup will appear.
Select Aspect Ratio, which will create a constraint matching whatever the view's current ratio is (in this example, it's 15:8). If the view was already square, the constraint created should already be correct.
If not, you can find that constraint by clicking the following icon (for the Size inspector):
From there, you can double-click on that constraint to edit it, and change the Multiplier to 1:1:
In fact, an even easier option is, once you've Control-dragged from the view to itself, hold down Alt/Opt and the option displayed in the popup will change to Aspect Ratio (1:1), meaning you can set it directly from there without even having to edit the constraint.
Constrain the height equal to the width.
And, create a simple UIImageView subclass:
class RoundedImageView: UIImageView {
override func layoutSubviews() {
super.layoutSubviews()
layer.cornerRadius = bounds.height / 2
}
}
The frame can (and will) change based on view lifecycle. By updating the cornerRadius in layoutSubviews() it will keep it "round".
I want the DecriptionLabel (the Lorem Ipsum one) to have all the text inside it visible. As you can see, it is getting trimmed.
The two buttons should be under everything else, but in the case where DescriptionLabel contains a small text, the buttons should stick to the bottom of the view.
This is why I chose a >= 20 distance between the buttons and DescriptionLabel if it makes any sense.
How can I solve the trimming of the text?
Thanks.
I was originally answering How to make button stick to bottom of scroll view if the content isn't large enough? but since it is marked as duplicate of this one I am posting my answer here. Please try to set your constraints the following way: https://imageshack.com/a/img923/6671/Txzu98.png
The trick is that you set Button.Bottom Equal To ContainerView.Bottom with lower priority (I use 750) than Button.Top Greater Than Or Equal To Label.Bottom (Here I use default 1000)
The Label has to have number of lines set to 0. The height of the button should be set by height constraint (in this case is 50). The Container View Height constraint should be with low priority (in this case 250)
You should run the code to see actual result on device or simulator. Storyboard shows it a bit differently. For the current question:
https://imageshack.com/a/img923/7276/tQeT0h.png The basic idea is the same. Button Down has the same constraints as Button from above answer without Button.Top Greater Than Or Equal To Label.Bottom. There should be fixed vertical constraint between Button Up and Button Down. I am setting Button Up with fixed Height and setting trailing and leading constraint equal to trailing and leading of Button Down. The constraint Button.Top Greater Than Or Equal To Label.Bottom is now Button Up.Top Greater Than Or Equal To Label.Bottom
Have you set numberOfLines for label to 0 (that means autosize the label according to its text length)?
You should add the following constraints:
(following in sudo code)
// Constraints for ScrollView
scrollView.top = ViewController.view.top
scrollView.leading = ViewController.view.leading
scrollView.trailing = ViewController.view.trailing
scrollView.bottom = ViewController.view.bottom
// Constraints for View
view.top = scrollView.top
view.leading = scrollView.leading
view.trailing = scrollView.trailing
view.bottom = scrollView.bottom
// Width of view
view.width = ViewController.view.width
Now you just need to make sure you have layout constraints for each child of the 'view' and it's height will be correct and display the full size of the textview.
Add the following constraint:
scrollview.contentview.height >= safearea.height
This may show an error in interface builder but works in my tests:
To remove the design time error you could set a design time intrinsic content size for the scrollview's contentview (in my case I used the safe area's height of 554):
Another option (without placeholder values in IB) is to create the following constraint...
scrollview.contentview.height = safearea.height
... and change its priority to a value lower than the label's vertical content compression resistancy.
I wanted the "number" & "status" to display on the left if there is not QRCode display (constraints has been set for image & labels.)
Result without QRCode:
.
The result with QRCode will be:
IT IS very easy just make width Constraint of QRcode image, if QR code is not available than make widht constant = 0,
#IBOutlet weak var width: NSLayoutConstraint!
if (your condition)
{
width.constant = 0
}
else
{
width.constant = 30
}
You can do that with a second pair of constraints attached to left side of a view.
Add outlets to that constraints and set constant value to desired offset(from code), if there is no QRCode View.
Another way is to add MoreThanOrEquel constraint to left side (e.g >= 10)
Than another constraint with constant value 10, but with lower priority.
When you remove QRCode view, it will destroy it constraints and constraints to left side will affects and move yours labels to left.
You could make constraint for labels that way:
I.e. make constraint for image leading to left side + image width, both labels also have leading to left side. Then if there is no QR Code adjust labels leading constraints to value you need.
Or you could make both labels leading to image view and set the image view width constraint to 0.
This Problem is very simple , can achieve using UIStackView just making hide/Show.
For Ex: If QR-code is present show or else hide QR-Code.
Label (Number and status and image) will automatically get adjust. Following is the screen short for better understanding.
IBOutlet UIView *qr_view; // Image or View
Case 1 :QR Present
qr_view.hidden = NO;// Show
Case 2: QR Not Present
qr_view.hidden = YES;// hide
I have Imageview and UIView on View Controller. If Imageview is nil or image is not available then UIView replace its postion.Do any know how is it possible using auto layout?
For trying purpose, I have fixed height and width of both(Imageview and UIView). Imageview have "top 8 pixel" and "Horizontally in container" margin. UIView have "top 0 from Imageview" and "Horizontally in container" margin. Set Imageview to nil but it doesn't work.
A good suggestion would be to add both of the image view and the view in a stackView and follow the steps mentioned in: UIStackView Distribution Fill Equally.
However, you can achieve what are you asking for by adding additional constraint between the bottom view and the top layout guide:
and then, set its priority value to be less than the default (1000) -in my example I set it to 500- and the its constant value to 0:
Its appearance should be displayed as dotted line, meaning that there is another constraint -with a higher priority value- deciding the x axis of the view, if this constraint has been removed/deactivated the dotted one should be activated.
Finally, make sure that if there is no available image you have to remove image view from its super view (call imageView.removeFromSuperview()), setting it as hidden or setting its alpha to 0.0 doesn't activate the dotted constraint:
class ViewController: UIViewController {
//...
#IBOutlet weak var imageView: UIImageView!
// I'm checking in 'viewDidLoad' method just for describing purposes,
// of course, you can do the check when needed...
override func viewDidLoad() {
// if there is something wrong, you should call:
imageView.removeFromSuperview()
}
//...
}
The output would be:
Take the outlet of height constraint of UIImageView and do below code
if (imageview == nil){
imageViewHeightConstraint.constant = 0
}
else{
imageViewHeightConstraint.constant = 60
}
And other query you can ask.
You can manage this by giving priority to the constraints using auto layout. Give your UIView top space from ImageView and the TopLayout. Assign a lower priority to the constraint (any value less than 1000) where you have given top space from top layout guide. If your image is nil , remove the image view from the view using imageview.RemoveFromSuperView(), the UIView will automatically take the next constraint i.e. from TopLayout guide. I am attaching a screenshot where to find the priority of the constraint on storyBoard.
I have a view that I am making hidden at the bottom of the screen, and want the scrollView above it to adjust and fill the void space.
The view at the bottom of the screen is a GADBannerView and has a fixed height of 50 (bannerHeight). The scroll view above it has a constraint to the bottom of the container that equals 50 (scrollConstraint). See photo.
In viewDidLoad is am setting these constraints to the following:
bannerHeight.constant = 0
scrollConstraint.constant = 0
This is causing the bannerView did disappear but the scroll view is staying in it's original position and not filling the void space.
You can force the superview to take into account the change of the constraint because this does not happen automatically. Add your code to viewDidLayoutSubviews() instead or simply call view.layoutIfNeeded() after you set the constants to 0 in the viewDidLoad().
If this does not work, you can try this alternative approach:
Go to your Storyboard and click on the scroll view's bottom constraint (the blue line that gives the scroll view its bottom constraint of 50). In the Attributes Inspector you should be able to see details about your constraint, it should look something like this
In the field that asks for an Identifier, give it the name "ScrollViewBottom" or whatever name you like.
Now loop over all the constraints that make up your scroll view and use the identifier name to find the correct one and change it's constant as follows
for constraint in yourScrollView.superview!.constraints {
if constraint.identifier == "ScrollViewBottom" {
constraint.constant = 0
}
}
Finally, force the view to take into account of this change by calling the following straight after
view.layoutIfNeeded()