i need to create a custom footer for a section within a table view. The footer contains a text (label) and a button underneath it.
The problem is that the text has a different length in different languages. How can I create the footer with a dynamic height based on the content from the label?
Thx!
You can determine the height of the footer view by calculating the estimated size of the label according to the text inside of it, adding the height of the button and adding perhaps another small value for padding.
Here's a Swift example:
let theLabelFont = UIFont.systemFontOfSize(FONTSIZE)
let labelRect = (yourLabelText as NSString).boundingRectWithSize(CGSizeMake(LABEL_WIDTH, CGFloat.max), options: .UsesLineFragmentOrigin, attributes: [NSFontAttributeName:theLabelFont], context: nil)
let footerHeight: CGFloat = labelRect.height + (YOUR_BUTTON).frame.height + somePaddingValue
Then simply return it in the heightForFooterInSection: method.
Related
I understand that this question has been asked here, but it didn't solve my problem as the link in the accepted answer is down and the minimal example didn't help.
Here is a picture of my custom UITableViewCell & all its constraints:
Each post contains these UI elements. The only element that could make each cell's height different is messageView, because its height depends on the string being displayed. Question is, how do I dynamically set each cell's height? Here's what I have now (Does NOT work, messageView is not shown at all):
func cellForRowAt(indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(...) as! PostCell
let message = ...
cell.messageView.text = message
return cell
}
func heightForRowAt(indexPath: IndexPath) -> CGFloat {
var cellMinimumHeight: CGFloat = 120
if let cell = tableView.cellForRow(at: indexPath) as? PostCell {
let size = cell.messageView.sizeThatFits(cell.messageView.frame.size)
cellMinimumHeight += size.height
}
return cellMinimumHeight
}
in heightForRowAt function, the if is not being executed, therefore, all cells' heights are cellMinimumHeight = 120.
How could I make each cell's height = 120 + messageView's height?
---------------------------------EDIT 1---------------------------------
Made a mistake in the picture, messageView's height is not set
When using Auto-Layout for dynamically sizing cells, you don't really need to implement sizeThatFits(...). If the constraints are setup correctly, then you only need to disable the scrolling of the UITextView.
From code:
yourTextView.scrollEnabled = false
From IB:
Select your Text View and open Attributes inspector, then
In Attributes Inspector select your UITextView(messageView) and Uncheck "Scrolling Enabled".
And then change your UITextView(messageView)'s content compression resistence priority as follows:
Horizontal = 750
Vertical = 1000
I hope this will help you.
Just disable UITextview scroll...
But here is no use of UITextview, you can use label also.
In HeightForRow tableview delegate method remove that stuff and use
return UITableViewAutomaticDimension
You have used constrain to make cell hight dynamic
form apple documentation
To define the cell’s height, you need an unbroken chain of constraints
and views (with defined heights) to fill the area between the content
view’s top edge and its bottom edge.
So for your case you need
cell's height = 120 + messageView's height?
So start from Profile Image to measure unbroken chain of constraints from Top to Bottom
Profile Image top = 10 + ImageHeight = 60 ----> 70
MessageView top = 10 + set minimum height to message say 20 one line if every cell should have message even if one word and set this height Greater than or equal to 20 make sure that you set Scroll enable = false
so message Height minimum = 10 top + 20 + 10 bottom ---> 40
Menu Stack view Height ---> 30
So all Total = 70 + 40 + 30 = 140 this default hight no cell will be less than this
Also you must set the table view’s rowHeight property to UITableViewAutomaticDimension. You must also assign a value to the estimatedRowHeight property
tableView.estimatedRowHeight = 130.0
tableView.rowHeight = UITableViewAutomaticDimension
Here is apple documentation Here
I have to create a UI which has 3 UICollectionViewCell in a row. So i created it using UICollectionViewController, with section = 1 and no of rows = coming from api. So i was able to create 6 cells in which every row contains 3 cells. These cells are separated by 0.5 pt vertically and horizontally.
I have given the background color to collectionView which comes in separator.
In particular this is what i need :-
Problem :-
This is the type of UICollectionViewController requirement i have
The separators needs to be red, and the space not rendered needs to be yellow. But I am unable to do that, I can have a single background color for UICollectionView which shows for both separator and free space. Is there a way to have different colors.
I dont want to use UITableView and have a UICollectionView inside UITableViewCell. I know this approach but i want to do the same in UICollectionViewController.
If I understand your question right, you can solve this by removing the space between the cells. Remove the 0.5pt space entirely. Then, all cells will be glued to each other, and you can create your own separators inside each cell. It'll require some logic though, because all cells should not use the same separators (if you do, then the center cells will have double separators on each side).
To achieve your photo, you could set these rules:
The first and the last cell in each row should only show a separator on bottom.
All the other cells in between (in your case, one cell in between) should show separator on bottom, left, and right.
To add these separators, just go into your custom UICollectionViewCell and add some UIViews to each side, and set them to have a width of 0.5pt, and set them visible on demand.
I would suggest a custom cell as Sti suggested. I usually do that. but an easier way would be:
To add a subview to the collectionView every time you reload data of
the collection view.
Code:
let count: CGFloat = CGFloat(items.count)
let numberOfRows: CGFloat = ceil(count / 3.0)
let height: CGFloat = numberOfRows * (cellHeight + seperatorHeight)
if collectionBackView != nil { // controller member object
collectionBackView.removeFromSuperview()
}
collectionBackView = UIView(frame:
CGRect(x: 0, y: 0, width: collectionView.frame.size.width, height: height))
collectionView.addSubview(collectionBackView)
collectionView.sendSubview(toBack: collectionBackView)
I just found out about UIStackView, and I'm trying to see if it can finally make it easier to lay out expanding content.
Specifically, I want to do the following:
|-- UITextView ------------|
| some dynamic text here, | I want the text view's height to change
| it could be short, or it | depending on the height of the text
| could be tall | (set later, in code)
|-- UIView ----------------|
|xxxxxxxxxxxxxxxxxxxxxxxxxx| I want this view to expand to fill the
|xxxxxxxxxxxxxxxxxxxxxxxxxx| vertical space.
|xxxxxxxxxxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxxxxxxx| It should start right below the
|xxxxxxxxxxxxxxxxxxxxxxxxxx| bottom of the UITextView
|xxxxxxxxxxxxxxxxxxxxxxxxxx|
|--------------------------|
I think I know how to do this with regular constraints. Is it possible to do with UIStackView? I might be understanding the purpose of UIStackView, but I would love to be able to create layouts like this more easily.
When I put both of these into a UIStackView, Interface builder says "Needs constraints for: Y position or height" for both views.
Programmatically it looks like this:
#IBOutlet private var stackView: UIStackView!
{
didSet {
stackView.addArrangedSubview(titleTextView)
stackView.addArrangedSubview(UIView())
}
}
lazy var titleTextView: UITextView =
{
let textView = UITextView()
textView.isScrollEnabled = false
return textView
}()
You don’t need anything else for the UITextView to expand automatically. This shouldn’t complain about ambiguities.
You can add a stackview then inside that add a textview, then set scrollable false, it will automaticaly handle your problem
Calculate the text height in textview add a height constraint on uitextview say 20 and when you calculate the height just change the height constraint.Give the below view constraint of top 0 from textview and you issue will be resolved.
Calculate height using this function
let height = string.boundingRectWithSize(CGSizeMake(CGFloat.max,textviewwidth), options: .UsesLineFragmentOrigin, attributes: [NSFontAttributeName: font!], context: nil).size.height
Try using an UILabel with lines = 0 instead of an UITextView.
I am trying to get the content height of an UITextView for calculating the bottom position of it (y position + height).
I can get the y position just fine with
travelDescriptionTextView.frame.origin.y
and need to determinate the height. All over the internet it says to get the content height with:
let contentSize = self.travelDescriptionTextView.sizeThatFits(self.travelDescriptionTextView.bounds.size)
let height = contentSize.height
but this technique doesn't work when height is resized (extended) by word wrapping, that is, if a sentence is wider than the width of the text box and the textbox creates a new line automatically. The above technique for getting content height only get the height right if there is no word wrapping, or else the height is excluding the extra word wrapping lines causing the content height to be shorter than the actual content height.
So how do I get the content height of a UITextView containing word wrapping height resizes?
Try like as follows,
let textViewComputedHeight = textView.contentSize.height - textView.contentInset.top - textView.contentInset.bottom
Thanks to RDC for the link. The working solution is:
self.travelDescriptionTextView.sizeToFit()
self.travelDescriptionTextView.layoutIfNeeded()
let contentSize = self.travelDescriptionTextView.sizeThatFits(self.travelDescriptionTextView.bounds.size)
let textViewHeight = contentSize.height
Right now, I'm using the following code to display my table cell. It is displaying text properly. However, there are some texts which are too long, so I want to display the first 5 lines of the text and then if the user expands the cell, it will display the whole text. I'm stuck because I am not so familiar with the new method in ios 7, boundRectWithSize.
CGSize size = CGSizeMake(self.reviewComments.width,999);
CGSize textRect =[self.reviewComments.text boundingRectWithSize: size options: NSStringDrawingUsesLineFragmentOrigin
attributes: #{NSFontAttributeName:self.reviewComments.font} context: nil].size ;
float height = textRect.height;
self.reviewComments.height = height;
I tried:
if (height > 150) {
height = 150;
}
But this way just cuts off the text, even after when I expand it.
UPDATE/EDIT:
I want my cell so that it only displays maybe the first 5 lines of the text if it exceeds 5 lines. The entire text will appear if the cell is expanded.
Try this:
float height = ceilf(textRect.height);