Xamarin 在某些情况下形成 iOS UIView Renderer 间歇性 OnElementChanged [英] Xamarin forms iOS UIView Renderer intermittent OnElementChanged in some cases

查看:28
本文介绍了Xamarin 在某些情况下形成 iOS UIView Renderer 间歇性 OnElementChanged的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 FlowListView 进行视频矩阵视图(1x1-2x2-3x3 视图).对于 iOS 应用,UIView 渲染器用于与第三方视频 SDK 集成.这是 FlowListView.

I am doing video matrix views (1x1-2x2-3x3 views) using FlowListView. For iOS app, UIView renderer is used to integrate with a third party video SDK. Here is the FlowListView.

    <flv:FlowListView x:Name="VideoFlowList" FlowColumnCount="{Binding ColumnCount}" RowHeight="{Binding RowHeight, Mode=TwoWay}"
                  SeparatorVisibility="None" HasUnevenRows="false" BackgroundColor="Transparent"
                  FlowColumnMinWidth="80" FlowTotalRecords="{Binding TotalRecords, Mode=TwoWay}" FlowItemsSource="{Binding Items}">

    <flv:FlowListView.FlowColumnTemplate>
        <DataTemplate>
            <Grid x:Name="VideoGrid" Padding="2" BackgroundColor="{Binding SelectedBorderColour, Mode=TwoWay}" RowSpacing="1" ColumnSpacing="1">
                <Grid.RowDefinitions>
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <video:CameraView x:Name="MyCameraView" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="Black" />
                <Image x:Name="AddIcon" Source="panel_add.png" Grid.Row="0" Grid.Column="0" IsVisible="{Binding CameraNotAssigned}"
                       HorizontalOptions="Center" VerticalOptions="Center" Aspect="AspectFit" BackgroundColor="Transparent" WidthRequest="50" HeightRequest="50">
                    <Image.GestureRecognizers>
                        <TapGestureRecognizer Command="{Binding BindingContext.AddCameraCommand, Source={x:Reference BrowseItemsPage}}" 
                                              CommandParameter="{x:Reference VideoGrid}" NumberOfTapsRequired="1" />
                    </Image.GestureRecognizers>
                </Image>

                <Label x:Name="Label" HorizontalOptions="Fill" HorizontalTextAlignment="Center" VerticalOptions="End"
                       BackgroundColor="Silver" Opacity="0.5" Text="{Binding CameraName, Mode=TwoWay}" TextColor="Black"/>
            </Grid>
        </DataTemplate>
    </flv:FlowListView.FlowColumnTemplate>
</flv:FlowListView>

在矩阵视图启动时,它在视图模型中显示 4 个视图(ColumnCount = 2,ToTalRecords = 4)并且每次都有效.切换到任何其他视图也有效.但是偶尔从单个视图切换到 4 个视图时,在重写的 OnElementChanged 中只有 2 个新元素而不是 4 个.如何保证每次都能获得4个新元素?

On the startup of the matrix views, it displays 4 views (ColumnCount = 2, ToTalRecords = 4) in the view model) and works everytime. Switching to any other views works too. But ocassionaly when switching to 4 views from a single view, there are only 2 new Elements instead of 4 in overrided OnElementChanged. How to ensure to get 4 new Elements everytime?

请注意,从 9 个视图切换到 4 个视图时不会发生此问题.

Please note that this issue doesn't happen when switching to 4 views from 9 views.

这是ViewRenderer的代码.

Here is the code of the ViewRenderer.

public class VideoRender : ViewRenderer<CameraView, UIVideoView>
{
    private UIVideoView _videoView;

    protected override void OnElementChanged(ElementChangedEventArgs<CameraView> e)
    {
        base.OnElementChanged(e);
        if (e.OldElement != null)
        {
            //Unsubscribe
            _videoView.Tapped -= OnVideoViewTapped;
            Log.Debug($"OldElement CameraIndex {e.OldElement.CameraIndex}, PlayWndHandle {e.OldElement.PlayWndHandle}");
        }
        if (e.NewElement != null)
        {
            //Control is TNativeView, CameraView
            if (Control == null)
            {
                _videoView = new UIVideoView(Element);
                SetNativeControl(_videoView);
            }

            //Element.PlayWndHandle = Handle;

            if (_videoView.Subviews.Length > 0)
            {
                Element.PlayWndHandle = _videoView.Subviews[0].Handle;
            }
            App.PlayWndHandles.Add(Element.PlayWndHandle);
            Log.Debug($"NewElement CameraIndex {Element.CameraIndex}, PlayWndHandle {Element.PlayWndHandle}");
            Log.Debug($"App.PlayWndHandles[{App.PlayWndHandles.Count - 1}]: {Element.PlayWndHandle}");

            // Subscribe
            _videoView.Tapped += OnVideoViewTapped;
        }
    }

}

I added a subview in the UIView UIVideoView and play the video in the subview. Is the issue related to the way I use the subview?
        
void Initialize()
{
    //place the video in subview
    var subView = new UIView();
    subView.UserInteractionEnabled = true;
    AddSubview(subView);
    if (Subviews.Length > 0)
    {
        Subviews[0].Frame = new CoreGraphics.CGRect(0, 0, 100, 100);
    }
}

推荐答案

使用 4 个单独的播放窗口句柄列表(每个矩阵大小一个)似乎可以克服句柄管理问题.单个视图通过清除列表中的句柄来特殊处理,因为句柄总是会被删除和重新创建.

It appears that using 4 separate lists of play window handles (one for each matrix size) can overcome the handle management issue. A single view is specially handled by clearing the handles in the list because the handle will always be removed and re-created.

这篇关于Xamarin 在某些情况下形成 iOS UIView Renderer 间歇性 OnElementChanged的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆