Skip to content

Commit d9049ea

Browse files
authored
Merge pull request #3 from Redth/dev/redth/new-button-api
Padding, Hot Reload Support, Better UIButton Usage
2 parents 1a76392 + 7f42721 commit d9049ea

11 files changed

+212
-206
lines changed

Maui.ContentButton/Apple/ContentButtonHandler.ios.maccatalyst.cs

Lines changed: 48 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -12,106 +12,68 @@ public partial class ContentButtonHandler : ViewHandler<IContentButton, MButton>
1212

1313
public readonly static Thickness DefaultPadding = new Thickness(12, 7);
1414

15-
// Because we can't inherit from Button we use the container to handle
16-
// Life cycle events and things like monitoring focus changed
17-
public override bool NeedsContainer => true;
18-
15+
public const int ContentButtonHandlerContentViewTag = 23123;
1916

2017
protected override UIButton CreatePlatformView()
2118
{
22-
var button = new UIButton(UIButtonType.System);
23-
SetControlPropertiesFromProxy(button);
24-
25-
button.ClipsToBounds = true;
26-
button.AddSubview(new MauiButtonContentView
27-
{
19+
var button = new MauiAppleButton {
2820
CrossPlatformLayout = VirtualView,
29-
});
30-
31-
return button;
32-
}
33-
34-
readonly ButtonEventProxy _proxy = new ButtonEventProxy();
21+
ClipsToBounds = true,
22+
Configuration = UIButtonConfiguration.BorderedButtonConfiguration,
23+
TouchesHandlers = new MauiAppleButtonTouches(VirtualView.Pressed, VirtualView.Released, VirtualView.Clicked)
24+
};
3525

36-
protected override void SetupContainer()
37-
{
38-
base.SetupContainer();
39-
40-
// We need to use reflection on this internal only property
41-
(ContainerView as WrapperView)?.SetCrossPlatformLayout(VirtualView);
42-
}
43-
44-
protected override void ConnectHandler(MButton platformView)
45-
{
46-
_proxy.Connect(VirtualView, platformView);
47-
48-
base.ConnectHandler(platformView);
49-
}
50-
51-
protected override void DisconnectHandler(MButton platformView)
52-
{
53-
_proxy.Disconnect(platformView);
26+
SetControlPropertiesFromProxy(button);
5427

55-
base.DisconnectHandler(platformView);
28+
return button;
5629
}
30+
31+
5732

58-
#if MACCATALYST
5933
public static void MapBackground(IContentButtonHandler handler, IContentButton button)
6034
{
61-
//If this is a Mac optimized interface
62-
if (OperatingSystem.IsIOSVersionAtLeast(15) && UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Mac)
63-
{
64-
var config = handler.PlatformView?.Configuration ?? UIButtonConfiguration.BorderedButtonConfiguration;
65-
if (button?.Background is Paint paint)
66-
{
67-
if (paint is SolidPaint solidPaint)
68-
{
69-
Color backgroundColor = solidPaint.Color;
70-
71-
if (backgroundColor == null)
72-
{
73-
if (OperatingSystem.IsIOSVersionAtLeast(13))
74-
config.BaseBackgroundColor = UIColor.SystemBackground;
75-
else
76-
config.BaseBackgroundColor = UIColor.White;
77-
}
78-
else
79-
{
80-
config.BaseBackgroundColor = backgroundColor.ToPlatform();
81-
}
82-
83-
}
84-
}
85-
if (handler.PlatformView != null)
86-
handler.PlatformView.Configuration = config;
87-
}
88-
else
35+
if (handler.PlatformView.Configuration is not null)
8936
{
90-
handler.PlatformView?.UpdateBackground(button);
37+
var con = handler.PlatformView.Configuration;
38+
con.Background.BackgroundColor = button.Background?.ToColor()?.ToPlatform();
39+
handler.PlatformView.Configuration = con;
9140
}
9241
}
93-
#endif
9442

9543
public static void MapStrokeColor(IContentButtonHandler handler, IButtonStroke buttonStroke)
9644
{
97-
handler.PlatformView?.UpdateStrokeColor(buttonStroke);
45+
if (handler.PlatformView.Configuration is not null)
46+
{
47+
var con = handler.PlatformView.Configuration;
48+
con.Background.StrokeColor = buttonStroke.StrokeColor?.ToPlatform();
49+
handler.PlatformView.Configuration = con;
50+
}
9851
}
9952

10053
public static void MapStrokeThickness(IContentButtonHandler handler, IButtonStroke buttonStroke)
10154
{
102-
handler.PlatformView?.UpdateStrokeThickness(buttonStroke);
55+
if (handler.PlatformView.Configuration is not null)
56+
{
57+
var con = handler.PlatformView.Configuration;
58+
con.Background.StrokeWidth = (float)buttonStroke.StrokeThickness;
59+
handler.PlatformView.Configuration = con;
60+
}
10361
}
10462

10563
public static void MapCornerRadius(IContentButtonHandler handler, IButtonStroke buttonStroke)
10664
{
107-
handler.PlatformView?.UpdateCornerRadius(buttonStroke);
65+
if (handler.PlatformView.Configuration is not null)
66+
{
67+
var con = handler.PlatformView.Configuration;
68+
con.Background.CornerRadius = buttonStroke.CornerRadius;
69+
handler.PlatformView.Configuration = con;
70+
}
10871
}
10972

110-
// public static void MapPadding(IContentButtonHandler handler, IPadding padding)
111-
// {
112-
// handler.PlatformView?.UpdatePadding(padding.Padding, DefaultPadding);
113-
// }
114-
73+
public static void MapPadding(IContentButtonHandler handler, IPadding padding)
74+
{
75+
handler.PlatformView?.UpdatePadding(padding.Padding, DefaultPadding);
76+
}
11577

11678
static void SetControlPropertiesFromProxy(UIButton platformView)
11779
{
@@ -121,68 +83,28 @@ static void SetControlPropertiesFromProxy(UIButton platformView)
12183
}
12284
}
12385

124-
class ButtonEventProxy
125-
{
126-
WeakReference<IContentButton>? _virtualView;
127-
128-
IContentButton? VirtualView => _virtualView is not null && _virtualView.TryGetTarget(out var v) ? v : null;
129-
130-
public void Connect(IContentButton virtualView, UIButton platformView)
131-
{
132-
_virtualView = new(virtualView);
133-
134-
platformView.TouchUpInside += OnButtonTouchUpInside;
135-
platformView.TouchUpOutside += OnButtonTouchUpOutside;
136-
platformView.TouchDown += OnButtonTouchDown;
137-
}
138-
139-
public void Disconnect(UIButton platformView)
140-
{
141-
_virtualView = null;
142-
143-
platformView.TouchUpInside -= OnButtonTouchUpInside;
144-
platformView.TouchUpOutside -= OnButtonTouchUpOutside;
145-
platformView.TouchDown -= OnButtonTouchDown;
146-
}
147-
148-
void OnButtonTouchUpInside(object? sender, EventArgs e)
149-
{
150-
if (VirtualView is IContentButton virtualView)
151-
{
152-
virtualView.Released();
153-
virtualView.Clicked();
154-
}
155-
}
156-
157-
void OnButtonTouchUpOutside(object? sender, EventArgs e)
158-
{
159-
VirtualView?.Released();
160-
}
161-
162-
void OnButtonTouchDown(object? sender, EventArgs e)
163-
{
164-
VirtualView?.Pressed();
165-
}
166-
}
167-
16886
public static void MapContent(IContentButtonHandler handler, IContentButton view)
16987
{
17088
_ = handler.PlatformView ?? throw new InvalidOperationException($"{nameof(PlatformView)} should have been set by base class.");
17189
_ = handler.VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} should have been set by base class.");
17290
_ = handler.MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class.");
17391

174-
var contentSubview = handler.PlatformView.FindDescendantView<MauiButtonContentView>();
175-
if (contentSubview is not null)
92+
// Remove the known content subview (by tag) if it exists
93+
for (var i = 0; i < handler.PlatformView.Subviews.Length; i++)
17694
{
177-
contentSubview.ClearSubviews();
178-
179-
if (handler.VirtualView.PresentedContent is IView presentedView)
95+
var subview = handler.PlatformView.Subviews[i];
96+
if (subview.Tag == ContentButtonHandlerContentViewTag)
18097
{
181-
var inner = presentedView.ToPlatform(handler.MauiContext);
182-
contentSubview.AddSubview(inner);
98+
subview.RemoveFromSuperview();
99+
break;
183100
}
101+
}
184102

185-
contentSubview.SetNeedsLayout();
103+
if (handler.VirtualView.PresentedContent is IView presentedView)
104+
{
105+
var inner = presentedView.ToPlatform(handler.MauiContext);
106+
inner.Tag = ContentButtonHandlerContentViewTag;
107+
handler.PlatformView.AddSubview(inner);
186108
}
187109
}
188110
}

Maui.ContentButton/Apple/MauiButtonContentView.ios.maccatalyst.cs renamed to Maui.ContentButton/Apple/MauiAppleButton.ios.maccatalyst.cs

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
#if IOS || MACCATALYST
2+
using UIKit;
23
using CoreGraphics;
4+
using Foundation;
35
using Microsoft.Maui.Platform;
4-
using UIKit;
56

67
namespace MauiContentButton;
78

8-
public class MauiButtonContentView : UIView, ICrossPlatformLayoutBacking
9+
public class MauiAppleButton : UIButton, ICrossPlatformLayoutBacking
910
{
1011
bool _fireSetNeedsLayoutOnParentWhenWindowAttached;
1112

@@ -14,6 +15,8 @@ public class MauiButtonContentView : UIView, ICrossPlatformLayoutBacking
1415

1516
WeakReference<ICrossPlatformLayout>? _crossPlatformLayoutReference;
1617

18+
public MauiAppleButtonTouches? TouchesHandlers { get; set; }
19+
1720
protected bool IsMeasureValid(double widthConstraint, double heightConstraint)
1821
{
1922
// Check the last constraints this View was measured with; if they're the same,
@@ -78,10 +81,7 @@ public override void LayoutSubviews()
7881
return;
7982
}
8083

81-
// IMPORTANT: Use the superview's bounds for the measurement constraints
82-
// This is the big change from the MauiView implementation, since we want to layout
83-
// and then measure if needed, based on the superview/container bounds
84-
var bounds = (Superview?.Bounds ?? Bounds).ToRectangle();
84+
var bounds = Bounds.ToRectangle();
8585

8686
var widthConstraint = bounds.Width;
8787
var heightConstraint = bounds.Height;
@@ -133,5 +133,33 @@ public override void MovedToWindow()
133133
//_movedToWindow?.Invoke(this, EventArgs.Empty);
134134
TryToInvalidateSuperView(true);
135135
}
136+
137+
138+
public override void TouchesBegan(NSSet touches, UIEvent? evt)
139+
{
140+
base.TouchesBegan(touches, evt);
141+
142+
TouchesHandlers?.PressedHandler?.Invoke();
143+
}
144+
145+
public override void TouchesEnded(NSSet touches, UIEvent? evt)
146+
{
147+
base.TouchesEnded(touches, evt);
148+
149+
TouchesHandlers?.ReleasedHandler?.Invoke();
150+
151+
if (touches?.FirstOrDefault() is UITouch touch)
152+
{
153+
var point = touch.LocationInView(this);
154+
if (this.PointInside(point, evt)) {
155+
// didTouchUpInside
156+
TouchesHandlers?.ClickedHandler?.Invoke();
157+
}
158+
}
159+
}
160+
}
161+
162+
public record MauiAppleButtonTouches(Action PressedHandler, Action ReleasedHandler, Action ClickedHandler)
163+
{
136164
}
137-
#endif
165+
#endif

Maui.ContentButton/Apple/WrapperViewExtensions.ios.maccatalyst.cs

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)