我有一个以前是 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 上有一个网格,它可以随着键盘弹出或消失而调整大小(对于 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();
}