I am experiencing a very strange phenomenon. I am using the AutomaticDimension function on my tableview and for some odd reason it works on all of my cells except for 3. All of my cells have the exact same constraints which is the weird part. I have tried changing the constraints on the cells but it appears that they are being ignored. Any insight would be great. I make sure to call the auto dimension function in viewdidload.
override func viewDidLoad() {
super.viewDidLoad()
self.TableView.dataSource = self
TableView.estimatedRowHeight = 200.0
TableView.rowHeight = UITableViewAutomaticDimension
}
Here is one of the classes that is not working:
class foursleepCell: UITableViewCell {
#IBOutlet weak var foursleepLabel: UILabel!
#IBOutlet weak var foursleepScale: UISegmentedControl!
var delegate: foursleepCellToController?
#IBAction func foursleepValueChanged(_ sender: UISegmentedControl) {
if let delegate = delegate {
let indexPath = delegate.indexOfChangedfoursleepCell(at: self)
delegate.savefoursleepCellResponse(at: indexPath, response: foursleepScale.selectedSegmentIndex)
}
}
}
Attached are images of constraints and output:
Label Constraints
Segmented Control Constraints
Actual Output
Working Output
I don't think there is anything wrong with the way you are trying to set the cell to automatically resize, it is just the fact the the top-to-bottom constraints that are required for that resizing to happen are not present at runtime. Apparently this is something that can happen sometimes in Xcode - try creating a new table view cell and setting up all the views and constraints again from scratch. Copying and pasting the table view cell into a new cell and working from the copy did not fix it for me - it behaved exactly the same. But setting it up fresh did the trick.
Related
My UITable's last row is getting cut off.
Code
#IBOutlet weak var listTableView: UITableView!
var feedItems: NSArray = NSArray()
var selectedFood: foodItem = foodItem()
override func viewDidLoad() {
super.viewDidLoad()
//set delegates and initialize foodModel
self.listTableView.delegate = self
self.listTableView.dataSource = self
self.listTableView.estimatedRowHeight = 115
//self.listTableView.rowHeight = UITableViewAutomaticDimension
let FoodModel = foodModel()
FoodModel.delegate = self
FoodModel.downloadItems()
}
When I tried to add the line, self.listTableView.rowHeight = UITableViewAutomaticDimension. It gives me something strange
I know this question has been asked multiple times, but none of the solutions was fitting for my problem. Thank you!
You have to set proper layout constraints from your labels to all edges of the cell.
If all of the labels can have fixed height of one row, you can set a height constraint also.
If any of the labels can have multiple rows you'll have to set priority, content hugging etc.
Look it up: https://www.appcoda.com/learnswift/auto-layout-intro.html
When using auto-layout and the Navigation Controller, be sure that the constraint for Table View.bottom is equal to Bottom Layout Guide.top, and not with the View. That was my problem.
I have the structures below...
I wrap two of collection views into tableview
One is in tableview header(Collection1), another is in tableview 1st row(Collection2).
All the functions are good (Both collection view).
just...
When I scroll up in Collection2, Collection1 will Not scroll up together, because I'm only scrolling the collectionViews not the tableview.
It only scroll together when I scroll in Collection1.
Is it possible to make the header view scroll with user just like app store's index carousel header?
Or I just went to the wrong place, I should use other ways to approach.
Solution
When you keep CollectionView1 as a TableViewHeader, CollectionView1 will always on the top of TableView after it reaches top. If you want Collection1 and Collection2 scroll up together, you need to keep CollectionView1 in a cell, not a header.
Make sure CollectionView2 content height smaller or equal to TableViewCell's height. As I checked on App Store, they always make SubCollectionView content height equal to TableViewCell's height (If they use TableView).
Result
For more detail, you can take a look at my sample project
https://github.com/trungducc/stackoverflow/tree/app-store-header
Problem
1) Your tableview cell Collectionview (let's say collection2) , Collection 2 is scrollable. So when you scroll up tableview won't scroll up
Solution
1) Just simple and working solution would be height constant , You have to give height constant to the collection2 with >= relationship and 0 Constant value and 750 priority !!
Now the question is how to use this
You need to take IBOutlet of Height constant to your custom tableview cell and need to manage the collectionview height from there.
Here is example
class FooTableViewCell: UITableViewCell {
static let singleCellHeight = 88;
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var descriptionLabel: UILabel!
#IBOutlet weak var iconsCollectionView: IconsCollectionView!
#IBOutlet weak var const_Height_CollectionView: NSLayoutConstraint!
var delegateCollection : TableViewDelegate?
var bars:[Bar] = [] {
didSet {
self.iconsCollectionView.reloadData()
iconsCollectionView.setNeedsLayout()
self.layoutIfNeeded()
let items:CGFloat = CGFloat(bars.count + 1)
let value = (items / 3.0).rounded(.awayFromZero)
const_Height_CollectionView.constant = CGFloat((iconsCollectionView.collectionViewLayout as! UICollectionViewFlowLayout).itemSize.height * value)
self.layoutIfNeeded()
}
}
override func awakeFromNib() {
iconsCollectionView.translatesAutoresizingMaskIntoConstraints = false
iconsCollectionView.initFlowLayout(superviewWidth: self.frame.width)
iconsCollectionView.setNeedsLayout()
iconsCollectionView.dataSource = self
iconsCollectionView.delegate = self
const_Height_CollectionView.constant = iconsCollectionView.contentSize.height
self.layoutIfNeeded()
self.setNeedsLayout()
}
}
You can check my answer Making UITableView with embedded UICollectionView using UITableViewAutomaticDimension Very similar and 100% working
Another solution You can also take UICollectionView with sections which contain another horizontal collectionview , with this solution you don't need to manage contentsize for every cell
Hope it is helpful
I have a custom table cell where two labels are on top of an image, though are not appearing when I run the app in the simulator. When I comment out the image, I see the labels just fine.
I have auto-layout set, pinning the image to the top, bottom, left, and right of the super view. I also have the labels pinned to left and right edges of the superview, and vertical spacing between them and the bottom edge of the superview to the bottom label.
If the image is included, however, I don't see the labels at all. I'm sure they're above (i.e. they come after) the image in the scene explorer at the left.
Any ideas? Here's what the custom cell looks like:
I've tried deleting all constraints, running without using Auto-layout at all, re-adding constraints several times... nothing seems to work.
My UITableView class is as follows:
class CustomCell: UITableViewCell {
#IBOutlet weak var name: UILabel!
#IBOutlet weak var location: UILabel!
#IBOutlet weak var cardImage: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func setProperty (name: String, location: String, cardImageName: String) {
self.name.text = name
self.location.text = location
self.cardImage.image = UIImage(named: cardImageName)
}
}
I've also done println in the cellForRowAtIndexPath function, and the name and location are populating properly from the array... which I already knew, as they populate properly when the image is commented out. Maddening!
Here's how the labels and image are stacked:
Thanks in advance for any help!
Here's an interesting problem I'm trying to solve.
I want to use a single cell that is configured in storyboard for different cell configurations by removing stuff I don't need from the cell.
Here's how to cell is constrained.
Basically, if I don't need image for the step (or the red view) I just remove it from cell, and everything aligns dynamically just perfect, and I do not have to calculate cell height or do any coding. However, since I have to reuse the cells, when I get the cell for the next row I do not have that view. I can add it again to cell, but I loses all of the constraints.
In case you need it for ideas, here's some code:
class RecipeStepTableViewCell: UITableViewCell {
#IBOutlet weak var preparationLabel: UILabel!
#IBOutlet weak var stepNumberLabel: UILabel!
#IBOutlet weak var stepImageView: UIImageView!
#IBOutlet weak var stepTextLabel: UILabel!
#IBOutlet weak var stepTimerView: UIView!
override func awakeFromNib() {
super.awakeFromNib()
}
}
And this is how I handle it it cellForRowAtIndexPath:
let cell = tableView.dequeueReusableCellWithIdentifier("RecipeStepCell", forIndexPath: indexPath) as RecipeStepTableViewCell
let step = stepForIndexPath(indexPath)
if step.image == nil {
cell.stepImageView.removeFromSuperview()
}
// etc.
I really like this approach since I don't have to build 10 cell configurations, and all I need is to force it to create a new cell for each row.
By the way, the view will only have 5, 6 cells so performance shouldn't be an issue.
It seems like removing the image is deleting all the constraints associated with it.
I have an idea. Instead of removing the image, you can just adjust constraints when step.image == nil, since the image will be invisible anyway.
This would be done by using storyboard to connect IBOutlets to the constraints. It would look like this:
#IBOutlet weak var constraintToTop: NSLayoutConstraint!
And then later to adjust it,
let cell = tableView.dequeueReusableCellWithIdentifier("RecipeStepCell", forIndexPath: indexPath) as RecipeStepTableViewCell
let step = stepForIndexPath(indexPath)
if step.image == nil { //Set constraint(s) so imageView takes up no space
cell.constraintToTop.constant = 0
}
else { //Go back to original constraints
cell.constraintToTop.constant = 50
}
This may require creating many IBOutlets for your constraints to get the desired result, but this is the general idea.
I hope this helps you.
I use an UICollectionView in my first app. My problem is I can't get the number of column (or line) calculated in the UICollectionView.
The UICollectionView is inside an UIScrollView, and I want to set the height of the UICollectionView because I don't want to scroll in the UICollectionView but I want to see all the items.
Is this possible?
Thanks,
F.G
After many researches I found the solution:
I don't need to know the number of column or line in the collection view if I want to fix the height.
The height of the collection view can be updated automatically:
Add a height constrain to the collection view
Add the CollectionView and the constrain as outlets in the ViewController:
#IBOutlet weak var heightConstrainCollectionView: NSLayoutConstraint!
#IBOutlet weak var myCollectionView: UICollectionView!
After the view Load, update the height of the CollectionView:
override func viewDidAppear(animated: Bool) {
super.viewDidLoad()
heightConstrainCollectionView.constant = myCollectionView.contentSize.height
}
If the user rotate the device, update the CollectionView's height:
override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
heightConstrainCollectionView.constant = myCollectionView.contentSize.height
// Add this if you want to see the height after rotation
println("New Width: \(newspaperCollectionView.contentSize.height)")
}
Now I can't scroll in my CollectionView and the CollectionView show all the items