0

I am pretty new to the iOS SDK so I am trying hard to learn how to do things properly, so please feel free to point out any flaws in the way I am doing things aside from my question. Also I using the Xamarin framework but I can more or less translate Obj-C into what I am doing so either answer is fine.

I am creating a custom cell that is very similar to the UITableViewCellStyleSubtitle. Infact the only difference is that I want a slightly larger cell size in terms of height and a Calendar icon on the right side of the cell. To do the calendar icon I have 2 UILabels that act as the top and bottom half of the calendar. This way I can put text in them dynamically for month and date:

public pendingMessagesCell (NSString cellId) : base(UITableViewCellStyle.Subtitle, cellId)
    {

        _calendarBottom = new UILabel () {
            TextColor       = UIColor.White,
            BackgroundColor = UIColor.Gray,
            TextAlignment   = UITextAlignment.Center
        };

        _calendarTop    = new UILabel () {
            TextColor       = UIColor.White,
            BackgroundColor = UIColor.DarkGray,
            TextAlignment   = UITextAlignment.Center
        };

Following the guide in this stack overflow question I use EstimatedRowHeigh and UITableView.AutomaticDimension in my TableViewController :

public class pendingMessageTableViewController : UITableViewController
{
    /// <summary>
    /// Parent Controller.
    /// </summary>
    private pendingViewController _controller;
    /// <summary>
    /// Messages pending 
    /// </summary>
    private IList<Message> pendingMessages;


    /// <summary>
    /// Initializes a new instance of the <see cref="SaltAndPepper.ios.pendingMessageTableViewController"/> class.
    /// </summary>
    public pendingMessageTableViewController (UITableViewStyle style) : base(style)
    {

    }

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

        pendingMessages     = new List<Message> ();
        pendingMessages     = MessageManager.GetMessages ();
        var source          = new pendingTableMessageViewSource (pendingMessages);
        TableView.Source    = source;
        TableView.RowHeight = UITableView.AutomaticDimension;
        TableView.EstimatedRowHeight = 66;
        TableView.TableFooterView = new UIView(CoreGraphics.CGRect.Empty);
        this.AutomaticallyAdjustsScrollViewInsets = false;
    }

Then in my UITableViewSource subclass I override GetCell as such:

public override UITableViewCell GetCell (UITableView tableView, Foundation.NSIndexPath indexPath)
    {
        var row                 = indexPath.Row;
        var cell    = tableView.DequeueReusableCell (_Cell) as pendingMessagesCell;

        if (cell == null) {
            cell = new pendingMessagesCell ((NSString)_Cell);
        }

        UIImage img = GetContactInfo ();
        cell.UpdateCell (_data [indexPath.Row].Recipient.ToString (), _data [indexPath.Row].Text.ToString (), "Aug", "12", img);
        cell.SetNeedsUpdateConstraints ();
        return cell;

    }

Finally in my UITableViewCell subclass I state in the constructor that:

TextLabel.TranslatesAutoresizingMaskIntoConstraints        = false;
DetailTextLabel.TranslatesAutoresizingMaskIntoConstraints  = false;
_calendarTop.TranslatesAutoresizingMaskIntoConstraints     = false;
_calendarBottom.TranslatesAutoresizingMaskIntoConstraints  = false;

DetailTextLabel.LineBreakMode = UILineBreakMode.TailTruncation;
ContentView.AddSubviews (new UIView[]{ _calendarBottom, _calendarTop });

Then I go ahead an add constraints following the stackoverflow link mentioned above on dynamic cell height.

My issue is this: I have been trying to make the whole class with constraints using Auto Layout, but for the specific case of the ImageView I don't want to use constraints as I like the default implementation (sort of) of the UITableViewCells ImageView. To start with I want a round circle image instead of the default square one of UITableViewCell.ImageView. If I just go ahead and use:

ImageView.Layer.CornerRadius = ImageView.Frame.Size.Width / 2;
ImageView.ClipsToBounds = true;

In LayoutSubview in my Cell subclass the images (Obtained from contacts thumbnailImageData) are circle yet a bit large for my taste:

Large Thumbnails

So I tried adding constraints on the TextLabel and DetailedTextLabel to the ImageView left side and adjusting the frame size with ImageView.Frame = new CoreGraphics.CGRect ( ImageView.Frame.X, (ContentView.Frame.Height / 2) - ((ImageView.Frame.Height * .75)/2), ImageView.Frame.Width * .75, ImageView.Frame.Height * .75);

And bam the image is centered at the size I want. (Constraints done in UpdateConstraints, Image resizing done in LayoutSubViews):

Working Image Resize and Constraints

When I was looking form information on this I came across a SO question HERE that says I shouldn't be using constraints on the Style items of a cell such as TextLabel and so forth, so I am confused as to how to go about doing this. I like most of the positioning of the Subtitle Cell Style, just want some minor adjustments. Am I going about it in a poor way or should I constrain EVERYTHING myself with self built UILables. And if so, is there documentation on default positioning of the Subtitle Cell Style for me to refer too? I haven't found it.

Community
  • 1
  • 1
Chris Shields
  • 151
  • 1
  • 12

1 Answers1

0

So if you want a simpler route, instead of recreating an entirely new Cell, just assign the Accessory view to your own custom view which is your Calendar view. will automatically adjust everything.

If you want to keep going the way you are now, just keep your custom cell but once again move your calendar into the accessory view. As long as you set its size first, it will be perfect.

Clancey
  • 333
  • 1
  • 6
  • Aha! I didn't know `AccessoryView` existed. Thank you :). Ok so I think I understand. So let's say I add the calendar UILables to the AccessoryView as a subclassed `UIView`. If I am now not creating a subclass of `UITableViewCell` how do I adjust the height of the cell? – Chris Shields Oct 03 '15 at 10:18