Auto Cell Height on UITableView without overlapping bottom part of iPhone X - ios

So my goal is to achieve automatic height for my table view. What I mean by by that is whenever I add new item to the table view, the table is still "full screen" while the cell is decreasing its height.
for example this is what I've done :
on iPhone 6s Simulator
on iPhone 5s Simulator
and I've achieve that using code :
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let itemCount:CGFloat = CGFloat(items.count)
let statusHeight = UIApplication.shared.statusBarFrame.height
let navHeight = self.navigationController!.navigationBar.frame.height-statusHeight
let viewHeight = view.bounds.height
let cellHeight = (viewHeight-navHeight)/itemCount
return cellHeight
}
but the problem is that in iPhone X it was doing something like :
on iPhone X Simulator
the bottom part of the bottom item is cut/overlapped. How can I fix it?
Thank you.
Edit :
Thanks for the answer Trupesh Vaghasiya and Pankaj I've done your solution, couldn't find it but this is what I've done {Screenshot}
But the outcome was like this {iPhone X Screenshot}. Don't you think that's violates the iPhone X UI guideline?

You need to change TableView Bottom Constraint First Item Safe Area to give SupperView.
Let us know... is working?

Just change your Interface constraint relevant to superView instead of safe area. Check your tableview top and bottom Constraint and make it related to superView. but as per apple said, it is good if you make it related to safe area as iPhone X and higher version have home button on screen so. you can check bellow screen shots. Select Bottom Constraint

Select constraint that you want to change and Double Click at there.
And then select First Item and then select Superview

Related

The constraints in my tableview isn't working on my view objects. Any reason why?

I have downloaded data from a URL and wanted to display it in a table view. I've gotten the data to populate, but I can get the constraints to work on the view objects in my table view.
Here is a complete picture of my storyboard :
But this is what I end up getting in my simulator :
Does anyone understand the reason why I am getting these constraint problems? Thank you.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return pictures.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier:"PictureCell") as! PictureCellTableViewCell
cell.likeLabel.text = String(pictures[indexPath.row].likes)
cell.tagsLabel.text = pictures[indexPath.row].tags
return cell
}
Here's how to resolve the constraint issues you're having. Starting from the beginning....
Step 1: Add labels to cell.
Step 2: Embed labels in stack view.
Step 3: Pin all edges of stack view to cell.
Step 4: Almost there, we just need to resolve content hugging priority issues with labels...
]
Step 5: Lower the bottom label's Vertical Content Hugging Priority to be a smaller value than the top label. With this in place, both labels won't have to fight over who should be prioritized. The bottom label now has a lower vertical content hugging priority so it will allow itself to adjust its vertical height. In other words, the label Because of how AutoLayout works and cell resizing, this is required.
Using storyboards as an intro-iOS developer is a good starting point to visualize constraints, as constraint issues can be difficult to resolve in UIKit when done programatically.
As you progress in your understandings though you'll eventually move away from storyboards all together and layout your views programmatically.
You could also opt to learn SwiftUI and see how dealing with constraints is not as an issue as in UIKit.

Append item horizontally into a tableView cell but make them not fill all the space

I have a specific design that I want to achieve, it doesn't seems to complex to me but I'm struggling a lot to make it happen.
First the design looks like this:
So, I have a table view of items which have a picture, then a title and then a collection of three items which will be ImageViews.
All of this inside a cell and inside a stackView.
I tried to make an horizontal stack view and did manage to append my items correctly but it went horribly wrong in terms of design as my imageviews were stretching all the way horizontally. I guess this is not possible to NOT stretch this items.
I also tried to add a collection view into the table view but figured out that was very complex for a thing this basic (as I guess it should be). And then, I'm here.
Here is my code and where I'm stuck at:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = debateList.dequeueReusableCell(withIdentifier: "itemsBox", for: indexPath) as! ItemBox
// Make a variable with 3 participants
let participants = tableView[indexPath.row].participants?.prefix(3)
// iterate over them and adding them to anything that can be doable
participants?.forEach { participant in
let imageView = UIImageView()
let imageUrl = URL(string: participant.imageURL)
imageView.kf.setImage(with: imageUrl)
// Here add item to something
}
return cell
}
I'm stuck and it's getting too long for something this little. Guess I'm a little bit upset with myself for not figuring out how to do it.
If you are having up to 5 participants, then I would suggest you to add by default 2 subviews in horizontal stack view:
empty view with width constraint >= 5 (call it spaceview)
fixed width for "60 % no" UILabel.
then programmatically insert image views with fixed width and aspect ratio 1:1 in horizontal stack view at index 0.
This way, if there will be only 1-2 participants, then the remaining space will be occupied by spaceview as its width will be greater than 5.
If the participants will be more than 5, then better option is to use collectionview with uilabel in horizontal stack view.
First if they are 3 static number of images then it's better to make them inside design and assign the image urls to their outlets respectively
Second for your current work you need to add a width constraint (regarding height they will fit all the stack height when it's a horizontal stack ) like
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.widthAnchor.constraint(equalToConstant: 50).isActive = true

How to make right scrollable menu with buttons?

I want to make scrollable menu (first view controller) with 4 buttons. Every button linked with specific view controller. But I want to make it specific: after app launching user must see only first three buttons on every iPhone version (4, 4.7, 5.5) and he needs to scroll down to see one more button. Should I use stack view with scrollview? Should I use UICollectionView (I found that's good for images but not for buttons)?
Thanks everybody for help!
If you use a UICollectionViewController (or UITableViewController, either would work) you can layout your storyboard like this:
Then in your MyTableViewController (again, this also works with a UICollectionViewController) you can implement the following method to set the cell size equal to a third of the window height:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
// get the height for the current view
let viewHeight = self.view.frame.height
// since we want 3 rows to appear at a time, simply divide the viewHeight by 3
return viewHeight / 3
}

How to adjust UICollectionView contentSize.height based on number of rows in swift

I'd really appreciate if someone can light up some ideas here. I've been trying to fix this for weeks now (not kidding).
I have a "to do list" using a collectionView where I hide the rows that were completed and move them to the end of the list. I then unhide the items if needed with a button. The collectionView looks exactly as a tableView with one item(cell) per row.
When the items are hidden the collectionView has a lot of empty scrolling space at the bottom instead of automatically deleting the space used by the hidden rows since they technically are still there.
I'm trying to cut that empty space so the collectionView height would be equal to the amount of cells/rows left visible.
override func viewDidAppear(animated: Bool) {
if isCellHidden { //checking if cells are hidden
var heightOfSection0 = 95 + (42 * self.collectionView.numberOfItemsInSection(0))
println(self.collectionView.contentSize.heigh) //returns 2350
self.collectionView.contentSize.height = CGFloat(heightOfSection0)
println(heightOfSection0) //returns 1019
println(self.collectionView.contentSize.heigh) //returns 1019.0 which is correct but as soon as I scroll down it resets to it's original size (2350) and let's me scroll through that empty space...
}}
If I try to read the collectionView height immediately after setting this, it displays the correct value but as soon as I try to scroll down it resets back to it's original height. I also tried disabling the auto layout and it doesn't make a difference
You should not manage contentSize directly - return appropriate number of items to be displayed from collectionView(_:numberOfItemsInSection:) instead (i.e. do not count your "hidden" cells).
You can use sizeForItemAtIndexPath: to change the size of collection view cell.
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
var numberOfCellInRow : Int = 3
var padding : Int = 5
var collectionCellWidth : CGFloat = (self.view.frame.size.width/CGFloat(numberOfCellInRow)) - CGFloat(padding)
return CGSize(width: collectionCellWidth , height: collectionCellWidth)
}
Changing UI stuff in viewDidAppear() in theory is a good place to do so. However, at this point, you can't be sure that auto layout has operated on the subview that you're manipulating.
You can check when it has and when it's safe to manipulate the frame, by subclassing it and overriding layoutSubviews()
I had a similar issue here: https://stackoverflow.com/a/30446125/4396258

CollectionView margin not the same

i'm trying to create a simple collectionView like pinterest. I've reached a problem i've set the margins like in the image, but as u can see the middle margin is 20 since both right and left is 10 how can i make so that its also 10. i've tried changing some values, but it is not working.
for fitting all orientations
Is there a better way?
func collectionView(collectionView : UICollectionView,layout collectionViewLayout:UICollectionViewLayout,sizeForItemAtIndexPath indexPath:NSIndexPath) -> CGSize
{
return CGSizeMake(self.collectionView!.frame.width/2-20, self.collectionView!.frame.width/2-20+50)
}
Use auto layout and view constraints. This will allow you to have each tile maintain its spacing and scale for different orientations.
see the apple docs

Resources