MvvmCross Resize UITableView once binded - ios

I have a MvxTableViewSource which is bound to my TableView, I want the TableView's frame height to match it's content height. The below code doesn't do anything visual to my app even though the TableView's height has been updated (at breakpoint in ViewDidAppear), the TableView's height display to what was set initially in ViewDidLoad.
Any ideas of how I can programmatically set the frame height of the binded TableView so it shows on screen, the value seems to be set correctly but the UI is not being updated?
public override void ViewDidAppear(bool animated)
{
base.ViewDidAppear(animated);
var frame = _jobTable.Frame;
frame.Height = _jobTable.ContentSize.Height;
frame.Width = View.Frame.Width;
_jobTable.Frame = frame;
_jobTable.SetNeedsDisplay();
}

Related

Resizing UIView causes child table UITableView to disappear

I have a UIView which contains a label, a button, and a UITableView which populates its data dynamically from a server. I am having trouble resizing the parent UIView to fit its content after the content has dynamically populated. For the purpose of demonstrating my issue, I have made the background of the containing UIView blue.
After populating the TableView with data, the UIView's height does not adjust causing the Tableview data to overflow, seen in the diagram below.
I have set the bottom, leading and trailing space constraints of the TableView to the superview, and top space constraint to the button. The UIView itself has no height constraints set.
I implemented a function to manually recalculate the height of the UIView after populating the content of the TableView. Code for the function below:
func resizeToFitSubviews()
{
var w: CGFloat = self.frame.size.width,
h: CGFloat = 0
for view in subviews {
if view.frame.origin.y + view.frame.height > h { h = view.frame.origin.y + view.frame.height }
}
self.frame.size = CGSize(width: w, height: h)
}
This function works. The UIView resizes to what seems to be the right size, but the TableView disappears after doing so:
Completely lost as to why this occurs. The label and button seem unaffected. I either need to make it so autolayout automatically adjusts the height of the UIView, or make it so that resizing the UIView does not cause the TableView to disappear.
In the View Debugger, the TableView is returning a height of 0 (while the rows are returning 130 as expected given that is what I return in my heightForRowAt function).
Thanks
Don't adjust the view frame if you are using Auto Layout.
Make a height constraint and adjust that to your calculated value.
-
Also it might be easier to manually calculate this height.
height = numberOfRows * heightPerRow

Self sizing tableview

First of all this is not a question about how to automatically size the cells inside the tableview, moreover how to automatically resize the entire tableview.
So I have a scrollview which has a tableview and 2 other views as its subviews. The tableview's cells already automatically resize itself, again this question is not about the individual cells. However, the tableview does not resize at all.
What I have done:
1) Set up the tableview to have a top, bottom, leading and trailing constraint
2) Set the cells up to have auto layout enabled
3) * I do not know the cell size at build time
4) I have disabled scrolling mode on tableview
So long story short, how can I go along to get the tableview to resize itself?
Edit
The cells contain a label which can have various lines of text, so therefore the cells, which use auto layout, should then determine the height of the table view.
The following images show how the view is set up:
As you can see the tableview is only a small part of the view and since the scrollview from the tableview is deactivated there should, and aren't, any scrolling problems.
EDIT 2
This is actually how it should end however, i am calculating this on my own and everytime I want to make a small change to the cells the whole code, which calculates the height of the cell, needs to be rewritten and it is quite difficult for me to get the height just right.
Edit 3
Until now I had a height constraint on the tableview which I calculated manually, however removing this constraint and trying to let auto layout handle the tableview height size creates the following error:
Scroll View
Need constraint for: Y position or height
I can conclude therefore that the tableview does not know how to automatically calculate the height based on its cells with autolayout.
You don't need to create a height constraint or set frame whatsoever. Create a subclass of UITableView and recalculate its intrinsicContentSize every time its contentSize changes aka new data added or removed. Here is all you needed:
class SelfSizingTableView: UITableView {
override var contentSize: CGSize {
didSet {
invalidateIntrinsicContentSize()
setNeedsLayout()
}
}
override var intrinsicContentSize: CGSize {
let height = min(.infinity, contentSize.height)
return CGSize(width: contentSize.width, height: height)
}
}
You can change your UITableView's frame by using tableview.frame = CGRect(x: <some_x>, y: <some_y>, width: <some_width>, height: <some_height>)
If your UITableViewCells use auto layout then they should resize when the UITableView's frame changes.

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----------------

UITableView: Set table header view height based on screen size

I have a table view with a table header view created through interface builder inside the same xib. I want to set the height of the header based on the screen size, for example 50% of the screen height.
Here is what I get with a static height on an iPhone 4s:
And here is is what I get on an iPhone 6:
Note that the content of the header is static.
I cannot set constraints to the header using auto layout. I tried to set a height constraint based on the height of the table view but it does not seem to be possible in interface builder. Control-dragging does not work. I cannot drag a line from the header to the table view or even to the header itself.
How can I set the header's height based on the screen size?
Unfortunately, table header views cannot be sized using auto layout. You can use auto layout for elements inside the header but you have to specify the header's size by explicitly setting its frame. If the header's height is static and known at compile time you can use IB. However, if the height is dynamic or depends on the device (as in your case), you have to set it in code.
A quite flexible solution would be to create a custom subclass of UITableView and adapt the header's frame in the layoutSubviews method. This way the header's size gets automatically adjusted when the table view is resized. You have to be careful, however, to only re-apply the header's frame when a change is actually needed to avoid an infinite loop.
Here's what it would look like in Objective-C:
#interface MyTableView : UITableView
#end
#implementation MyTableView : UITableView
- (void)layoutSubviews {
[super layoutSubviews];
if (self.tableHeaderView) {
UIView *header = self.tableHeaderView;
CGRect rect = CGRectMake(0, 0, self.bounds.size.width,
self.bounds.size.height / 2);
// Only adjust frame if needed to avoid infinite loop
if (!CGRectEqualToRect(self.tableHeaderView.frame, rect)) {
header.frame = rect;
// This will apply the new header size and trigger another
// call of layoutSubviews
self.tableHeaderView = header;
}
}
}
#end
The Swift version looks like this:
class MyTableView: UITableView {
override func layoutSubviews() {
super.layoutSubviews()
if let header = tableHeaderView {
let rect = CGRectMake(0, 0, bounds.size.width, bounds.size.height / 2)
// Only adjust frame if needed to avoid infinite loop
if !CGRectEqualToRect(header.frame, rect) {
header.frame = rect
// This will apply the new header size and trigger
// another call of layoutSubviews
tableHeaderView = header
}
}
}
}
Note that the above snippets use the bounds of the table view rather than the screen size to calculate the header size.
Update: Note that sometimes an additional call to layoutIfNeeded is needed after setting the tableHeaderView property. I ran into an issue where section headers were drawn above the header view without calling layoutIfNeeded.
I have tried the following code and it seems to work on iOS7 and iOS8. It changes the height of the header frame to half the screen height. You might want to subtract the height of the navigation and status bar from the screen height before /2, if the header has to be half the size of the table view area only.
- (void)viewDidLoad
{
[super viewDidLoad];
// Your other code
// Set the table header height
CGRect headerFrame = self.tableView.tableHeaderView.frame;
headerFrame.size.height = [[UIScreen mainScreen] bounds].size.height/2;
self.tableView.tableHeaderView.frame=headerFrame;
}

UITableView Auto Height With Constraint problems Xamarin.iOS

I need to resize my UITableView with the height of his contentSize for this i made this:
private void ajustHeightOfTableView()
{
nfloat height = tableViewCores.ContentSize.Height;
nfloat maxHeight = tableViewCores.Superview.Frame.Size.Height - tableViewCores.Frame.Y;
if (height > maxHeight)
height = maxHeight;
UIView.Animate(0.25, new Action (() => {
this.tableViewAjustHeight.Constant = height;
this.contentView.SetNeedsUpdateConstraints();
}));
}
and
public override void ViewDidAppear (bool animated)
{
base.ViewDidAppear (animated);
ajustHeightOfTableView();
}
i have a IBOutlet with de Height Constraint of my UITableView... so i resize the tableview calling after reloadData() my function ajustHeightOfTableView...
The problem is: Below my UITableView i have another UIView with buttons and textfields WHEN i resized my tableView my another View does not work! she does not respond for the user interaction... i thing that my problem is that after the resize the view is not in the correct position.
i have another constraint with the Vertical Spacing between the UITableView and UIView like this:
IMAGE 1
this constraint is to put my view in the correct space another my uitableview resize...
here my UITableView Constraint Height:
IMAGE2
someone please know what am i doing wrong here?
I don't know if you can adjust the height and width separately, but I know of a method to scale the webpage to your view in both directions. This is done using the ScalesPageToFit.
UIWebView webView = new UIWebView (new RectangleF (0, 0, cellWidth, cellHeight));
webView.ScalesPageToFit = true;
webView.ScrollView.MinimumZoomScale = 1f;
webView.ScrollView.MaximumZoomScale = 5f;
webView.LoadRequest (new NSUrlRequest(new NSUrl(URL)));
Adjusting the Frame of the UIWebView won't work.
I hope this short information helps. Good luck!
Love and regards,
Björn

Resources