Xamarin.FormsのiOSでEntryがKeyboardで隠れないようにするBehavior
Androidはよしなに隠れないようにしてくれてるみたいですが、iOSはやっぱり隠れてしまうので隠れないようにするBehavior作りました。
ほんとは
NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.WillShowNotification, n => { var h = ((NSValue)n.UserInfo[UIKeyboard.FrameBeginUserInfoKey]).CGRectValue.Height; var v =((NSNumber) n.UserInfo[UIKeyboard.AnimationDurationUserInfoKey]).DoubleValue; … }
などで高さやアニメーションのデュレーションとってやらないとだめだと思いますが、それだとBehaviorにしにくいじゃないですかーということでマジックナンバーで手抜き。
<Entry Text="{Binding Pass}" HorizontalOptions="FillAndExpand"> <Entry.Behaviors> <appCommon:NoHiddenBehavior RootView="{x:Reference rootGrid}"/> </Entry.Behaviors> </Entry>
などとすれば使えると思います。rootGridはそのページの一番上のViewです。ContentViewでもいいのではと思いますが、その下のを今回は指定してます。
以下Behaviorのソース。OnDetachingFromも手抜いてます。
public class NoHiddenBehavior : Behavior<Entry> { public View RootView { get; set; } public double Margin { get; set; } public uint AnimateDuration { get; set; } public double KeyboardHeight { get; set; } public NoHiddenBehavior() { Margin = 10; AnimateDuration = 200; KeyboardHeight = 216; } protected override void OnAttachedTo(Entry entry) { entry.Focused += (sender, e) => { if (Device.OS == TargetPlatform.iOS) { var y = RelatedY(RootView,entry); var scroll = RootView.Height - y - entry.Height-Margin - KeyboardHeight; if(scroll<0) RootView.TranslateTo(0, scroll, AnimateDuration); } }; entry.Unfocused += (sender, e) => { if (Device.OS == TargetPlatform.iOS) { RootView.TranslateTo(0, 0, AnimateDuration); } }; } protected override void OnDetachingFrom(Entry entry) { } double RelatedY(View prmParent, View button) { var y = button.Y; var parent = (VisualElement)button.Parent; while (parent != prmParent) { y += parent.Y; parent = (VisualElement)parent.Parent; } return y; } }
※追記
ScrollViewの中にあるもののことなどは何も考えてないのでご注意ください。