I have got a view and some elements in it
let background_img_view: UIView = {
let view = UIView()
return view
}()
background_img_view.addSubview(background_image)
background_img_view.addSubview(border)
background_img_view.addSubview(about_txt)
about_txt size is unknown, it can be 30px or 300px, now I want my background_img_view's height to depend on about_txt's height.
How can I make it happen programmatically?
Have you tried using the sizeThatFits(_:) method for the about_txt view. Use the size that this function returns and set the superview's size to that.
https://developer.apple.com/reference/uikit/uiview/1622625-sizethatfits
If you have the subviews added before the view is on the screen, you could set the height in the viewWillAppear method of your view controller. You can also update the size in viewWillLayoutSubviews.
If you're using auto layouts, have a look at setNeedsLayout vs. setNeedsUpdateConstraints and layoutIfNeeded vs updateConstraintsIfNeeded
Related
I'm using Storyboard with autolayout. In my ViewController I have a basic structure: one UIScrollView and one contentView (UIView) that contains different labels). Then I have different elements that I add in the viewDidAppear method of the class inside my contentView , then in order to recalculate it's frame size I do this:
- (void)fixContentViewHeight
{
_contentView.frame = CGRectMake(_contentView.frame.origin.x, _contentView.frame.origin.y, _contentView.frame.size.width, operators.frame.origin.y + operators.frame.size.height);
//constraint for contentView height
_contentViewHeight.constant = operators.frame.origin.y + operators.frame.size.height;
}
- (void)fixScrollViewHeight
{
_scrollView.frame = _contentView.frame;
_scrollView.contentSize = _contentView.frame.size;
}
where operators is the LAST placed element of contentView, it's always on the bottom of the frame. I call these 2 methods inside the viewDidAppear and they make the view scrollable, the problem is that the frame of contentView doesn't get updated so the last elements are always unclickable (because they're placed outside the frame of the view).
What am I doing wrong? Why the scrollView becomes scrollable but the contentView keeps it's old frame?
If you have autolayout constraints affecting the height of _contentView You will not be able to change its height by setting the frame, as the constraints will override that.
You will need to (and should be) adding new / modifying constraints in your code when you are adding new elements. then calling
_contentView.layoutIfNeeded()
After all the updates to let the UI update if it needs to, which it should.
Please update UI On Main Queue
dispatch_async(dispatch_get_main_queue(), ^{
// update any UI on Main queue
});
I think that all your frame related information should be inside viewWillLayoutSubviews() and viewDidLayoutSubviews(). You can add stuff in viewDidLoad() but for any frame management I would use mentioned methods.
In your particular situation use former, viewDidLayoutSubviews(). However, you can resolve these kind of issues using constraints connected to the code as #Simon McLoughlin mentioned. 'scrollView becomes unscrollable' means that you should update contentSize as well so keep an eye on that as well.
Try to add vertical space constraint between scroll view and your last placed element.
how to expand the view width after loading ios?
I have a view that will be initialized with self.view.bounds
I want this view to have another frame after loading how can I do that?
FYI this view is a sub view of Scrollview.
So I am initializing a view, that is subview of a scroll view, inside a view.
If you are using storyboard and autolayout,
Update constants of width constrain of the view. You can create directly IBOutlet of the constraint and
int desiredWidth = 150;
_modifyViewWidthConstraint.constant = desiredWidth;
If the views are created programatically, then simply change the frame
modifyView.frame = CGRectMake(modifyView.frame.origin.x, modifyView.frame.origin.y,desiredWidth,modifyView.frame.size.height);
Keeping all its x,y and height same as previous.
If you are using Auto Layout on view and given width constant to view then change property of that constant,change relation from == to >= and change priority from 1000 to 250.Hope it will work you.
I create a view called boundView using IB and Auto Layout,then in the controller I call [self.boundView layoutIfNeeded],then I pass self.boundView.frame.size to a method to generate the size of boundView's subview CardView. And then use the
PlayingCardView *playingCardView = [[PlayingCardView alloc]initWithFrame:frame];
to create subview programmatically. I do use NSLog to check that the size of subview is smaller than superview. But when I use [self.boundView addSubview:CardView] to add the subview. It is larger than superview!
Is there something wrong with the coordinate?Or it is because I combine the Auto Layout with the view I create by code?
Where are you doing this? If it is in viewDidLoad then the autolayout sizes will not have been calculated yet. Try doing it in viewDidLayoutSubviews.
I subclassed UIView: http://pastebin.com/MVk1XmPS and when I add it to another view of a UIViewController:
self.myView = MyView.newAutoLayoutView()
self.myView.backgroundColor = UIColor.redColor()
self.view.addSubview(self.myView)
the red background is missing. It seems that myView has no width and height. However the content is visible:
I have to hard code the dimension:
self.myView.autoSetDimensionsToSize(CGSize(width: 100, height: 100))
but shouldn't it grow automatically by the size of the content? I use swift, xcode6.1 and iOS8.1
Views do not automatically grow to fit their content. If you enable clipsToBounds on your view, you will see the content disappear. Alternatively, if you put a button as part of your content, you will see it but be unable to interact with it because it is outside of its superview's bounds.
In your subclass, you could implement the sizeToFit or sizeThatFits: methods, but these are not going to be automatically called by the system. You should consider assigning constraints for your view in your storyboard. If you're not using a storyboard, you will need to assign a frame in your viewWillLayoutSubviews or layoutSubviews method.
Storyboards will also like your custom view better if you implement intrinsicContentSize.
I have a UIView that is a footerview of a uitableview. At run time, the user enters text into a uitextview within the footerview that should adjust to the size of the text content with a height constraint in autolayout.
All other objects in the view (labels, imageviews) have appropriate constraints to accommodate the expansion of the textview.
HOWEVER the height of the overall footerview will not change size, and it is impossible to use autolayout on the tableview footerview height.
Does anyone have a solution? Thanks
Haven't found an actual, elegant, solution yet, but I've postponed fixing this by using a workaround:
Setting the frame of the view used as a footer to be as large as you might possible need. In my case this meant giving it about 60px of spare vertical room. Since it's the footer and there's nothing below it to reposition the user won't be affected by the workaround.
The contents of the footer view are pinned to the top and have enough space to expand when needed.
For the record: my view is loaded from a nib file.
Although in theory the size one gives to the top level view in interface builder is just for design-time and the runtime size should be calculated based on constraints and the resulting intrinsic size, for this specific case I found the height stays the same as it was in IB.
We can change the height of the footer view run time by the following code:
func methodToChangeTableViewFooterHeight()
{
var footerView:UIView = self._tableView.tableFooterView! as UIView
var frame:CGRect = footerView.frame
frame.size.height = self.heightCollectionCS.constant + 10
footerView.frame = frame
self._tableView.tableFooterView! = footerView
}
Here , self.heightCollectionCS.constant is the height constraint for our Collection View.
We can use text content height on that place.
You may try to set again the footer view each time you footer height changes, to inform the table it should change the footer height. Or use inset. From within the footer view:
SetNeedsLayout()
LayoutIfNeeded()
ownertable.TableFooterView = this
Sorry about that, misread that question long ago. You can access the footer directly through the tableview's property tableFooterView.
What you could do is create your default footer in a xib or in your viewDidLoad:. Once you need to increase the size of the footer, you can pull out the UIView from that property and edit its frame if necessary to make it larger.
So make sure the tableFooterView gets assigned a UIView because it is nil by default. To just make the height taller, you can use self.tableView.tableFooterView.frame = CGRectMake(whatever rect you need);