C# 一个容器视图上的多个视图
目前,我已经准备好了一些代码,这是我在一个教程中遵循的,允许在一个容器视图中使用多个视图控制器,并允许在选择表中的行时使用带有标识符的自定义分段来显示新的视图控制器 我用xamarin.ios编写代码 现在,我有了选定的行部件,它激活了我的ContainerViewController中的正确行。但是,当performsgue被激活时,它会抛出一个错误,正如它所说的那样 抛出Objective-C异常。名称:NSInvalidArgumentException原因:Receiver()没有标识符为“test1”的序列 我有id为test1的segue,因此id是正确的,但仍然抛出该错误 这是我遵循的教程: 这是ContainerViewController的代码:C# 一个容器视图上的多个视图,c#,ios,swift,xamarin,xamarin.ios,C#,Ios,Swift,Xamarin,Xamarin.ios,目前,我已经准备好了一些代码,这是我在一个教程中遵循的,允许在一个容器视图中使用多个视图控制器,并允许在选择表中的行时使用带有标识符的自定义分段来显示新的视图控制器 我用xamarin.ios编写代码 现在,我有了选定的行部件,它激活了我的ContainerViewController中的正确行。但是,当performsgue被激活时,它会抛出一个错误,正如它所说的那样 抛出Objective-C异常。名称:NSInvalidArgumentException原因:Receiver()没有标识符
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));
}
}
}
名称空间PMApp.class
{
公共类表源:UITableViewSource
{
列出表格项目;
字符串CellIdentifier=“AreaCell”;
公共表源(列表项)
{
TableItems=项目;
}
公共覆盖第九行第九节(UITableView表格视图,第九节)
{
返回表项。计数;
}
公共覆盖UITableViewCell GetCell(UITableView tableView,NSIndexPath indexPath)
{
UITableViewCell cell=tableView.DequeueReusableCell(CellIdentifier);
string item=TableItems[indexath.Row];
//----如果没有可重用的单元,请创建一个新单元
if(单元格==null)
{cell=新的UITableViewCell(UITableViewCellStyle.Default,CellIdentifier);}
cell.textlab.Text=项目;
返回单元;
}
public override void RowSelected(UITableView tableView,NSIndexPath indexPath)
{
ContainerViewController containerController=新的ContainerViewController();
containerController.SegueIdentifierRecievedFromParent(indexPath.Row);
//MainViewController.PresentContainerView(indexPath.Row);
取消选择行(indexPath,true);
}
私有void newAlertView()
{
var alertController=UIAlertController.Create(“标题”,“消息”,UIAlertControllerStyle.Alert);
AddAction(UIAlertAction.Create(“back”,UIAlertActionStyle.Default,null));
}
}
}
希望有人能帮忙,到处寻找解决方案,但就是找不到解决问题的方法 就像@Paulw11所说的,我们不应该在
RowSelected()
事件中创建ContainerViewController
的新实例。此实例不是您在Storyborad中放置的实例,因此它无法了解您在Storyboard中所做的所有配置
假设您将ContainerView放在TableView所在的ViewController中。我们可以通过以下方式从故事板获取实例:
ContainerViewController containerViewController;
public override void PrepareForSegue(UIStoryboardSegue segue, NSObject sender)
{
if (segue.Identifier == "Container")
{
containerViewController = segue.DestinationViewController as ContainerViewController;
}
}
然后将此containerViewController
传递到TableSource
。最后,您可以在RowSelected()
事件中调用ContainerViewController
的方法:
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
container.segueIdentifireRecievedFromParent(indexPath.Row);
}
但我想建议您使用另一种方法“更改”ContainerServiceController的容器。在您的链接中,作者只需使用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");
}
}
是我的示例供您参考。因为您只是通过调用其初始化器来创建一个新的
ContainerViewController
实例,该实例与情节提要无关,因此对分段一无所知。您需要通过调用UIStoryboard
实例上的instanceeviewcontroller
来检索视图控制器实例。非常感谢您的帮助。我使用了你的解决方案,效果很好。然而,为了让它工作,我不能使用表单元格标题的列表,因为它会抛出一个null异常。既然如此,我该如何更改每个单元格的标题,但仍保留功能?如何传递列表?在“TableSource”的构造方法中,您能得到正确的列表吗?我使用TableSource构造函数,其中container=viewcontroller。这就是我使用TableSource(列表项)传递列表的地方,我刚刚发布了一个示例。你可以自己定制。如果您想要列表,您的构造函数可能类似于:TableSource(列表项,ContainerViewController)。非常感谢您的帮助。这很有效。我对编程有点陌生,所以我还是会想一些事情,但再次感谢你!