Кнопка «Подписаться» и «Отказаться от подписки» Событие Click не работает в iOS 11 - PullRequest
0 голосов
/ 27 апреля 2018

Я работаю над Xamarin.iOS. В TableView. Я связываю клетку кнопкой.

Для нажатия кнопки Я делаю событие «Подписаться и отписаться от ячейки» по коду ниже

cell.btn_Click.Tag = indexPath.Row;
cell.btn_Click.TouchUpInside -= BtnClickEvent;
cell.btn_Click.TouchUpInside += BtnClickEvent;

это не работает нормально, когда я снова вызываю API данных и устанавливаю TableView.

Объяснение: Когда я открываю ViewController первый раз, кнопка ячейки щелкает событие огня 1 раз. И я открываю это во второй раз, когда это вызовет событие нажатия кнопки ячейки 2 раза Я использую верхний код для события кнопки подписки и отмены подписки, тогда почему она будет вызываться несколько раз.

с этой проблемой я сталкиваюсь в iOS 11.2

Первый путь:

Полный код исходного класса

class StockListSourceClass : UITableViewSource
{
    private List<PacketAndPacketDetailItem> stockLists;
    private List<string> serialNoList;
    private UINavigationController navigationController;
    public static event EventHandler BtnClickEvented;


    public StockListSourceClass(List<PacketAndPacketDetailItem> stockLists, List<string> serialNolist, UINavigationController navigationController)
    {
        this.stockLists = stockLists;
        this.serialNoList = serialNolist;
        this.navigationController = navigationController;
    }

    public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
    {
        StockTableViewCell cell = tableView.DequeueReusableCell(StockTableViewCell.Key) as StockTableViewCell ?? StockTableViewCell.Create();
        var item = stockLists[indexPath.Row];
        if (serialNoList.Contains(item.SerialNo))
            cell.BindData(item, true);
        else
            cell.BindData(item, false);

        cell.SelectionStyle = UITableViewCellSelectionStyle.None;
        cell.PreservesSuperviewLayoutMargins = false;
        cell.SeparatorInset = UIEdgeInsets.Zero;
        cell.LayoutMargins = UIEdgeInsets.Zero;
        cell.SetNeedsLayout();
        cell.LayoutIfNeeded();

        cell.btn_Click.Tag = indexPath.Row;


        cell.btn_Click.TouchUpInside -= BtnClickEvent;
        cell.btn_Click.TouchUpInside += BtnClickEvent;

        cell.btn_Click.TouchUpInside += (sender, e) => {
            var imageName = ((UIButton)sender).TitleLabel.Text;
            if (imageName.Equals("unchecked"))
            {
                ((UIButton)sender).SetBackgroundImage(UIImage.FromBundle("checked"), UIControlState.Normal);
                ((UIButton)sender).TitleLabel.Text = "checked";
            }
            else
            {
                ((UIButton)sender).SetBackgroundImage(UIImage.FromBundle("unchecked"), UIControlState.Normal);
                ((UIButton)sender).TitleLabel.Text = "unchecked";
            }
        };

        return cell;
    }

    public void BtnClickEvent(object sender, EventArgs e)
    {
        var row = ((UIButton)sender).Tag;
        MarketSheetViewController.RowNo = (int)row;
        if (BtnClickEvented != null)
        {
            BtnClickEvented(stockLists[(int)row].SerialNo, EventArgs.Empty);
        }
    }

    public override nint RowsInSection(UITableView tableview, nint section)
    {
        return stockLists.Count;
    }

    public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
    {
        var storyboard = UIStoryboard.FromName("Main", null);
        var webController = storyboard.InstantiateViewController("PacketDetailViewController") as PacketDetailViewController;
        webController.item = stockLists[indexPath.Row];
        this.navigationController.PushViewController(webController, true);
    }
}

Внутри ViewController Я использую это

StockListSourceClass.BtnClickEvented += (sender, e) =>
{
    if (!(serialNoList.Contains(stockLists[RowNo].SerialNo)))
        serialNoList.Add(stockLists[RowNo].SerialNo);
    else
        serialNoList.Remove(stockLists[RowNo].SerialNo);
    SetUpperPanelData();
};

Второй способ

cell.btn_Click.TouchUpInside += (sender, e) => {

    var imageName = ((UIButton)sender).TitleLabel.Text;
    if (imageName.Equals("unchecked"))
    {
        ((UIButton)sender).SetBackgroundImage(UIImage.FromBundle("checked"), UIControlState.Normal);
        ((UIButton)sender).TitleLabel.Text = "checked";
    }
    else
    {
        ((UIButton)sender).SetBackgroundImage(UIImage.FromBundle("unchecked"), UIControlState.Normal);
        ((UIButton)sender).TitleLabel.Text = "unchecked";
    }
    var row = ((UIButton)sender).Tag;
    MarketSheetViewController.RowNo = (int)row;
    if (BtnClickEvented != null)
    {
        BtnClickEvented(stockLists[(int)row].SerialNo, EventArgs.Empty);
    }
};

Но этот метод вызывается несколько раз, если я открываю ViewController во второй раз.

Ответы [ 2 ]

0 голосов
/ 02 мая 2018

Наконец-то получили решение, выполнив следующий способ

StockTableViewCell.cs

 public partial class StockTableViewCell : UITableViewCell
    {
        public int Row;
        public event EventHandler<int> SelectButtonTapped;

        public void BindData(PacketAndPacketDetailItem item, bool flag, int row)
        {
            this.Row = row;

            btn_click.TouchUpInside -= OnSelectButtonTapped;
            btn_click.TouchUpInside += OnSelectButtonTapped;
        }

        private void OnSelectButtonTapped(object sender, EventArgs e)
        {
            if (SelectButtonTapped != null)
                SelectButtonTapped(sender, Row);
        }
    }

Класс TableSource

class StockListSourceClass : UITableViewSource
    {
       public event EventHandler<int> SelectButtonTapped;


        public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
        {
            StockTableViewCell cell = tableView.DequeueReusableCell(StockTableViewCell.Key) as StockTableViewCell ?? StockTableViewCell.Create();
            var item = stockLists[indexPath.Row];
            if (serialNoList.Contains(item.SerialNo))
                cell.BindData(item, true, indexPath.Row);
            else
                cell.BindData(item, false, indexPath.Row);

            cell.SelectButtonTapped -= OnCellSpeakButtonTapped;
            cell.SelectButtonTapped += OnCellSpeakButtonTapped;

            cell.SelectionStyle = UITableViewCellSelectionStyle.None;
            cell.PreservesSuperviewLayoutMargins = false;
            cell.SeparatorInset = UIEdgeInsets.Zero;
            cell.LayoutMargins = UIEdgeInsets.Zero;
            cell.SetNeedsLayout();
            cell.LayoutIfNeeded();
            return cell;
        }

        void OnCellSpeakButtonTapped(object sender, int e)
        {
            var row = e;
            MarketSheetViewController.RowNo = (int)row;
            if (SelectButtonTapped != null)
                SelectButtonTapped(sender, e);
        }
}

и, наконец, мы можем сделать это в ViewController, чтобы получить единичное событие кнопки Cell

определить этот путь

stockListSourceClass.SelectButtonTapped -= OnSelectButtonTapped;
stockListSourceClass.SelectButtonTapped += OnSelectButtonTapped;

и реализовать его.

private void OnSelectButtonTapped(object sender, int e)
    {

                if (!(serialNoList.Contains(stockLists[RowNo].SerialNo)))
                    serialNoList.Add(stockLists[RowNo].SerialNo);
                else
                    serialNoList.Remove(stockLists[RowNo].SerialNo);
                SetUpperPanelData();
    }
0 голосов
/ 30 апреля 2018

Вы можете попытаться поместить этот код в пользовательскую ячейку, отменить событие в методе PrepareForReuse и подписать его при заполнении данных в ячейке.

код

public class DetailCell : UICollectionViewCell
{
    CustomEventHandler HandlerForButton;

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

        if (HandlerForButton != null)
        {
            EditButton.TouchUpInside -= ButtonPressed;
        }
        HandlerForButton = null;
    }

    private void ButtonPressed (object sender, EventArgs args)
    {

        if (HandlerForButton != null)
        {
            HandlerForButton (this, args);
        }
    }

    internal void GetCell (int position, CustomEventHandler handler)
    {
        HandlerForButton = handler;
        EditButton.TouchUpInside += ButtonPressed;
    }
}

public class CollectionViewSource : UICollectionViewSource
{
    public override UICollectionViewCell GetCell (UICollectionView collectionView, NSIndexPath indexPath)
    {
        var cell = collectionView.DequeueReusableCell ("DetailCell", null) as DetailCell;
        cell.GetCell (indexPath.Row, ClickHandler);
        return cell;
    }

     private void ClickHandler (UICollectionViewCell sender, CustomEventArgs args)
    {
        var cell = sender as UICollectionViewCell;

        if (cell != null)
        {
            // do stuff
        }

        var yourArgs = args as CustomEventArgs;

        if (yourArgs != null)
        {
            // do stuff
        }
    }
}

internal delegate void CustomEventHandler (DetailCell sender, CustomEventArgs args);

Подробности относятся к здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...