Benny
Benny

Reputation: 3917

UITableViewSource Cells Height Always 44 Points

I am writing a custom cell for my UITableView sourced from UITableViewSource. I have implemented the GetHeightForRow and have logged the result to make sure the height comes through correctly. The problem is, my custom cell's Frame height is a fixed 44, regardless of what the value is returned from GetHeightForRow. The side effects are of course my Layer bounds are out of whack and the UITableView cuts off the bottom of my last cell and doesn't allow for scrolling any further.

It's worth mentioning I have tried manually changing the cell's frame in my cell constructor logic and in the GetCell logic, but obvious to most, this doesn't matter, the value used always reverts to 44.

Here is an idea of how my UITableViewSource logic goes:

public override float GetHeightForRow (UITableView tableView, NSIndexPath indexPath)
{
    var result = SingleItemCell.GetHeight(_models[indexPath.Row], _width, _isStandalone));
    Console.WriteLine(result);  //prints various heights, never 44
    return result;
}

public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{
    var cell = tableView.DequeueReusableCell(Id) as SingleItemCell ?? 
        (_isStandalone ? new StandaloneItemCell() : new SingleItemCell());

    var model = _models[indexPath.Row];
    cell.Model = model;

    Console.WriteLine(cell.Frame.Height); //always 44

    return cell;
}

UPDATE

Interestingly enough, the cell separators show up in the correct place, but my custom view still does not get to see the correct Frame height.

Even after changing the constructor of my custom cell view to pass an explicit frame to the base constructor, the height of my Frame does not change.

public SingleOffer(RectangleF frame) 
              : base(frame) //example new RectangleF(0, 0, 300, 65)
{
    //Here, before custom logic, Frame is still 0, 0, 300, 44!
    Initialize();
}

Upvotes: 1

Views: 2028

Answers (2)

Larry OBrien
Larry OBrien

Reputation: 8606

I can't reproduce your problem. As you seem to understand, the key is UITableViewSource.GetHeightForRow. The following program creates the expected output:

enter image description here

using System;
using System.Collections.Generic;
using System.Linq;

using MonoTouch.Foundation;
using MonoTouch.UIKit;

namespace SingleFileTableViewSolution
{
public class DomainClass
{
    static Random rand = new Random (0);
    public UIColor Color { get; protected set; }
    public float Height { get; protected set; }

    static UIColor[] Colors = new UIColor[] 
    {
        UIColor.Red,
        UIColor.Green,
        UIColor.Blue,
        UIColor.Yellow
    };

    public DomainClass ()
    {
        Color = Colors[rand.Next(Colors.Length)];
        switch(rand.Next(3))
        {
        case 0 : 
            Height = 24.0f;
            break;
        case 1 : 
            Height = 44.0f;
            break;
        case 2 : 
            Height = 64.0f;
            break;
        default:
            throw new ArgumentOutOfRangeException();
        }
    }
}

//Table Source
public class ColorTableDataSource : UITableViewSource
{
    List<DomainClass> Model { get; set; }

    public ColorTableDataSource(List<DomainClass> model)
    {
        this.Model = model;
    }

    public override int RowsInSection(UITableView tableView, int section)
    {
        return Model.Count;
    }

    public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
    {
        var cell = tableView.DequeueReusableCell(ColoredTableCell.ID);
        if(cell == null)
        {
            cell = new ColoredTableCell();
        }
        cell.ContentView.BackgroundColor = Model[indexPath.Row].Color;

        return cell;
    }

    public override float GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
    {

        var height = Model[indexPath.Row].Height;
        return height;
    }
}

public class ColoredTableCell : UITableViewCell
{
    public static readonly string ID = "ColoredTableCell";

    public ColoredTableCell ()
    {
    }
}

public class ColorTableController : UITableViewController
{
    String title;

    public ColorTableController (String title, UITableViewSource source) : base ()
    {
        this.title = title;
        this.TableView.Source = source;
    }

    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();

        Title = title;
    }
}

[Register ("AppDelegate")]
public  class AppDelegate : UIApplicationDelegate
{
    UIWindow window;
    ColorTableController viewController;

    public override bool FinishedLaunching (UIApplication app, NSDictionary options)
    {
        var models = new List<DomainClass>();
        for(int i = 0; i < 20; i++)
        {
            models.Add(new DomainClass());
        }

        var tableController = new ColorTableController("My Table", new ColorTableDataSource(models));

        window = new UIWindow (UIScreen.MainScreen.Bounds);
        window.RootViewController = tableController;

        window.MakeKeyAndVisible ();

        return true;
    }


}

public class Application
{
    static void Main (string[] args)
    {
        UIApplication.Main (args, null, "AppDelegate");
    }
}
}

Upvotes: 2

Anupam
Anupam

Reputation: 56

Implement tableView:heightForRowAtIndexpath: to return the tableviewcell height you want. If you don't implement this method, the framework by default takes the height as 44.

Upvotes: 1

Related Questions