UITableView Cell should not scroll horizontally swift iOS - ios

I have a table view which has card kind of cells as shown in picture.
I have set the content Inset so that I can get the cells with 20px spacing in left,right and top.
tableVw.contentInset = UIEdgeInsets(top: 20, left: 20, bottom: 0, right: 20)
Its displaying as I expected but the problem is, cells can be moved in all direction. But when I move it to right/top, it automatically comes back to original position. But when I move to left it just goes inside and don't scroll back to original position as shown in picture.
I don't want the cells to move at all or I want the cells to come back to centre if its dragged anywhere also. Please help!

Dont provide uiedgeinsets to tableview instead add a view in uitableview cell that cover up the whole cell and add another uiview inside that view and give constraint from top bottom leading trailing equals to 8 or whatever you want then the cell wont move anyways and u tableview cells will look like it has edgeinsets.

you need to set the clipsToBounds property true
tableview.clipsToBounds = true

If you're using AutoLayout, by setting this only should work for you:
In code:
tableView.alwaysBounceVertical = false
or In Interface Builder:
Just find this option and untick "Bounce Vertically" option.
Here's the reference:
If you're not using AutoLayout:
override func viewDidLayoutSubviews() {
// Enable scrolling based on content height
tableView.isScrollEnabled = tableView.contentSize.height > tableView.frame.size.height
}
and also try clipToBounds
tableview.clipsToBounds = true

I achieved what I wanted by below code.
postsTable.contentInset = UIEdgeInsets(top: 20, left: 20, bottom: 0, right: -20)
And in UITableViewCell class :
override var frame: CGRect{
get {
return super.frame
}
set(newFrame){
var frame = newFrame
frame.size.width = kScreenWidth - 40
super.frame = frame
}
}
Now if I drag the cell left or right also its coming back to original position.

Related

swift: how to adjust table view's height to fit super view's height

I have a viewController into which I dragged a tableView, but when I load data in the tableView I get a scroll, what I want is to extend this tableView to its height to fill its superView. I tried to resize the tableView by setting tableView.frame.height = tableView.contentSize.height in viewDidAppear and it worked but I don't get a scroll in the superView, the tableView just got expanded and the content is down the view but I cant scroll, I tried to put this tableView inside a scrollView but still the same thing, what can I do?
yourTableview.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height)
Basically what you did was adjust the height of the tableView to be is the height if its content rather than the height of the screen (the content height is larger than the screen)
The table should carry the height of the screen (or any height you want) and if your content is bigger than the frame of your tableView it will automatically have the scrolling enabled.
Hope this helps!
If you want your scrollview to be scrollable, you need to indicate its contentSize by dynamically calculating the height of its nested components:
scrollView.isScrollEnabled = true
scrollView.contentSize = imageView.frame.height + tableview1.frame.height + tableview2.frame.height + netLabel.frame.height
Notice that you may also have to include your margins' height
I just needed to add the constraint of height of my table as an Outlet like this #IBOutlet weak var myConstraint: NSLayoutConstraint!, and the do myConstraint.constant = myTable.contentSize.height in viewDidAppear

UITableView - footer of last section scrolls off the bottom of the screen. How to prevent?

I have a grouped UITableView. I've implemented tableView(:titleForHeaderInSection:) and tableView(:titleForFooterInSection:). As I scroll a long table, I can see that the section headers and footers contain the expected data. When I get to the bottom of the table and I drag up to see the footer of the last section, it has the correct data, but when I release my finger, the footer scrolls back down past the bottom of the screen and out of view. The last cell of the last section is what appears at the bottom of the screen rather than the footer of the last section.
How to fix it?
There's the last section and its footer. My finger is still on the screen
When I release my finger, the final footer slides off the bottom of the screen.
You can fix scrolling content issue by considering one of the following methods.
Method 1: Natural way to fix your problem by setting up your tableView frame and its bottom constraint properly from your storyboard.
Updated:
Method 2: You can validate your tableView frame in viewDidLayoutSubviews or viewWillLayoutSubviews
override func viewDidLayoutSubviews() {
tableView.frame = CGRect(x: 0, y: 0, width: tableView.frame.width, height: tableView.frame.height - (tabBarController?.tabBar.frame.size.height)!)
}
Method 3: Setting up your tableView frame by adjusting scroll view insets.
override func viewDidLayoutSubviews() {
tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: (tabBarController?.tabBar.frame.size.height)!, right: 0)
}
I think it's blocked by the tabbar.
If using storyborad, reset the constraint of your tableView.
If not, you need to set the frame of your tableView correctly.

Dynamic height for UITableView ( Not Cell )

I'm trying to have a UITableView that lists all the different HomeKit devices a user has available.
Obviously there is no way to know how many devices they have, so I need to have the UITableView's height in the storyboard change.
I've tried this, which I call in the viewDidLoad() function:
func adjustHeightOfTableView() {
//getting the height of the tableview
var tableHeight = self.tableView.contentSize.height
//the height of the content inside the view
var maxHeight = self.tableView.superview?.frame.size.height
//if the height of the content is bigger then the height of the tableview
if (maxHeight! > tableHeight) {
tableHeight = maxHeight!
//set the tableview height to be the content height
}
//trying to reload the tableview height?
self.view.layoutIfNeeded()
self.tableView.reloadData()
}
I am trying to have some UI Elements under the tableview, and I want them to be a set space from the bottom of the tableview, but also have the tableview be the height that it needs to be, for whatever amount of cells there is.
But it's just not working.
If I'm doing anything wrong, or if anyone knows how to make this work, please let me know.
Thanks!
Note: For this approach you need to have static cell height or figure out a way to know before hand whats the total contentsize height
Assuming you are using constraints, create following constraints on your UITableView (apart from leading and trailing!)
Add a height constraint with a priority of 750 and a bottom spacing constraint of 0 to your super view that will be >= 0 and have a priority of 1000. Create outlet for this height constraint that you created in your UIViewController
Now,
func adjustHeightOfTableView() {
//set the height to be equal to the number of elements multiplied by the height of each cell.
//or use some logic that allows you to know what content size or space the cells will occupy!
tableViewHeightConstraint.constant = dataArray.count * rowHeight
view.layoutIfNeeded()
}
Now if your UITableView height is less than super view, no problems! But if it is greater than screen bounds, it will break the height constraint and become full screen and display the content normally as you expect a UITableView to!
Edit:
Even if you are using UIAutomaticRowDimensions what you can do is add constraints programmatically to your UITableView. i.e
Of course all your other views will still have a bottom constraint to your UITableView.
Create a UITableView in your storyboard with normal leading, trailing, top and bottom to the super view. Fetch the data. Get the contentSize for your UITableView and then remove the bottom constraint. Now add a height constraint that will be the minimum value of your UIScreen.main().bounds.size.height and contentSize.
you can use Automatic Dimensions if you are using autolayouts
in view didload:
let nib = UINib(nibName: "YOURCELLNIB", bundle: nil)
tableView.registerNib(nib, forCellReuseIdentifier: "REUSEIDENTIFIER")
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 140
Remove the function
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath)
In your code, you have:
tableHeight = maxHeight!
//set the tableview height to be the content height
But this does not change the table height - it only changes some variable that previously was assigned the value of the old table content height. Nowhere in your code do you actually do anything to change the table height.
One way to change the table height directly is to assign it a completely new frame with values from the old frame, except for the frame's height, which you calculate however you like.
Try something like this (adding whatever other logic you need):
oldFrame = self.tableView.frame
newHeight = rowCount * rowHeight
self.tableView.frame = CGRectMake(oldFrame.origin.x, oldFrame.origin.y, oldFrame.size.width, newHeight)
There is a workaround which can make it seems like the height changes according to the number of the cells.
set tableview height to a proper value when init.
UITableView.init(frame: CGRect.init(x: 0, y: 70, width: self.view.frame.width, height: self.view.frame.height - 350))
set the tableview background color white transparent.
pulldownTableView?.backgroundColor = UIColor.white.withAlphaComponent(0)
set tableFooterView.
pulldownTableView?.tableFooterView = UIView(frame: CGRect.zero)
Below is the result, there are two table in the img. I set the transparent for the front tableview, left img set the backgroundColor to white, right white transparent.
----------------------vs----------------

iOS: Table view, allow scrolling "further down" than the end

Sorry the question sounds a bit confusing. I have two buttons overlapping my table view at the bottom, so if the table view scrolls "normal" the last row is partially hidden by these buttons. That's why I want to allow scrolling the table like the height of one row further down, so the last row is on top of these two buttons. How can I achieve this?
Adjust the content insets of the table view.
For instance, if your buttons are 50 points in height and your table's frame is the full window, you could set your table to snap to the top of your buttons like this:
tableView.contentInset = UIEdgeInsetsMake(0, 0, 50, 0);
Note: In iOS 7+ view controllers have a property automaticallyAdjustsScrollViewInsets that is set to YES by default. When this property is set to YES, the contentInsets you set manually may be overridden. Assuming you have a nav bar of some kind that you want to scroll under, you can set your top edge inset to the length of the topLayoutGuide.
Your final solution (put this in viewDidLoad):
self.automaticallyAdjustsScrollViewInsets = NO;
tableView.contentInset = UIEdgeInsetsMake(self.topLayoutGuide.length, 0, 50, 0);
As pointed out by others, deprecations have made this solution impossible, and if we use a section footer, this will display at the inset all the time. A much simpler solution would be to add a tableFooterView to allow the bottom cells to scroll past the buttons. Like so:
let bottomView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 83))
bottomView.backgroundColor = .clear
tableView.tableFooterView = bottomView
This will make it so the contents shift up.
If you want them to shift down you can change the insets accordingly.
func shiftScrollingUp() {
yourScrollView.contentInsetAdjustmentBehavior = .never
yourScrollView.contentInset = UIEdgeInsetsMake(0, 0, 150, 0)
}
AutomaticallyAdjustsScrollViewInsets is deprecated in ios 11.

TableView ContentInset does not shrink cell width / Add horizontal padding to TableView contents

I'd like to have a UITableView which is full screen. But the content of the UITableView should have a padding on the left and right.
So I tried to set ContentInset. But now the cells are as wide as the UITableView and the UITableView scrolls horizontally.
Is there a way to say that the UITableView content's width should become narrowed by the horizontal content insets? Or do I have to add the padding to all cells and header/footer views?
I don't want to narrow the table view itself, because the scroll indicator should stay at the right side of the screen and not in the middle.
The here (How to set the width of a cell in a UITableView in grouped style) suggested solution seems to be not as generic as i'd love to, beacuse the cells and header and footer views have to know about the padding (at least 3 places to maintain instead of one)
I don't want to narrow the table view itself, because the scroll
indicator should stay at the right side of the screen and not in the
middle.
This makes you happy?
_tableView.clipsToBounds = NO;
_tableView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, 0, -30.f);
If you don't like clipsToBounds = NO effects, you can embed the tableView in container view which is clipsToBounds = YES.
Set the layout margins of the table view. For this to work make sure your constraints in the cells are set relative to the superview margin.
tableView.layoutMargins = UIEdgeInsets(top: 0, left: 40, bottom: 0, right: 40)

Resources