Skip to content

Commit a32fea1

Browse files
Vetle444Vetle Finstad
andauthored
Fix barcode overlay z-order, support runtime navigation bar color changes, and remove SafeAreaEdges.None from CameraPreview containers (#876)
Co-authored-by: Vetle Finstad <finstad@Vetles-MacBook-Pro-2.local>
1 parent 76c729a commit a32fea1

17 files changed

Lines changed: 648 additions & 41 deletions

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## [60.0.2]
2+
- [BarcodeScanner] Fixed barcode scan overlay rendering on top of toolbar containers by inserting the overlay at the correct z-order position.
3+
- [ContentPage] `NavigationPage.BarBackgroundColorProperty` and `NavigationPage.BarTextColorProperty` changes are now propagated at runtime, allowing dynamic navigation bar color updates without re-navigation.
4+
- [CameraPreview] Removed `SafeAreaEdges.None` from internal containers so maui handles insets.
5+
16
## [60.0.1]
27
- [CameraPreview] Removed manual safe-area padding on iOS and set `SafeAreaEdges.None` on internal containers so the top toolbar renders correctly on both modal and regular shell pages.
38

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml
2+
version="1.0"
3+
encoding="utf-8"?>
4+
5+
<dui:ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
6+
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
7+
xmlns:dui="http://dips.com/mobile.ui"
8+
x:Class="Playground.VetleSamples.BarcodeNoNavBarRepro"
9+
Title="No NavBar Repro"
10+
NavigationPage.HasNavigationBar="False"
11+
NavigationPage.BarBackgroundColor="Black"
12+
NavigationPage.BarTextColor="White">
13+
<dui:CameraPreview x:Name="CameraPreview"/>
14+
</dui:ContentPage>
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
using DIPS.Mobile.UI.API.Camera;
2+
using DIPS.Mobile.UI.API.Camera.BarcodeScanning;
3+
using Colors = Microsoft.Maui.Graphics.Colors;
4+
5+
namespace Playground.VetleSamples;
6+
7+
/// <summary>
8+
/// Repro: When no navigation bar in a modal page, top toolbar is squished into the status bar.
9+
/// Open this page modally with a NavigationPage wrapper (nav bar hidden) and observe
10+
/// the top toolbar content overlapping with the status bar.
11+
/// </summary>
12+
public partial class BarcodeNoNavBarRepro
13+
{
14+
private readonly BarcodeScanner m_barcodeScanner;
15+
16+
public BarcodeNoNavBarRepro()
17+
{
18+
InitializeComponent();
19+
m_barcodeScanner = new BarcodeScanner();
20+
}
21+
22+
private async Task Start()
23+
{
24+
try
25+
{
26+
await m_barcodeScanner.Start(new BarcodeScannerStartOptions
27+
{
28+
Preview = CameraPreview,
29+
OnCameraFailed = CameraFailed,
30+
OnBarcodeAcceptedAsync = HandleBarcodeAcceptedAsync,
31+
Strategy = new ScanRectangleBarcodeScanStrategy
32+
{
33+
WidthFraction = 0.8f,
34+
HeightFraction = 0.3f
35+
}
36+
});
37+
38+
CameraPreview.AddTopToolbarView(new BoxView
39+
{
40+
Color = Colors.White,
41+
HeightRequest = 50,
42+
WidthRequest = 200,
43+
HorizontalOptions = LayoutOptions.Center
44+
});
45+
CameraPreview.AddBottomToolbarView(CreateCloseButton());
46+
}
47+
catch (Exception exception)
48+
{
49+
Console.WriteLine(exception);
50+
}
51+
}
52+
53+
private void CameraFailed(CameraException e)
54+
{
55+
Console.WriteLine($"Camera failed: {e.Message}");
56+
}
57+
58+
private Task HandleBarcodeAcceptedAsync(BarcodeScanResult barcodeScanResult)
59+
{
60+
return Task.CompletedTask;
61+
}
62+
63+
protected override void OnAppearing()
64+
{
65+
_ = Start();
66+
base.OnAppearing();
67+
}
68+
69+
private void Close()
70+
{
71+
m_barcodeScanner.StopAndDispose();
72+
Shell.Current.Navigation.PopModalAsync();
73+
}
74+
75+
protected override bool OnBackButtonPressed()
76+
{
77+
Close();
78+
return true;
79+
}
80+
81+
private Button CreateCloseButton()
82+
{
83+
var button = new Button
84+
{
85+
Text = "Close",
86+
TextColor = Colors.White,
87+
BackgroundColor = Colors.Transparent,
88+
HorizontalOptions = LayoutOptions.Center
89+
};
90+
button.Clicked += (_, _) => Close();
91+
return button;
92+
}
93+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml
2+
version="1.0"
3+
encoding="utf-8"?>
4+
5+
<dui:ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
6+
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
7+
xmlns:dui="http://dips.com/mobile.ui"
8+
x:Class="Playground.VetleSamples.BarcodeNoNavBarStatusBarRepro"
9+
Title="StatusBar Color Repro"
10+
NavigationPage.HasNavigationBar="False"
11+
NavigationPage.BarBackgroundColor="Black"
12+
NavigationPage.BarTextColor="White">
13+
<dui:CameraPreview x:Name="CameraPreview"/>
14+
</dui:ContentPage>
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
using DIPS.Mobile.UI.API.Camera;
2+
using DIPS.Mobile.UI.API.Camera.BarcodeScanning;
3+
using Colors = Microsoft.Maui.Graphics.Colors;
4+
5+
namespace Playground.VetleSamples;
6+
7+
/// <summary>
8+
/// Repro: When navigation bar is hidden in a modal, the status bar text color is not changed.
9+
/// Open this page modally with a NavigationPage wrapper (nav bar hidden) and observe
10+
/// the status bar text remains dark instead of switching to light for the camera background.
11+
/// </summary>
12+
public partial class BarcodeNoNavBarStatusBarRepro
13+
{
14+
private readonly BarcodeScanner m_barcodeScanner;
15+
16+
public BarcodeNoNavBarStatusBarRepro()
17+
{
18+
InitializeComponent();
19+
m_barcodeScanner = new BarcodeScanner();
20+
}
21+
22+
private async Task Start()
23+
{
24+
try
25+
{
26+
await m_barcodeScanner.Start(new BarcodeScannerStartOptions
27+
{
28+
Preview = CameraPreview,
29+
OnCameraFailed = CameraFailed,
30+
OnBarcodeAcceptedAsync = HandleBarcodeAcceptedAsync
31+
});
32+
33+
CameraPreview.AddTopToolbarView(new BoxView
34+
{
35+
Color = Colors.White,
36+
HeightRequest = 50,
37+
WidthRequest = 200,
38+
HorizontalOptions = LayoutOptions.Center
39+
});
40+
CameraPreview.AddBottomToolbarView(CreateCloseButton());
41+
}
42+
catch (Exception exception)
43+
{
44+
Console.WriteLine(exception);
45+
}
46+
}
47+
48+
private void CameraFailed(CameraException e)
49+
{
50+
Console.WriteLine($"Camera failed: {e.Message}");
51+
}
52+
53+
private Task HandleBarcodeAcceptedAsync(BarcodeScanResult barcodeScanResult)
54+
{
55+
return Task.CompletedTask;
56+
}
57+
58+
protected override void OnAppearing()
59+
{
60+
_ = Start();
61+
base.OnAppearing();
62+
}
63+
64+
private void Close()
65+
{
66+
m_barcodeScanner.StopAndDispose();
67+
Shell.Current.Navigation.PopModalAsync();
68+
}
69+
70+
protected override bool OnBackButtonPressed()
71+
{
72+
Close();
73+
return true;
74+
}
75+
76+
private Button CreateCloseButton()
77+
{
78+
var button = new Button
79+
{
80+
Text = "Close",
81+
TextColor = Colors.White,
82+
BackgroundColor = Colors.Transparent,
83+
HorizontalOptions = LayoutOptions.Center
84+
};
85+
button.Clicked += (_, _) => Close();
86+
return button;
87+
}
88+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml
2+
version="1.0"
3+
encoding="utf-8"?>
4+
5+
<dui:ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
6+
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
7+
xmlns:dui="http://dips.com/mobile.ui"
8+
x:Class="Playground.VetleSamples.BarcodeOverlayToolbarRepro"
9+
Title="Overlay Toolbar Repro"
10+
NavigationPage.BarBackgroundColor="Black"
11+
NavigationPage.BarTextColor="White">
12+
<dui:ContentPage.ToolbarItems>
13+
<ToolbarItem IconImageSource="{dui:Icons close_line}"
14+
Clicked="Close"/>
15+
</dui:ContentPage.ToolbarItems>
16+
<dui:CameraPreview x:Name="CameraPreview"/>
17+
</dui:ContentPage>
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
using DIPS.Mobile.UI.API.Camera;
2+
using DIPS.Mobile.UI.API.Camera.BarcodeScanning;
3+
using Colors = Microsoft.Maui.Graphics.Colors;
4+
5+
namespace Playground.VetleSamples;
6+
7+
/// <summary>
8+
/// Repro: Android's GraphicsView overlay spans the entire top and bottom toolbar.
9+
/// Open this page modally with a NavigationPage wrapper and observe the overlay
10+
/// extending behind the navigation bar and bottom safe area on Android.
11+
/// </summary>
12+
public partial class BarcodeOverlayToolbarRepro
13+
{
14+
private readonly BarcodeScanner m_barcodeScanner;
15+
16+
public BarcodeOverlayToolbarRepro()
17+
{
18+
InitializeComponent();
19+
m_barcodeScanner = new BarcodeScanner();
20+
}
21+
22+
private async Task Start()
23+
{
24+
try
25+
{
26+
await m_barcodeScanner.Start(new BarcodeScannerStartOptions
27+
{
28+
Preview = CameraPreview,
29+
OnCameraFailed = CameraFailed,
30+
OnBarcodeAcceptedAsync = HandleBarcodeAcceptedAsync,
31+
Strategy = new ScanRectangleBarcodeScanStrategy
32+
{
33+
WidthFraction = 0.8f,
34+
HeightFraction = 0.3f
35+
}
36+
});
37+
38+
CameraPreview.AddTopToolbarView(new BoxView
39+
{
40+
Color = Colors.White,
41+
HeightRequest = 50,
42+
WidthRequest = 200,
43+
HorizontalOptions = LayoutOptions.Center
44+
});
45+
CameraPreview.AddBottomToolbarView(CreateCloseButton());
46+
}
47+
catch (Exception exception)
48+
{
49+
Console.WriteLine(exception);
50+
}
51+
}
52+
53+
private void CameraFailed(CameraException e)
54+
{
55+
Console.WriteLine($"Camera failed: {e.Message}");
56+
}
57+
58+
private Task HandleBarcodeAcceptedAsync(BarcodeScanResult barcodeScanResult)
59+
{
60+
return Task.CompletedTask;
61+
}
62+
63+
protected override void OnAppearing()
64+
{
65+
_ = Start();
66+
base.OnAppearing();
67+
}
68+
69+
private void Close()
70+
{
71+
m_barcodeScanner.StopAndDispose();
72+
Shell.Current.Navigation.PopModalAsync();
73+
}
74+
75+
private void Close(object? sender, EventArgs e) => Close();
76+
77+
private Button CreateCloseButton()
78+
{
79+
var button = new Button
80+
{
81+
Text = "Close",
82+
TextColor = Colors.White,
83+
BackgroundColor = Colors.Transparent,
84+
HorizontalOptions = LayoutOptions.Center
85+
};
86+
button.Clicked += (_, _) => Close();
87+
return button;
88+
}
89+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml
2+
version="1.0"
3+
encoding="utf-8"?>
4+
5+
<dui:ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
6+
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
7+
xmlns:dui="http://dips.com/mobile.ui"
8+
x:Class="Playground.VetleSamples.CameraNavBarColorNoNavBarRepro"
9+
Title="Camera NavBar Color (No NavBar)"
10+
NavigationPage.HasNavigationBar="False"
11+
NavigationPage.BarBackgroundColor="Black"
12+
NavigationPage.BarTextColor="White">
13+
<Grid SafeAreaEdges="None">
14+
<dui:CameraPreview x:Name="CameraPreview"/>
15+
<Image x:Name="CapturedImageView"
16+
IsVisible="False"
17+
Aspect="AspectFit"/>
18+
</Grid>
19+
</dui:ContentPage>

0 commit comments

Comments
 (0)