Question

I'm using Monotouch.Dialog and need to reposition some EntryElements - they seem to drift right when inside a Section.

I am setting the frame to frame.X = frame.X - 5; to account for this. However if the cell goes off screen and then is scrolled back on the frame seems to be reset and the UI looks out of line.

What can I do to ensure the frame is never reset or at least set back to what it should be?

Here is the code - this is using the MvvmCross port of Monotouch.Dialog so GetCell is now GetCellImpl - it works in pretty much the same way - thing is dequeuereusablecell is called in it's base class (EntryElement) and I am modifying the cell after that point anyway... so should work no?:

public class MyEntryElement : EntryElement, IElementSizing
{
    public bool Disabled {
        get;
        set;
    }


    public MyClaimEntryElement()
        : base()
    {
    }

    public MyEntryElement(string caption)
        : base(caption)
    {
    }

    public MyEntryElement(string caption, string placeholder)
        : base(caption, placeholder)
    {
    }

    public MyEntryElement(string caption, string placeholder, string value)
        : base(caption, placeholder, value)
    {
    }

    public MyEntryElement(string caption, string placeholder, string value, bool isPassword)
        : base(caption, placeholder, value, isPassword)
    {
    }

    protected override UITableViewCell GetCellImpl(UITableView tv)
    {
        var cell = base.GetCellImpl(tv);
        cell.BackgroundColor = UIColor.Clear;
        UITextField uiTextField;

        if (cell.ContentView.Subviews.Length == 1)
        {
            uiTextField = ((UITextField)cell.ContentView.Subviews[0]);
        }
        else
        {
            uiTextField = ((UITextField)cell.ContentView.Subviews[1]);
        }

        if (cell.ContentView.Subviews.Length == 2) {
            var labelField = ((UILabel)cell.ContentView.Subviews [0]);
            labelField.TextColor = UIColor.White;
        }
        uiTextField.Enabled = Disabled;
        uiTextField.TextColor = UIColor.Black;
        uiTextField.Background = UiHelper.Text_Bubble;
        uiTextField.Enabled = !Disabled;
        var frame = uiTextField.Frame;
        frame.X = frame.X - 5;
        frame.Height = frame.Height + 10;
        uiTextField.Frame = frame;
        return cell;
    }

    private const float CellHeight = 40; //standard height. You can make it bigger or smaller, tho smaller means fingers miss easier.

    public float GetHeight(UITableView tableView, NSIndexPath indexPath)
    {
        return CellHeight;
    }
}
Was it helpful?

Solution

Since UITableViewCell are re-used modifying it's Frame property based on it's previous value will lead you to problems.

E.g.

  • You show 12 cells on your table view. They are all visible and need to be created;

  • Your code subtract 5 from the X position. If the original X was 20, then it's now 15;

  • You scroll then some new cells are created (X will be 20 - 5 = 15 again) but, mostly, cells that are not visible anymore will be recycled;

  • Your code subtract again 5 from the X position. Any cell where X == 15 will now be at 10;

This is why setting Frame.X to a static field value (not based on the current X) works.

note: the above would be a lot easier to understand if you run this in the debugger and inspect the Frame for each call to GetCellImpl.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top