简体   繁体   English

如何从Xamarin Forms显示iOS添加联系人屏幕?

[英]How to show iOS add contact screen from Xamarin Forms?

I'm trying to show the iOS add contact screen using Xamarin Forms. 我正在尝试使用Xamarin Forms显示iOS添加联系人屏幕。 From what I can see Xamarin Forms does not support this out of the box but Xamarin iOS does. 从我可以看出,Xamarin Forms不支持此功能,但Xamarin iOS支持。 Unfortunately I can't get them to work together. 不幸的是,我不能让他们一起工作。 What I mean by "together" is that I need get access to NavigationController from Xamarin Forms Page. 我的意思是“在一起”是我需要从Xamarin表单页面访问NavigationController。

Can this be done? 能做到吗?

I have a sample solution that demonstrates the problem here: https://github.com/pawelpabich/XamarinFormsContacts . 我有一个示例解决方案,在这里演示了该问题: https : //github.com/pawelpabich/XamarinFormsContacts I also put the most important code below. 我还将最重要的代码放在下面。

public void ShowContact(NavigationPage page)
{
    var newPersonController = new ABNewPersonViewController();
    var person = new ABPerson();
    person.FirstName = "John";
    person.LastName = "Doe";

    newPersonController.DisplayedPerson = person;
    var controller = page.CreateViewController();

    //!!!!---> controller.NavigationController is null !!!!!<----
    controller.NavigationController.PushViewController(newPersonController, true);
}

I updated the repo and it now contains code that works. 我更新了存储库,现在包含了可以正常工作的代码。

There is a UINavigationController when using Xamarin.Forms (when using a NavigationPage), but you have to search for it. 使用Xamarin.Forms时(使用NavigationPage时)有一个UINavigationController,但是您必须搜索它。 This was the only way I could get a hold of it. 这是我掌握它的唯一方法。 Those other methods, CreateViewController and RendererFactory actually create a new ViewController which isn't what you wanted. 其他方法,CreateViewController和RendererFactory实际上创建了一个新的ViewController,这不是您想要的。

public void ShowContact(NavigationPage page)
{
    var newPersonController = new ABNewPersonViewController();
    var person = new ABPerson();
    person.FirstName = "John";
    person.LastName = "Doe";
    newPersonController.Title = "This is a test";

    newPersonController.DisplayedPerson = person;

    UINavigationController nav = null;
    foreach (var vc in 
      UIApplication.SharedApplication.Windows[0].RootViewController.ChildViewControllers) 
    {
        if (vc is UINavigationController)
            nav = (UINavigationController)vc;
    }

    nav.PresentModalViewController(new UINavigationController (newPersonController), true);
}

I also attempted to Create a PersonPage and PersonPageRenderer, as that would be the cleanest solution, but I couldn't get it working. 我还尝试创建一个PersonPage和PersonPageRenderer,因为这将是最干净的解决方案,但我无法使其正常运行。 This could work if you spent some time. 如果您花了一些时间,这可能会起作用。

[assembly: ExportRenderer(typeof(PersonPage), typeof(PersonPageRenderer))] 

public class PersonPageRenderer : ABNewPersonViewController, IVisualElementRenderer, IDisposable, IRegisterable 

Because iOS Add Contact screen is a Native iOS API and your application logic is in a PCL you need to use a DependancyService. 由于“ iOS添加联系人”屏幕是本机iOS API,并且您的应用程序逻辑在PCL中,因此您需要使用DependancyService。

1) To do this in the PCL create a Interface which provides the functionality, like 1)为此,请在PCL中创建一个提供功能的接口,例如

public interface ILocalAddContact 
{   
    void DisplayContactScreen(Contact contact) 
}

2) Implement the Interface in the Native Applications: 2)在本机应用程序中实现接口:

public class LocalAddContactiOS : ILocalAddContact
{
    public void DisplayContactScreen(Contact contact)
    {
        //... do iOS Magic
    }
}

3) Register the Dependancy in the Top of the Native File 3)在本机文件的顶部注册依赖项

[assembly: Xamarin.Forms.Dependency(typeof(LocalAddContactiOS))]

4) Obtain the Dependancy from the iOS Project from the 4)从iOS项目的iOS项目中获取依赖关系

var addContact = DependencyService.Get<ILocalAddContact> ();
addContact.DisplayContactScreen (contact);

If you take a look at this sample application on github, it's very similar (but is used for CreateCalendar). 如果您在github上查看此示例应用程序 ,它非常相似(但用于CreateCalendar)。

Pawel, the problem is that when you use Xamarin.Forms no NavigationController is created (as I know at least in XF 1.3+, maybe Michael will prove me wrong). Pawel的问题是,当您使用Xamarin.Forms时,没有创建NavigationController(据我所知,至少在XF 1.3+中,也许Michael会证明我错了)。 If you want to create new address boo element you can use this approach - How do you add contacts to the iPhone Address book with monotouch? 如果要创建新的地址boo元素,则可以使用这种方法- 如何通过单点触控将联系人添加到iPhone通讯录中?

Ok, this is how I finally implemented. 好的,这就是我最终实现的方式。 I created UINavigationController manually and use it for navigations outside Xamarin.Forms. 我手动创建了UINavigationController并将其用于Xamarin.Forms之外的导航。

using System;
using System.Collections.Generic;
using System.Linq;

using Foundation;
using UIKit;
using Xamarin.Forms;
using AddressBookUI;
using AddressBook;

namespace TestContacts.iOS
{
    [Register ("AppDelegate")]
    public partial class AppDelegate : UIApplicationDelegate
    {
        UIWindow window;
        public override bool FinishedLaunching (UIApplication app, NSDictionary options)
        {
            global::Xamarin.Forms.Forms.Init ();
            window = new UIWindow(UIScreen.MainScreen.Bounds);

            var nav = 
                new UINavigationController(new App ().MainPage.CreateViewController());
            ContactsShared.Instance = new TouchContacts (nav);
            window.RootViewController = nav;

            window.MakeKeyAndVisible();

            return true;
        }
    }

    public class TouchContacts : IContactsShared {
        UINavigationController nav;
        public TouchContacts(UINavigationController nav){
            this.nav = nav;
        }
        public void Show() {

            var newPersonController = new ABNewPersonViewController();
            newPersonController.NewPersonComplete += 
               (object sender, ABNewPersonCompleteEventArgs e) => 
            {    
                nav.PopViewController(true);
            };
            var person = new ABPerson();
            person.FirstName = "John";
            person.LastName = "Doe";


            newPersonController.DisplayedPerson = person;
            nav.PushViewController(newPersonController, true); 
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM