OGeek|极客世界-中国程序员成长平台

标题: ios - Xamarin.Forms 和 iOS : how to combine UseSafeArea and a background image? [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-13 15:58
标题: ios - Xamarin.Forms 和 iOS : how to combine UseSafeArea and a background image?

我有一个关于 iOS 使用 安全区域 的问题。

我通过RelativeLayout 使用背景图片,并在此背景图片上显示表单。我在表单的容器上为 iOS 使用了 margin:这很好用,但是 iPhone X 上的渲染效果不是很好。

<RelativeLayout>

    <Image Source="background.jpg" Opacity="0.75"
           Aspect="AspectFill"
           RelativeLayout.WidthConstraint =
               "{ConstraintExpression Type=RelativeToParent, Property=Width}"
           RelativeLayout.HeightConstraint =
               "{ConstraintExpression Type=RelativeToParent, Property=Height}" />

    <ScrollView RelativeLayout.WidthConstraint =
                    "{ConstraintExpression Type=RelativeToParent, Property=Width}"
                 RelativeLayout.HeightConstraint =
                    "{ConstraintExpression Type=RelativeToParent, Property=Height}">    
    <ScrollView.Margin>                
        <OnPlatform x:TypeArguments="Thickness">
            <On Platform="iOS" Value="0, 20, 0, 0" />
        </OnPlatform>
    </ScrollView.Margin>

    <StackLayout>
        <!-- Header -->
        <StackLayout VerticalOptions="Start">
            <fnc:HunterHeader />
        </StackLayout>

        <!-- Form -->
        <StackLayout VerticalOptions="CenterAndExpand"
                     Spacing="6" Margin="20">
            <!-- ... -->
        </StackLayout>
    </StackLayout>
</RelativeLayout>

所以我尝试将 UseSafeArea 设置为 true,但我得到了顶部和底部边距。

是否有可能解决这个问题,并将 UseSafeArea 和背景图像结合起来? 或者有没有办法只为 iPhone X 添加特定的边距?



Best Answer-推荐答案


选项 1 - 将安全区域应用于特定控件而不是页面

安全区域可以设置在特定控件而不是整个页面上。例如,可以将安全区域值设置为 ScrollView 的边距或填充。还需要考虑方向更改(如果您的应用支持它们)。

XAML

<RelativeLayout>

    <Image Aspect="AspectFill" Source="background.png" 
           RelativeLayout.WidthConstraint = "{ConstraintExpression Type=RelativeToParent, Property=Width}"
           RelativeLayout.HeightConstraint = "{ConstraintExpression Type=RelativeToParent, Property=Height}"  />

    <ScrollView x:Name="scrollView"
                RelativeLayout.WidthConstraint = "{ConstraintExpression Type=RelativeToParent, Property=Width}"
                RelativeLayout.HeightConstraint = "{ConstraintExpression Type=RelativeToParent, Property=Height}">    

        <StackLayout Margin="20, 0" Spacing="20">

            <!-- Header -->
            <StackLayout>
                <BoxView BackgroundColor="Black" HeightRequest="50" />
            </StackLayout>

            <!-- Form -->
            <StackLayout Spacing="20">
                <BoxView BackgroundColor="White" HeightRequest="150" />
                <BoxView BackgroundColor="White" HeightRequest="150" />
                <BoxView BackgroundColor="White" HeightRequest="150" />
                <BoxView BackgroundColor="White" HeightRequest="150" />
                <BoxView BackgroundColor="White" HeightRequest="150" />
                <BoxView BackgroundColor="White" HeightRequest="150" />
            </StackLayout>

        </StackLayout>

    </ScrollView>

</RelativeLayout>

代码隐藏

    private double width = 0;
    private double height = 0;
    private bool safeAreaSetInitially;

    protected override void OnAppearing()
    {
        base.OnAppearing();

        if (!this.safeAreaSetInitially)
        {
            this.SetSafeAreaOnContentContainer();
            this.safeAreaSetInitially = true;
        }
    }

    protected override void OnSizeAllocated(double width, double height)
    {
        base.OnSizeAllocated(width, height); //must be called

        if (Math.Abs(this.width - width) > double.Epsilon || Math.Abs(this.height - height) > double.Epsilon)
        {
            this.width = width;
            this.height = height;

            if (this.width > this.height)
            {
                // reconfigure for landscape if needed
            }
            else
            {
                // reconfigure for portrait if needed
            }

            // reset safe area on rotation as the landscape/portrait safe areas are different
            this.SetSafeAreaOnContentContainer();
        }
    }

    private void SetSafeAreaOnContentContainer()
    {
        if (Device.RuntimePlatform == Device.iOS)
        {
            // set safe insets on content that you want to be within the safe area
            var safeInsets = On<Xamarin.Forms.PlatformConfiguration.iOS>().SafeAreaInsets();
            safeInsets.Top += 20; // add any other custom design margin specific to iOS (the extra 20 came from the original XAML)
            this.scrollView.Margin = safeInsets;
        }
    }

结果

enter image description here

选项 2 - 使用 Page.BackgroundImage属性

根据要求,另一种选择是只使用 PageBackgroundImage 属性(它不受 On().SetUseSafeArea(true) 方法)。这种方法的一个问题是 BackgroundImage 在 iOS 中是“平铺的”。要解决此问题,请创建一个不会“平铺”BackgroundImage 的自定义 Xamarin.Forms.ContentPage 渲染器。 .这是一个 example .

关于ios - Xamarin.Forms 和 iOS : how to combine UseSafeArea and a background image?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51553694/






欢迎光临 OGeek|极客世界-中国程序员成长平台 (http://jike.in/) Powered by Discuz! X3.4