主にプログラミング関連のメモ帳 ♪(✿╹ヮ╹)ノ
書いてあるコードは自己責任でご自由にどうぞ。記事本文の無断転載は禁止です。
2016/03/28
新しいノートパソコン超快適で幸せです。
UWP の入力フォームなどで、タッチキーボード*1を表示すると、隠れてしまう要素があります。
しかしながら、ガイドラインにもあるように、常に表示しておくのが良い要素もあります。
私が探した限りでは、標準で楽に実装できるものがなさそうだったので、
やり方をメモしておきます。
キーボードに隠れると困る要素というのは、例えば、送信フォームの「送信」ボタンだとか。
Twitter で言えば、画像添付だとか、そういうのは隠れると、ちょっと不便になってしまいます。
ちょうど、 Twitter 公式アプリも、そういった要素はキーボードで隠れないようにされています。
ということで、早速実装。
<Page x:Class="UniversalApp10.Views.Pages.TweetPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:mvvm="using:Prism.Windows.Mvvm"
xmlns:vm="using:UniversalApp10.ViewModels.Pages"
d:DataContext="{d:DesignInstance vm:TweetPageViewModel}"
d:DesignHeight="300"
d:DesignWidth="400"
mvvm:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d">
<RelativePanel x:Name="Root" VerticalAlignment="Stretch">
<RelativePanel x:Name="Header"
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.AlignRightWithPanel="True"
RelativePanel.AlignTopWithPanel="True">
<Grid x:Name="TweetCounter"
Height="64"
RelativePanel.AlignRightWithPanel="True">
<TextBlock Margin="0,0,10,0"
VerticalAlignment="Center"
FontSize="15"
Text="{x:Bind ViewModel.WhisperCount, Mode=TwoWay}" />
</Grid>
<StackPanel Height="64"
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.LeftOf="TweetCounter"
Orientation="Horizontal">
<Image Width="48"
Height="48"
Source="{x:Bind ViewModel.User.Icon}" />
<StackPanel Margin="10,0">
<TextBlock FontSize="16" Text="{x:Bind ViewModel.User.Name}" />
<TextBlock FontSize="14" Foreground="Silver" Text="{x:Bind ViewModel.User.ScreenName}" />
</StackPanel>
</StackPanel>
</RelativePanel>
<Grid x:Name="Footer"
Height="32"
RelativePanel.AlignBottomWithPanel="True"
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.AlignRightWithPanel="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0"
HorizontalAlignment="Stretch"
Content="@" />
<Button Grid.Column="1"
HorizontalAlignment="Stretch"
Content="#" />
<Button Grid.Column="2" HorizontalAlignment="Stretch">
<Button.Content>
<FontIcon Glyph="" />
</Button.Content>
</Button>
<Button Grid.Column="3"
HorizontalAlignment="Stretch"
Background="{StaticResource SystemControlHighlightAccentBrush}"
Content="Tweet" />
</Grid>
<TextBox HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
AcceptsReturn="True"
RelativePanel.Above="Footer"
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.AlignRightWithPanel="True"
RelativePanel.Below="Header"
TextWrapping="Wrap" />
</RelativePanel>
</Page>
長いですが、なんとなく公式 Twitter アプリのツイート画面っぽいレイアウトになっています。
次は、コードビハインド側です。
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using UniversalApp10.ViewModels.Pages;
// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236
namespace UniversalApp10.Views.Pages
{
public sealed partial class TweetPage : Page
{
private readonly InputPane _inputPane;
private double? _rootHeight;
public TweetPage()
{
InitializeComponent();
_inputPane = InputPane.GetForCurrentView();
_rootHeight = null;
}
public TweetPageViewModel ViewModel => DataContext as TweetPageViewModel;
private void OnKeyboardShowing(InputPane sender, InputPaneVisibilityEventArgs args)
{
_rootHeight = !_rootHeight.HasValue ? Root.ActualHeight : _rootHeight;
Root.Height = _rootHeight.Value- sender.OccludedRect.Height; // *
Root.VerticalAlignment = VerticalAlignment.Top;
}
private void OnKeyboardHiding(InputPane sender, InputPaneVisibilityEventArgs args)
{
if (!_rootHeight.HasValue)
return;
Root.Height = _rootHeight.Value;
Root.VerticalAlignment = VerticalAlignment.Stretch;
}
#region Overrides of Page
protected override void OnNavigatedTo(NavigationEventArgs e)
{
_inputPane.Hiding += OnKeyboardHiding;
_inputPane.Showing += OnKeyboardShowing;
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
_inputPane.Hiding -= OnKeyboardHiding;
_inputPane.Showing -= OnKeyboardShowing;
}
#endregion Overrides of Page
}
}
ガイドラインにあるとおり、 InputPane
のイベントで処理を行います。
OnKeyboardShowing
では、元の高さの保存と、キーボード分の高さの調節を行っています。
また、なぜか、 OnKeyboardHiding
が呼ばれずに、再度 OnKeyboardShowing
が
呼ばれることがあったので、一応元の高さを使って計算しています。
OnKeyboardHiding
では、キーボードがない状態へと、要素の高さを復元しています。
上の通り、たまに呼ばれません。イミフです。
これで、タッチキーボードの上に、何らかの要素(今回の場合は、 Footer
) が表示されます。
なお、 CommandBar
を一番下に表示しているなどで、
Root.Height != Window.Current.Bounds.Height
な場合は、
*
が付いてるところで調節を行えば、うまい具合に表示することが可能です。
ということで、ではでは~。(他に実装方法があったら教えて下さい)
*1:ソフトウェアキーボードやスクリーンキーボードともいう