Forum Xamarin.iOS

Dynamic tableview and buttons

TroySmithTroySmith USUniversity

Hi,

I have a tableviewcontroller, with dynamic rows. I'm using a storyboard, so the cell is re-used for each dynamic row. On each row, I have 2 buttons. When the view first runs, the buttons work fine. I have a scenario where the view needs to be refreshed (I reload the root element). At this point, the buttons break with the SIGSEGV error when tapped. From the hours of research I've done this far, it appears as though the GC has disposed of the button, but not the handler. Even though I recreate the buttons when I reload the root element, the new buttons, when tapped, seem to be handled by the previous event handler. How can I create the dynamic buttons (or totally remove the previous event handler)?

Posts

  • sezamuzsezamuz BSMember ✭✭
    edited October 2013

    pls show you GetCell / GetHeight code and Cell constructor

  • TroySmithTroySmith USUniversity
    edited October 2013

    _standardBuyButton is declared class level as:

    UIButton _standardBuyButton;

    protected override void OnGetCell (UITableViewCell cell)

    {

    ECLSUIUtil.TryAction ("ResultItem_OnGetCell", () => {

    _standardBuyButton = (cell.ViewWithTag(500) as UIButton);
    
    _standardBuyButton.SetTitle("Click Me", UIControlState.Normal);
    
    _standardBuyButton.TouchUpInside += (sender, e) => { 
        ECLSAlertView.Show("Rate Result Tapped", "Rate     Tapped",ECLSAlertViewType.Ok);
    };
    

    (cell.ViewWithTag (2) as UILabel).Text = this.BindingContext.Entity.VehicleName;

    }

  • sezamuzsezamuz BSMember ✭✭
            void TouchUpInsideCode (object sender, EventArgs e)
            {
                // you code // ECLSAlertView.Show("Rate Result Tapped", "Rate     Tapped",ECLSAlertViewType.Ok);
            }
    
            public override void PrepareForReuse ()
            {
                standardBuyButton.TouchUpInside -= TouchUpInsideCode;
                base.PrepareForReuse ();
            }
    public void PrepareForUse ()
    {
    standardBuyButton.TouchUpInside += TouchUpInsideCode;
    }
    
  • TroySmithTroySmith USUniversity
    edited October 2013

    This was helpful, thanks sezamuz! So, the solution is to not use an anonymous delegate so that I could later remove the custom event. Is there anyway to do this at the cell element level (the button) instead of the entire cell? I think the PrepareForReuse is a cell method. If not, is there a way to iterate or remove all event handlers in the cell, no matter how many elements (say I have 2 buttons, 3 text boxes, etc)

    Thanks.

  • sezamuzsezamuz BSMember ✭✭

    enjoy

  • TroySmithTroySmith USUniversity

    Hi sezamuz,
    thanks again for you help. Do you know if there is anyway to do this at the cell element level (the button) instead of the entire cell? I think the PrepareForReuse is a cell method. If not, is there a way to iterate or remove all event handlers in the cell, no matter how many elements (say I have 2 buttons, 3 text boxes, etc)

  • sezamuzsezamuz BSMember ✭✭
    edited October 2013

    create custom class extends UIButton with delegate field and move +=/-= assignts:
    += to constructor
    -= to Dispose:
    protected override void Dispose (bool disposing) { if (disposing){ if (selfActionDelegate!= null) this.OnTouchUpInside -= selfActionDelegate; selfActionDelegate = null; } base.Dispose (disposing); }

    see also

    http://docs.xamarin.com/guides/ios/advanced_topics/api_design/

    http://docs.xamarin.com/guides/cross-platform/application_fundamentals/memory_perf_best_practices/

Sign In or Register to comment.