Added support to the iOS layout handlers to support when a handler’s native view changes.

This commit is contained in:
Jon Lipsky 2019-07-09 23:17:28 -07:00
Родитель 7efcd79d24
Коммит 0e548c2d6c
23 изменённых файлов: 194 добавлений и 49 удалений

Просмотреть файл

@ -60,9 +60,9 @@
<PackageReference Include="Xamarin.Android.Support.v7.MediaRouter" Version="28.0.0.1" />
<PackageReference Include="Xamarin.Android.Support.Core.Utils" Version="28.0.0.1" />
<PackageReference Include="Xamarin.Android.Support.CustomTabs" Version="28.0.0.1" />
<PackageReference Include="Xamarin.Essentials" Version="1.1.0" />
<PackageReference Include="Xamarin.Essentials" Version="1.2.0" />
<PackageReference Include="Xamarin.Forms">
<Version>4.0.0.497661</Version>
<Version>4.1.0.581479</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>

Просмотреть файл

@ -126,9 +126,9 @@
<Reference Include="System.Numerics.Vectors" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Xamarin.Essentials" Version="1.1.0" />
<PackageReference Include="Xamarin.Essentials" Version="1.2.0" />
<PackageReference Include="Xamarin.Forms">
<Version>4.0.0.497661</Version>
<Version>4.1.0.581479</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>

Просмотреть файл

@ -15,8 +15,8 @@
<LangVersion>7.2</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Xamarin.Forms" Version="4.0.0.497661" />
<PackageReference Include="Xamarin.Essentials" Version="1.1.0" />
<PackageReference Include="Xamarin.Forms" Version="4.1.0.581479" />
<PackageReference Include="Xamarin.Essentials" Version="1.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\HotUI\HotUI.csproj" />

Просмотреть файл

@ -104,7 +104,7 @@
<PackageReference Include="Xamarin.Android.Support.Design" Version="28.0.0.1" />
<PackageReference Include="Xamarin.Android.Support.Core.Utils" Version="28.0.0.1" />
<PackageReference Include="Xamarin.Android.Support.CustomTabs" Version="28.0.0.1" />
<PackageReference Include="Xamarin.Essentials" Version="1.1.0" />
<PackageReference Include="Xamarin.Essentials" Version="1.2.0" />
<PackageReference Include="Xamarin.FFImageLoading">
<Version>2.4.11.982</Version>
</PackageReference>

Просмотреть файл

@ -31,7 +31,7 @@ namespace HotUI.Samples {
new MenuItem("SwiftUI Tutorial Section 4", ()=> new Section4()),
new MenuItem("SwiftUI Tutorial Section 4b", ()=> new Section4b()),
new MenuItem("SwiftUI Tutorial Section 4c", ()=> new Section4c()),
};
};
public MainPage ()
{
Body = () => new NavigationView {

Просмотреть файл

@ -74,8 +74,8 @@
<Reference Include="System.Numerics.Vectors" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="HotUI.Reload" Version="0.0.2-alpha" />
<PackageReference Include="Xamarin.Essentials" Version="1.1.0" />
<PackageReference Include="HotUI.Reload" Version="0.0.5-alpha" />
<PackageReference Include="Xamarin.Essentials" Version="1.2.0" />
<PackageReference Include="Xamarin.FFImageLoading">
<Version>2.4.11.982</Version>
</PackageReference>

Просмотреть файл

@ -87,7 +87,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Xamarin.Android.Support.v7.AppCompat" Version="28.0.0.1" />
<PackageReference Include="Xamarin.Essentials" Version="1.1.0" />
<PackageReference Include="Xamarin.Essentials" Version="1.2.0" />
<PackageReference Include="Xamarin.FFImageLoading" Version="2.4.11.982" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />

Просмотреть файл

@ -15,7 +15,7 @@
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Xamarin.Forms" Version="4.0.0.497661" />
<PackageReference Include="Xamarin.Forms" Version="4.1.0.581479" />
</ItemGroup>
<ItemGroup>
<Folder Include="Handlers\" />

Просмотреть файл

@ -115,6 +115,9 @@ namespace HotUI.iOS.Controls
get => _maskLayer;
set
{
if (_maskLayer != null)
_mainView.Layer.Mask = null;
_maskLayer = value;
if (_mainView != null)
_mainView.Layer.Mask = value;

Просмотреть файл

@ -12,8 +12,9 @@ namespace HotUI.iOS
private TVirtualView _virtualView;
private TNativeView _nativeView;
private HUIContainerView _containerView;
public EventHandler ViewChanged { get; set; }
public event EventHandler<ViewChangedEventArgs> NativeViewChanged;
public event EventHandler RemovedFromView;
protected AbstractHandler(PropertyMapper<TVirtualView> mapper)
{
@ -39,12 +40,15 @@ namespace HotUI.iOS
{
if (!value && _containerView != null)
{
var previousContainerView = _containerView;
_containerView.ShadowLayer = null;
_containerView.MaskLayer = null;
_containerView = null;
_nativeView.Layer.Mask = null;
_nativeView.RemoveFromSuperview();
ViewChanged?.Invoke(this, EventArgs.Empty);
NativeViewChanged?.Invoke(this, new ViewChangedEventArgs(VirtualView, previousContainerView, _nativeView));
return;
}
@ -52,7 +56,7 @@ namespace HotUI.iOS
{
_containerView = new HUIContainerView();
_containerView.MainView = _nativeView;
ViewChanged?.Invoke(this, EventArgs.Empty);
NativeViewChanged?.Invoke(this, new ViewChangedEventArgs(VirtualView, _nativeView, _containerView));
}
}
}
@ -67,6 +71,8 @@ namespace HotUI.iOS
_nativeView.RemoveFromSuperview();
_containerView = null;
}
RemovedFromView?.Invoke(this, EventArgs.Empty);
}
public virtual void SetView(View view)

Просмотреть файл

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using CoreGraphics;
@ -14,8 +15,9 @@ namespace HotUI.iOS
private Size _measured;
private bool _measurementValid;
public AbstractLayout Layout => _view;
public event EventHandler<ViewChangedEventArgs> NativeViewChanged;
public event EventHandler RemovedFromView;
protected AbstractLayoutHandler(CGRect rect, ILayoutManager<UIView> layoutManager) : base(rect)
{
_layoutManager = layoutManager;
@ -27,6 +29,8 @@ namespace HotUI.iOS
_layoutManager = layoutManager;
}
public AbstractLayout Layout => _view;
public Size Measure(UIView view, Size available)
{
CGSize size;
@ -85,6 +89,9 @@ namespace HotUI.iOS
public void SetView(View view)
{
if (_view != null)
Console.WriteLine("Removed should have been called beforehand.");
_view = view as AbstractLayout;
if (_view != null)
{
@ -92,9 +99,15 @@ namespace HotUI.iOS
_view.ChildrenAdded += HandleChildrenAdded;
_view.ChildrenRemoved += ViewOnChildrenRemoved;
foreach (var subView in _view)
foreach (var subview in _view)
{
var nativeView = subView.ToView() ?? new UIView();
if (subview.ViewHandler is iOSViewHandler handler)
{
handler.RemovedFromView += HandleHandlerRemovedFromView;
handler.NativeViewChanged += HandleSubviewChanged;
}
var nativeView = subview.ToView() ?? new UIView();
AddSubview(nativeView);
}
@ -105,16 +118,45 @@ namespace HotUI.iOS
public void Remove(View view)
{
foreach (var subview in Subviews)
subview.RemoveFromSuperview();
if (view != null)
foreach (var subview in _view)
{
_view.ChildrenChanged -= HandleChildrenChanged;
_view.ChildrenAdded -= HandleChildrenAdded;
_view.ChildrenRemoved -= ViewOnChildrenRemoved;
_view = null;
if (subview.ViewHandler is iOSViewHandler handler)
{
handler.RemovedFromView -= HandleHandlerRemovedFromView;
handler.NativeViewChanged -= HandleSubviewChanged;
}
}
foreach (var subview in Subviews)
{
subview.RemoveFromSuperview();
}
_view.ChildrenChanged -= HandleChildrenChanged;
_view.ChildrenAdded -= HandleChildrenAdded;
_view.ChildrenRemoved -= ViewOnChildrenRemoved;
_view = null;
RemovedFromView?.Invoke(this, EventArgs.Empty);
}
private void HandleHandlerRemovedFromView(object sender, EventArgs e)
{
var handler = (iOSViewHandler)sender;
handler.RemovedFromView -= HandleHandlerRemovedFromView;
handler.NativeViewChanged -= HandleSubviewChanged;
}
private void HandleSubviewChanged(object sender, ViewChangedEventArgs args)
{
Console.WriteLine($"HandlerViewChanged: [{sender.GetType()}] From:[{args.OldNativeView.GetType()}] To:[{args.NewNativeView.GetType()}]");
if (args.OldNativeView != null)
args.OldNativeView.RemoveFromSuperview();
var index = _view.IndexOf(args.VirtualView);
var newView = args.NewNativeView ?? new UIView();
InsertSubview(newView, index);
}
public virtual void UpdateValue(string property, object value)
@ -133,6 +175,13 @@ namespace HotUI.iOS
{
var index = e.Start + i;
var view = _view[index];
if (view.ViewHandler is iOSViewHandler handler)
{
handler.RemovedFromView += HandleHandlerRemovedFromView;
handler.NativeViewChanged += HandleSubviewChanged;
}
var nativeView = view.ToView() ?? new UIView();
InsertSubview(nativeView, index);
}
@ -143,6 +192,18 @@ namespace HotUI.iOS
private void ViewOnChildrenRemoved(object sender, LayoutEventArgs e)
{
if (e.Removed != null)
{
foreach (var view in e.Removed)
{
if (view.ViewHandler is iOSViewHandler handler)
{
handler.RemovedFromView -= HandleHandlerRemovedFromView;
handler.NativeViewChanged -= HandleSubviewChanged;
}
}
}
for (var i = 0; i < e.Count; i++)
{
var index = e.Start + i;
@ -156,6 +217,18 @@ namespace HotUI.iOS
private void HandleChildrenChanged(object sender, LayoutEventArgs e)
{
if (e.Removed != null)
{
foreach (var view in e.Removed)
{
if (view.ViewHandler is iOSViewHandler handler)
{
handler.RemovedFromView -= HandleHandlerRemovedFromView;
handler.NativeViewChanged -= HandleSubviewChanged;
}
}
}
for (var i = 0; i < e.Count; i++)
{
var index = e.Start + i;
@ -163,6 +236,13 @@ namespace HotUI.iOS
oldNativeView.RemoveFromSuperview();
var view = _view[index];
if (view.ViewHandler is iOSViewHandler handler)
{
handler.RemovedFromView += HandleHandlerRemovedFromView;
handler.NativeViewChanged += HandleSubviewChanged;
}
var newNativeView = view.ToView() ?? new UIView();
InsertSubview(newNativeView, index);
}
@ -186,7 +266,7 @@ namespace HotUI.iOS
}
public override CGSize IntrinsicContentSize => _measured.ToCGSize();
public override void LayoutSubviews()
{
if (Superview == null || Bounds.Size.IsEmpty)

Просмотреть файл

@ -12,7 +12,10 @@ namespace HotUI.iOS
private ContentView _contentView;
public UIView View => _view;
public event EventHandler<ViewChangedEventArgs> NativeViewChanged;
public event EventHandler RemovedFromView;
public object NativeView => View;
public HUIContainerView ContainerView => null;

Просмотреть файл

@ -35,6 +35,9 @@ namespace HotUI.iOS
public UIView View => this;
public event EventHandler<ViewChangedEventArgs> NativeViewChanged;
public event EventHandler RemovedFromView;
public HUIContainerView ContainerView => null;
public object NativeView => View;

Просмотреть файл

@ -23,6 +23,9 @@ namespace HotUI.iOS
public UIView View => this;
public event EventHandler<ViewChangedEventArgs> NativeViewChanged;
public event EventHandler RemovedFromView;
public HUIContainerView ContainerView => null;
public object NativeView => View;

Просмотреть файл

@ -1,4 +1,5 @@
using HotUI.iOS.Controls;
using System;
using HotUI.iOS.Controls;
using UIKit;
// ReSharper disable ClassNeverInstantiated.Global
@ -17,6 +18,9 @@ namespace HotUI.iOS
public UIView View => this;
public event EventHandler<ViewChangedEventArgs> NativeViewChanged;
public event EventHandler RemovedFromView;
public HUIContainerView ContainerView => null;
public object NativeView => View;

Просмотреть файл

@ -20,8 +20,9 @@ namespace HotUI.iOS
private View _view;
private UIView _body;
public Action ViewChanged { get; set; }
public event EventHandler<ViewChangedEventArgs> NativeViewChanged;
public event EventHandler RemovedFromView;
public UIView View => _body;
@ -39,10 +40,11 @@ namespace HotUI.iOS
public void SetView(View view)
{
var oldBody = _body;
_view = view;
SetBody();
Mapper.UpdateProperties(this, _view);
ViewChanged?.Invoke();
NativeViewChanged?.Invoke(this, new ViewChangedEventArgs(_view, oldBody, _body));
}
public void UpdateValue(string property, object value)
@ -137,7 +139,7 @@ namespace HotUI.iOS
{
var shadowLayer = new CAShapeLayer();
shadowLayer.Name = "shadow";
shadowLayer.FillColor = new CGColor(0,0,0,0);
shadowLayer.FillColor = new CGColor(0,0,0,1);
shadowLayer.Path = layer.Path;
shadowLayer.Frame = layer.Frame;
@ -149,6 +151,7 @@ namespace HotUI.iOS
}
else
{
nativeView.Layer.Mask = null;
handler.HasContainer = false;
}

Просмотреть файл

@ -70,6 +70,7 @@
<Compile Include="Handlers\ToggleHandler.cs" />
<Compile Include="HotUIView.cs" />
<Compile Include="Handlers\AbstractHandler.cs" />
<Compile Include="ViewChangedEventArgs.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\HotUI\HotUI.csproj">

Просмотреть файл

@ -32,14 +32,14 @@ namespace HotUI.iOS
_virtualView = value;
_handler = _virtualView.ToIUIView();
if (_handler is ViewHandler viewHandler)
viewHandler.ViewChanged = HandleViewChanged;
viewHandler.NativeViewChanged += HandleViewChanged;
HandleViewChanged();
HandleViewChanged(this, new ViewChangedEventArgs(_virtualView,null,null));
}
}
void HandleViewChanged()
void HandleViewChanged(object sender, ViewChangedEventArgs args)
{
if (_virtualView == null)
return;

Просмотреть файл

@ -0,0 +1,22 @@
using System;
using UIKit;
namespace HotUI.iOS
{
public class ViewChangedEventArgs : EventArgs
{
public View VirtualView { get; }
public UIView OldNativeView { get; }
public UIView NewNativeView { get; }
public ViewChangedEventArgs(
View view,
UIView oldNativeView,
UIView newNativeView)
{
VirtualView = view;
OldNativeView = oldNativeView;
NewNativeView = newNativeView;
}
}
}

Просмотреть файл

@ -5,7 +5,11 @@ namespace HotUI.iOS
{
public interface iOSViewHandler : IViewHandler
{
UIView View { get; }
HUIContainerView ContainerView { get; }
}
event EventHandler<ViewChangedEventArgs> NativeViewChanged;
event EventHandler RemovedFromView;
UIView View { get; }
HUIContainerView ContainerView { get; }
}
}

Просмотреть файл

@ -27,8 +27,9 @@ namespace HotUI
var count = _views.Count;
if (count > 0)
{
_views.Clear ();
ChildrenRemoved?.Invoke (this, new LayoutEventArgs (0, count));
var removed = new List<View>(_views);
_views.Clear ();
ChildrenRemoved?.Invoke (this, new LayoutEventArgs (0, count, removed));
}
}
@ -48,8 +49,9 @@ namespace HotUI
item.Parent = null;
item.Navigation = null;
var removed = new List<View> { item };
_views.Remove (item);
ChildrenRemoved?.Invoke (this, new LayoutEventArgs (index, 1));
ChildrenRemoved?.Invoke (this, new LayoutEventArgs (index, 1, removed));
return true;
}
@ -87,8 +89,9 @@ namespace HotUI
item.Parent = null;
item.Navigation = null;
var removed = new List<View> { item };
_views.RemoveAt(index);
ChildrenRemoved?.Invoke(this, new LayoutEventArgs(index, 1));
ChildrenRemoved?.Invoke(this, new LayoutEventArgs(index, 1, removed));
}
}
@ -100,13 +103,14 @@ namespace HotUI
var item = _views[index];
item.Parent = null;
item.Navigation = null;
var removed = new List<View> { item };
_views [index] = value;
_views[index] = value;
value.Parent = null;
value.Navigation = null;
ChildrenChanged?.Invoke (this, new LayoutEventArgs (index, 1));
ChildrenChanged?.Invoke (this, new LayoutEventArgs (index, 1, removed));
}
}

Просмотреть файл

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
namespace HotUI
{
@ -6,11 +7,19 @@ namespace HotUI
{
public int Start { get; }
public int Count { get; }
public List<View> Removed { get; }
public LayoutEventArgs(int start, int count)
{
Start = start;
Count = count;
}
public LayoutEventArgs(int start, int count, List<View> removed)
{
Start = start;
Count = count;
Removed = removed;
}
}
}

Просмотреть файл

@ -5,6 +5,6 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Xamarin.Forms" Version="4.0.0.497661" />
<PackageReference Include="Xamarin.Forms" Version="4.1.0.581479" />
</ItemGroup>
</Project>