Несколько представлений в одном представлении контейнера - PullRequest
0 голосов
/ 30 мая 2018

В настоящее время у меня есть некоторое кодирование, которому я следовал из учебника, чтобы разрешить несколько контроллеров представления в одном представлении контейнера и использование пользовательских сегментов с идентификаторами для представления нового контроллера представления, когда выбрана строка в таблице.

Я кодирую в xamarin.ios

Теперь у меня работает выбранная часть строки, и она активирует правильную строку в моем ContainerViewController.Однако при активации PerformSegue выдается ошибка, в которой говорится, что

Возникла исключительная ситуация Objective-C.name: NSInvalidArgumentException Причина: Reciever () не имеет перехода с идентификатором 'test1'

У меня есть переход с идентификатором test1, поэтому идентификатор правильный, но все равно выдает эту ошибку.

Это учебник, которому я следовал: https://kodesnippets.wordpress.com/2015/08/11/container-view-in-ios/

Это код для ContainerViewController:

namespace PMApp
{
    public partial class ContainerViewController : UIViewController
    {
        public ContainerViewController(IntPtr handle) : base(handle) { }
        public ContainerViewController() : base("ContainerViewController", null){}

        UIViewController vc;
        string segueIdentifier;
        UIViewController lastViewController;

        public void segueIdentifireRecievedFromParent(int selectedRow)
        {
            ContainerViewController containerController = new ContainerViewController();

            if (selectedRow == 0)
            {
                segueIdentifier = "test1";
                PerformSegue(segueIdentifier, null);

            }
            else if (selectedRow == 1)
            {
                segueIdentifier = "test2";
                PerformSegue(segueIdentifier, null);
            }
        }

        public override void PrepareForSegue(UIStoryboardSegue segue, NSObject sender)
        {
            base.PrepareForSegue(segue, sender);

            if (segue.Identifier == segueIdentifier)
            {
                if (lastViewController != null)
                {
                    lastViewController.View.RemoveFromSuperview();
                }

                vc = segue.DestinationViewController as UIViewController;
                AddChildViewController(vc);
                View.AddSubview(vc.View);
                vc.DidMoveToParentViewController(this);
                lastViewController = vc;
            }
        }    
    }
}

Это класс, который обрабатывает мою таблицу и выбор строки:

namespace PMApp.Classes
{
    public class TableSource : UITableViewSource
    {
        List<string> TableItems;
        string CellIdentifier = "AreaCell";

        public TableSource(List<string> items)
        {
            TableItems = items;
        }

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

        public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
        {
            UITableViewCell cell = tableView.DequeueReusableCell(CellIdentifier);
            string item = TableItems[indexPath.Row];

            //---- if there are no cells to reuse, create a new one
            if (cell == null)
            { cell = new UITableViewCell(UITableViewCellStyle.Default, CellIdentifier); }

            cell.TextLabel.Text = item;

            return cell;
        }

        public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
        {
            ContainerViewController containerController = new ContainerViewController();

            containerController.segueIdentifireRecievedFromParent(indexPath.Row);
            //MainViewController.PresentContainerView(indexPath.Row);  
            tableView.DeselectRow(indexPath, true);
        }

        private void newAlertView()
        {
            var alertController = UIAlertController.Create("Title", "Message", UIAlertControllerStyle.Alert);
            alertController.AddAction(UIAlertAction.Create("back", UIAlertActionStyle.Default, null));

        }
    }
}

Надеюсь, кто-нибудь может помочь, везде искал решение, но просто не мог ничего найти, чтобы решить проблему.

1 Ответ

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

Как и то, что @ Paulw11 сказал, мы не должны создавать новый экземпляр ContainerViewController в событии RowSelected().Этот экземпляр не тот, что вы положили в Storyborad, поэтому он не может знать обо всей конфигурации в раскадровке, которую вы сделали.

Давайте предположим, что вы поместили ContainerView в ViewController, который лежит в TableView.Мы можем получить экземпляр из Раскадровки через:

ContainerViewController containerViewController;
public override void PrepareForSegue(UIStoryboardSegue segue, NSObject sender)
{
    if (segue.Identifier == "Container")
    {
        containerViewController = segue.DestinationViewController as ContainerViewController;
    }
}

Затем передать это containerViewController в TableSource.Наконец, вы можете вызвать метод ContainerViewController в событии RowSelected():

public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
    container.segueIdentifireRecievedFromParent(indexPath.Row);
}

Но я хочу порекомендовать вам использовать другой способ "изменить" контейнер containerViewController.По вашей ссылке автор просто использует segue для добавления контроллеров и их представлений в containerView.Нет необходимости использовать segue, мы можем добавить их напрямую:

Во-первых, создайте два констроллера в раскадровке и установите их Storyboard ID на вкладке свойств контроллера.

Тогда мы можем использовать их в ContainerViewController:

UIViewController lastViewController;
private void addSubsFrom(string viewControllersIdentifier)
{
    if (lastViewController != null)
    {
        lastViewController.View.RemoveFromSuperview();
        lastViewController.RemoveFromParentViewController();
    }

    var viewController = Storyboard.InstantiateViewController(viewControllersIdentifier);
    viewController.View.Frame = View.Bounds;

    View.AddSubview(viewController.View);
    AddChildViewController(viewController);

    lastViewController = viewController;
}

public void segueIdentifireRecievedFromParent(int selectedRow)
{
    if (selectedRow == 0)
    {
        addSubsFrom("TestAVC");

    }
    else if (selectedRow == 1)
    {
        addSubsFrom("TestBVC");
    }
}

Здесь - мой образец, на который вы ссылаетесь.

...