Maui处理程序,困惑于在CreatePlatformView iOS中放入什么

kmpatx3s  于 2023-03-20  发布在  iOS
关注(0)|答案(1)|浏览(122)

我有一个自定义视图,以前是一个网格,但我已经改变了它的类继承视图,因为这对我来说似乎是正确的事情做的基础上,我已经阅读在线。

  • 此自定义视图包含内容。(自身包含内容的网格)
  • 此自定义视图在本机代码中有一个处理程序。
  • 然后每个项目都有自己的处理程序版本,我可以在其中处理Map方法。

我正在使用ContentMapper(在原生iOS处理程序内部)将内容从自定义视图添加到平台视图

public static void MapContent(MyHandler handler, MyView view)
    {
        if (view.Content == null)
            return;
        handler.PlatformView.AddSubview(view.Content.ToPlatform(handler.MauiContext));
    }

在CreatePlatformView()(原生iOS项目)中,我目前拥有。

UIView uIView = new UIView();
        uIView.BackgroundColor = UIColor.Yellow;
        return uIView;

但是我看不到我的任何内容,但是我可以看到黄色的背景占据了整个页面。
我试过在CreatePlatformView()VirtualView.ToPlatform(VirtualView.Handler.MauiContext)中这样做,但一是它不起作用,二是我认为它无论如何都不应该起作用。
我可能做错了,我不确定。如果需要,我可以创建一个演示项目并将其上传到GitHub。

yfjy0ee7

yfjy0ee71#

所以我在同一个问题上挣扎,这篇文章没有完全解释如何解决这个问题。
在我的例子中,我希望在iOS上有一个Grid,它可以随着键盘弹出或消失而调整大小(对于Android,这个问题可以更容易地解决)。但实际上,只使用ContentView作为基类似乎更容易。因此,我添加了一个类KeyboardAdjustingView

internal class KeyboardAdjustingView : ContentView
{
    public KeyboardAdjustingView() { }
}

P.S.:使用基于ContentView的类更容易的原因是ContentView有一个ContentViewHandler,但对于Grid,似乎不存在GridHandler

我还添加了一个部分处理程序类实现KeyboardAdjustingViewHandler

internal partial class KeyboardAdjustingViewHandler : ContentViewHandler
{        
    public KeyboardAdjustingViewHandler() : base() { }
}

请注意,此类继承自ContentViewHandler,因为KeyboardAdjustingView类基于ContentView
现在,对于iOS实现,我们在文件KeyboardAdjustingViewHandler.iOS.cs中添加部分KeyboardAdjustingViewHandler类实现

internal partial class KeyboardAdjustingViewHandler
{
    private NSObject _keyboardShowObserver;
    private NSObject _keyboardHideObserver;

    protected override void ConnectHandler(Microsoft.Maui.Platform.ContentView platformView)
    {
        base.ConnectHandler(platformView);
        
        RegisterForKeyboardNotifications();
    }

    protected override void DisconnectHandler(Microsoft.Maui.Platform.ContentView platformView)
    {
        UnregisterForKeyboardNotificiations();

        platformView.Dispose();            

        base.DisconnectHandler(platformView);
    }

    #region Private

    private void RegisterForKeyboardNotifications()
    {
        _keyboardShowObserver = UIKeyboard.Notifications.ObserveWillShow(OnKeyboardShow);
        _keyboardHideObserver = UIKeyboard.Notifications.ObserveWillHide(OnKeyboardHide);
    }

    private void UnregisterForKeyboardNotificiations()
    {
        _keyboardShowObserver?.Dispose();
        _keyboardShowObserver = null;

        _keyboardHideObserver?.Dispose();
        _keyboardHideObserver = null;
    }

    private void OnKeyboardShow(object sender, UIKeyboardEventArgs args)
    {
        nfloat keyboardHeight = 0;

        if (args.Notification.UserInfo is NSDictionary userInfo)
        {
            var result = (NSValue)userInfo.ObjectForKey(new NSString(UIKeyboard.FrameEndUserInfoKey));
            var keyboardSize = result.RectangleFValue.Size;

            // adjust keyboard height based on safe area insets on large screen devices like iPhone X
            keyboardHeight = keyboardSize.Height - UIApplication.SharedApplication.KeyWindow.SafeAreaInsets.Bottom;
        }

        if (VirtualView is View view)
        {
            view.Margin = new Thickness(0, 0, 0, keyboardHeight);
        }
    }

    private void OnKeyboardHide(object sender, UIKeyboardEventArgs args)
    {
        if (VirtualView is View view)
        {
            view.Margin = new Thickness(0);
        }
    }

    #endregion
}

为确保KeyboardAdjustingViewHandler.iOS.cs仅在iOS平台上编译,我们使用以下指令更新项目文件(*.csproj):

<Project Sdk="Microsoft.NET.Sdk">
    ...

    <!-- Android -->
    <ItemGroup Condition="$(TargetFramework.StartsWith('net7.0-android')) != true">
        <Compile Remove="**\**\*.Android.cs" />
        <None Include="**\**\*.Android.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
    </ItemGroup>

    <!-- Both iOS and Mac Catalyst -->
    <ItemGroup Condition="$(TargetFramework.StartsWith('net7.0-ios')) != true AND $(TargetFramework.StartsWith('net7.0-maccatalyst')) != true">
        <Compile Remove="**\**\*.MaciOS.cs" />
        <None Include="**\**\*.MaciOS.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
    </ItemGroup>

    <!-- iOS -->
    <ItemGroup Condition="$(TargetFramework.StartsWith('net7.0-ios')) != true">
        <Compile Remove="**\**\*.iOS.cs" />
        <None Include="**\**\*.iOS.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
    </ItemGroup>

    <!-- Mac Catalyst -->
    <ItemGroup Condition="$(TargetFramework.StartsWith('net7.0-maccatalyst')) != true">
        <Compile Remove="**\**\*.MacCatalyst.cs" />
    </ItemGroup>    
</Project>

以上内容确保了以iOS.cs结尾的文件仅针对iOS目标进行编译,但也包括针对Android、Mac Catalyst和iOS / Mac Catalyst组合的指令。
有关详细信息,请参见Configure multi-targeting
为了使用本机实现,我们在MauiProgram.cs中启动时注册视图和处理程序

public static MauiApp CreateMauiApp()
{
    var builder = MauiApp.CreateBuilder();
    builder
        .UseMauiApp<App>()
        // other stuff like MauiCommunityToolkit, Essentials, Services, Fonts ...
        .ConfigureMauiHandlers(handlers =>
        {
            // other handlers ...
            handlers.AddHandler(typeof(KeyboardAdjustingView), typeof(KeyboardAdjustingViewHandler));
        })

#if DEBUG
    builder.Logging.AddDebug();
#endif

    return builder.Build();
}

最后,为了使用视图,我们可以将一个示例赋给ContentPageContent属性,如下所示:

public class TextInputPage : BasePage // inherits from ContentPage
{
    public TextInputPage()
    {
        BindingContext = new TextInputViewModel();

        var content = new Grid
        {
            // some grid with various child Entry views ...
        };

        Title = "Title";
        Content = new KeyboardAdjustingView { Content = content };

        // no automated clean-up, so we need to do manually, see:
        // https://learn.microsoft.com/en-us/dotnet/maui/user-interface/handlers/create?view=net-maui-7.0
        Unloaded += (sender, e) =>
        {
            (Content as KeyboardAdjustingView).Handler?.DisconnectHandler();
        };
    }
}

相关问题