InstantiateViewController调用ViewDidLoad

时间:2016-06-12 21:27:26

标签: c# ios xamarin

我有一个经典的主 - 细节逻辑,并试图在点击事件中使用InstantiateViewController创建细节UIViewController的实例。

这是我的代码,

MasterViewController.cs

detailButton += delegate {
   UIStoryboard Storyboard = UIStoryboard.FromName ("Main", null);
   Console.WriteLine("InstantiateViewController() started");
   var profileController = Storyboard.InstantiateViewController("ProfileController") as ProfileController; 
   Console.WriteLine("InstantiateViewController() ended");
   profileController.Id = 5;  
};

ProfileViewController.cs

public partial class ProfileController : UIViewController
{
    public int Id { get; set; }
    public override void ViewDidLoad() 
    { 
        Console.WriteLine("ViewDidLoad() called");
    }
}

当我点击按钮输出时,

InstantiateViewController() started
ViewDidLoad() called
InstantiateViewController() ended

这意味着在profileController.Id之后设置了ViewDidLoad(),这意味着我无法在ViewDidload事件中按ID加载数据,因为ID为空。

所以我的问题是为什么ViewDidLoad()被InstantiateViewController()调用,我应该在哪个方法中加载Id的数据?

感谢。

2 个答案:

答案 0 :(得分:1)

VoewDidLoad加载到内存中时,

ViewControllercalled

因此,获取数据的正确位置在ViewDidAppearViewDidAppear通知ViewController其视图已添加到视图层次结构中。

更新:

根据评论中提供的新信息,您可以执行以下操作:

public partial class ProfileController : UIViewController
{
    private int _id;

    public void SetupProfile (int id)
    {
        // Save the Id if necessary.
        _id = id;
        // Add event with this id related.
    }
    public override void ViewDidLoad() 
    { 
        Console.WriteLine("ViewDidLoad() called");
    }
}

另外,如果您仍想在ViewDidAppear中进行事件设置,可以将此方法用于事件:

yourClass.Event -= MyHandler;
yourClass.Event += MyHandler;

答案 1 :(得分:1)

我会通过自定义segue来做到这一点。

1)创建一个可在整个应用程序中重复使用的自定义segue:

public class CustomSeque : UIStoryboardSegue // or UIStoryboardPopoverSegue depending upon UI design so you can "POP" controller
{
    public CustomSeque(String identifier, UIViewController source, UIViewController destination) : base (identifier, source, destination) { }

    public override void Perform()
    {
        if (Identifier == "StackOverflow")
        {
            // Are you using a NavigationController?
            if (SourceViewController.NavigationController != null)
                SourceViewController.NavigationController?.PushViewController(DestinationViewController, animated: true);
            else 
                SourceViewController.ShowViewController(DestinationViewController, this);
        } else
            base.Perform();
    }
}

2)然后你可以:

UIStoryboard Storyboard = UIStoryboard.FromName("Main", null);
Console.WriteLine("InstantiateViewController() started");
var profileController = Storyboard.InstantiateViewController("ProfileController") as ProfileController;
var seque = new CustomSeque($"StackOverflow", this, profileController);
profileController.Id = 5;
profileController.PrepareForSegue(seque, this); // instead of *this*, you can pass any NSObject that contains data for your controller
seque.Perform();
Console.WriteLine("InstantiateViewController() ended");

如果您的ProfileController看起来像这样:

public partial class ProfileController : UIViewController
{

    public ProfileController (IntPtr handle) : base (handle)
    {
        Id = -99;
    }

    public int Id { get; set; }

    public override bool ShouldPerformSegue(string segueIdentifier, NSObject sender)
    {
        if (segueIdentifier == "StackOverflow")
            return true;
        return base.ShouldPerformSegue(segueIdentifier, sender);
    }

    [Export("prepareForSegue:sender:")]
    public override void PrepareForSegue(UIStoryboardSegue segue, NSObject sender)
    {
        base.PrepareForSegue(segue, sender);
        Console.WriteLine("ProfileController.PrepareForSegue()");
        Console.WriteLine($"  - ID = {Id}");
    }

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();
        Console.WriteLine("ProfileController.ViewDidLoad()");
        Console.WriteLine($"  - ID = {Id}");
    }

    public override void ViewWillAppear(bool animated)
    {
        base.ViewWillAppear(animated);
        Console.WriteLine("ProfileController.ViewWillAppear()");
        Console.WriteLine($"  - ID = {Id}");
    }
}

您的顺序输出将是:

InstantiateViewController() started
ProfileController.PrepareForSegue()
- ID = 5
ProfileController.ViewDidLoad()
- ID = 5
InstantiateViewController() ended
ProfileController.ViewWillAppear()
- ID = 5