Skip to content

Commit e01061e

Browse files
committed
Move the iOS code and implement the changes for iOS15 plus.
1 parent df5061e commit e01061e

File tree

7 files changed

+125
-22
lines changed

7 files changed

+125
-22
lines changed

src/Controls/samples/Controls.Sample.UITests/Issues/Issue18242.xaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
namespace Maui.Controls.Sample.Issues
55
{
66
[XamlCompilation(XamlCompilationOptions.Compile)]
7-
[Issue(IssueTracker.Github, 18242, "Button ImageSource not Scaling as expected", PlatformAffected.UWP)]
7+
[Issue(IssueTracker.Github, 18242, "Button ImageSource not Scaling as expected", PlatformAffected.All)]
88
public partial class Issue18242 : ContentPage
99
{
1010
public Issue18242()

src/Controls/src/Core/Platform/iOS/Extensions/ButtonExtensions.cs

Lines changed: 75 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
using CoreGraphics;
44
using Foundation;
55
using Microsoft.Maui.Controls.Internals;
6-
using ObjCRuntime;
76
using UIKit;
7+
using Microsoft.Extensions.Logging;
88
using static Microsoft.Maui.Controls.Button;
99

1010
namespace Microsoft.Maui.Controls.Platform
@@ -182,15 +182,82 @@ public static void UpdateContentLayout(this UIButton platformButton, Button butt
182182

183183
platformButton.UpdatePadding(button);
184184

185-
#pragma warning disable CA1416, CA1422 // TODO: [UnsupportedOSPlatform("ios15.0")]
186-
if (platformButton.ImageEdgeInsets != imageInsets ||
187-
platformButton.TitleEdgeInsets != titleInsets)
185+
186+
// On iOS 15+, we will resize the image and then use the UIButton.Configuration to adjust the padding
187+
if (OperatingSystem.IsIOSVersionAtLeast(15) && platformButton.Configuration is not null)
188+
{
189+
ResizeImage(platformButton, button, image);
190+
var config = platformButton.Configuration;
191+
192+
config.ImagePadding = imageInsets.Right - imageInsets.Left + titleInsets.Left - titleInsets.Right;
193+
platformButton.Configuration = config;
194+
}
195+
196+
else if (!OperatingSystem.IsIOSVersionAtLeast(15))
197+
{
198+
if (platformButton.ImageEdgeInsets != imageInsets ||
199+
platformButton.TitleEdgeInsets != titleInsets)
200+
{
201+
platformButton.ImageEdgeInsets = imageInsets;
202+
platformButton.TitleEdgeInsets = titleInsets;
203+
platformButton.Superview?.SetNeedsLayout();
204+
}
205+
}
206+
}
207+
208+
static void ResizeImage(UIButton platformButton, Button button, UIImage image)
209+
{
210+
nfloat buttonSize = 0;
211+
212+
if (!OperatingSystem.IsIOSVersionAtLeast(15))
188213
{
189-
platformButton.ImageEdgeInsets = imageInsets;
190-
platformButton.TitleEdgeInsets = titleInsets;
191-
platformButton.Superview?.SetNeedsLayout();
214+
var contentEdgeInsets = platformButton.ContentEdgeInsets;
215+
if (platformButton.Bounds != CGRect.Empty)
216+
{
217+
if (platformButton.Bounds.Height > platformButton.Bounds.Width)
218+
buttonSize = platformButton.Bounds.Width - (contentEdgeInsets.Left + contentEdgeInsets.Right);
219+
else
220+
buttonSize = platformButton.Bounds.Height - (contentEdgeInsets.Top + contentEdgeInsets.Bottom);
221+
}
192222
}
193-
#pragma warning restore CA1416, CA1422
223+
else
224+
{
225+
if (platformButton.Bounds != CGRect.Empty && platformButton.Configuration?.ContentInsets is NSDirectionalEdgeInsets contentInsets)
226+
{
227+
if (platformButton.Bounds.Height > platformButton.Bounds.Width)
228+
buttonSize = platformButton.Bounds.Width - (contentInsets.Leading + contentInsets.Trailing);
229+
else
230+
buttonSize = platformButton.Bounds.Height - (contentInsets.Top + contentInsets.Bottom);
231+
}
232+
}
233+
234+
try
235+
{
236+
if (buttonSize != 0)
237+
image = ResizeImageSource(image, buttonSize, buttonSize);
238+
239+
image = image?.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
240+
241+
platformButton.SetImage(image, UIControlState.Normal);
242+
}
243+
catch (Exception)
244+
{
245+
button.Handler.MauiContext?.CreateLogger<ButtonHandler>()?.LogWarning("Can not load Button ImageSource");
246+
}
247+
}
248+
249+
static UIImage ResizeImageSource(UIImage sourceImage, nfloat maxWidth, nfloat maxHeight)
250+
{
251+
if (sourceImage is null || sourceImage.CGImage is null)
252+
return null;
253+
254+
var sourceSize = sourceImage.Size;
255+
float maxResizeFactor = (float)Math.Min(maxWidth / sourceSize.Width, maxHeight / sourceSize.Height);
256+
257+
if (maxResizeFactor > 1)
258+
return sourceImage;
259+
260+
return UIImage.FromImage(sourceImage.CGImage, sourceImage.CurrentScale / maxResizeFactor, sourceImage.Orientation);
194261
}
195262

196263
public static void UpdateText(this UIButton platformButton, Button button)

src/Controls/tests/UITests/Tests/Issues/Issue18242.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public Issue18242(TestDevice device) : base(device)
1515
[Test]
1616
public void Issue18242Test()
1717
{
18-
this.IgnoreIfPlatforms(new TestDevice[] { TestDevice.Android, TestDevice.Mac, TestDevice.iOS }, "Only Windows for now");
18+
this.IgnoreIfPlatforms(new TestDevice[] { TestDevice.Android }, "Ignore Android until https://github.com/dotnet/maui/pull/19834 lands.");
1919

2020
App.WaitForElement("WaitForStubControl");
2121

183 KB
Loading

src/Core/src/Handlers/Button/ButtonHandler.iOS.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,15 @@ public partial class ButtonHandler : ViewHandler<IButton, UIButton>
1919
protected override UIButton CreatePlatformView()
2020
{
2121
var button = new UIButton(UIButtonType.System);
22+
23+
// Starting with iOS 15, we can use the button.Configuration and assign future UIButton.Configuration.ContentInsets here instead of the deprecated UIButton.ContentEdgeInsets.
24+
// It is important to note that the configuration will change any set style changes so we will do this right after creating the button.
25+
if (OperatingSystem.IsIOSVersionAtLeast(15))
26+
{
27+
var config = UIButtonConfiguration.PlainButtonConfiguration;
28+
button.Configuration = config;
29+
}
30+
2231
SetControlPropertiesFromProxy(button);
2332
return button;
2433
}

src/Core/src/Handlers/ImageButton/ImageButtonHandler.iOS.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,16 @@ public partial class ImageButtonHandler : ViewHandler<IImageButton, UIButton>
99

1010
protected override UIButton CreatePlatformView()
1111
{
12-
var platformView = new UIButton(UIButtonType.System)
12+
var platformView = new UIButton(UIButtonType.System);
13+
14+
// Starting with iOS 15, we can use the UIButton.Configuration and assign future UIButton.Configuration.ContentInsets here instead of the deprecated UIButton.ContentEdgeInsets.
15+
// It is important to note that the configuration will change any set style changes so we will do this right after creating the button.
16+
if (OperatingSystem.IsIOSVersionAtLeast(15))
1317
{
14-
ClipsToBounds = true
15-
};
18+
platformView.Configuration = UIButtonConfiguration.PlainButtonConfiguration;
19+
}
20+
21+
platformView.ClipsToBounds = true;
1622

1723
return platformView;
1824
}

src/Core/src/Platform/iOS/ButtonExtensions.cs

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,18 @@ public static void UpdateCharacterSpacing(this UIButton platformButton, ITextSty
5454
public static void UpdateFont(this UIButton platformButton, ITextStyle textStyle, IFontManager fontManager)
5555
{
5656
platformButton.TitleLabel.UpdateFont(textStyle, fontManager, UIFont.ButtonFontSize);
57+
58+
// If iOS 15+, update the configuration with the new font
59+
if (OperatingSystem.IsIOSVersionAtLeast(15) && platformButton.Configuration is UIButtonConfiguration config)
60+
{
61+
config.TitleTextAttributesTransformer = (incoming) =>
62+
{
63+
var outgoing = incoming;
64+
outgoing[UIStringAttributeKey.Font] = platformButton.TitleLabel.Font;
65+
return outgoing;
66+
};
67+
platformButton.Configuration = config;
68+
}
5769
}
5870

5971
public static void UpdatePadding(this UIButton platformButton, IButton button, Thickness? defaultPadding = null) =>
@@ -73,15 +85,24 @@ public static void UpdatePadding(this UIButton platformButton, Thickness padding
7385
if (bottom == 0.0)
7486
bottom = AlmostZero;
7587

76-
#pragma warning disable CA1416 // TODO: 'UIButton.ContentEdgeInsets' is unsupported on: 'ios' 15.0 and later.
77-
#pragma warning disable CA1422 // Validate platform compatibility
78-
platformButton.ContentEdgeInsets = new UIEdgeInsets(
79-
(float)top,
80-
(float)padding.Left,
81-
(float)bottom,
82-
(float)padding.Right);
83-
#pragma warning restore CA1422 // Validate platform compatibility
84-
#pragma warning restore CA1416
88+
if (OperatingSystem.IsIOSVersionAtLeast(15) && platformButton.Configuration is not null)
89+
{
90+
var config = platformButton.Configuration;
91+
config.ContentInsets = new NSDirectionalEdgeInsets (
92+
(float)top,
93+
(float)padding.Left,
94+
(float)bottom,
95+
(float)padding.Right);
96+
platformButton.Configuration = config;
97+
}
98+
else if (!OperatingSystem.IsIOSVersionAtLeast(15))
99+
{
100+
platformButton.ContentEdgeInsets = new UIEdgeInsets(
101+
(float)top,
102+
(float)padding.Left,
103+
(float)bottom,
104+
(float)padding.Right);
105+
}
85106
}
86107
}
87108
}

0 commit comments

Comments
 (0)