一个容器视图上的多个视图

时间:2018-05-29 23:40:25

标签: c# ios swift xamarin xamarin.ios

我目前有一些编码,我从教程中遵循一个容器视图中允许多个视图控制器,并且当选择表中的行时,使用带有标识符的自定义segue来呈现新的视图控制器。

我在xamarin.ios中编码

现在我选择了行选项,它会激活我的ContainerViewController中的正确行。但是,当PerformSegue被激活时,它会抛出错误,因为它表示

  

抛出Objective-C异常。 name:NSInvalidArgumentException原因:Reciever()没有带标识符'test1'的segue

我有一个id为test1的segue,所以id是正确的但仍然会抛出错误。

这是我遵循的教程: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 :(得分:0)

与@ Paulw11所说的一样,我们不应在ContainerViewController事件中创建RowSelected()的新实例。此实例不是您在Storyborad中放置的实例,因此它无法了解您已完成的故事板中的所有配置。

假设您将ContainerView放在TableView所在的ViewController中。我们可以通过以下方式从Storyboard获取实例:

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,我们可以直接添加它们:

首先,在故事板中创建两个控制器,并在控制器的属性选项卡中设置其故事板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");
    }
}

Here是我提到的样本。