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

问题描述 投票:0回答:1

我有一个以前是 Grid 的自定义视图,但我已将其类继承更改为 View,因为根据我在网上阅读的内容,这对我来说似乎是正确的做法。

  • 这个自定义视图里面有内容。 (内部有内容的网格)
  • 这个自定义视图在本机代码中有一个处理程序。
  • 然后每个项目都有自己版本的处理程序,我可以在其中处理映射方法。

我正在使用 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。

ios mapping handler maui renderer
1个回答
0
投票

所以我在同一个问题上苦苦挣扎,这篇文章没有完全解释如何解决这个问题。

在我的例子中,我想在 iOS 上有一个网格,它可以随着键盘弹出或消失而调整大小(对于 Android,这个问题可以更容易地解决)。但实际上,仅使用 ContentView 作为基类似乎更容易。所以我添加了一个类

KeyboardAdjustingView

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

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

KeyboardAdjustingViewHandler

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

请注意这个类继承自

ContentViewHandler
,因为
KeyboardAdjustingView
类是基于
ContentView
.

现在对于 iOS 实现,我们在文件中添加部分

KeyboardAdjustingViewHandler
类实现
KeyboardAdjustingViewHandler.iOS.cs

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 组合的指令。

有关更多信息,请参阅配置多目标

最后我们在启动时注册我们的视图和处理程序

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();
}
© www.soinside.com 2019 - 2024. All rights reserved.