FireMonkeyのコントロールはネイティブコントロールの上に表示することができません。
Delphi iOSアプリケーションでネイティブコントロールの上に画像を表示するために
ネイティブコントロールのUIImageViewをラップしたクラスを作成しました。
UIImageViewもネイティブコントロールのため、ネイティブコントロールの上に画像を表示できます。
使用例
FUIImageView := FMX.iOS.UIImageView.TUIImageView.Create(Layout1);
FUIImageView.ImageWrapMode := TImageWrapMode.Fit;
FUIImageView.SetBitmap(Bitmap);
ソースコード
unit FMX.iOS.UIImageView;
interface
uses
iOSapi.UIKit, iOSapi.CoreGraphics,
System.Classes, System.Types, FMX.Graphics,
FMX.Layouts, FMX.Forms, FMX.Objects;
type
TUIImageView = class
private
FUIImageView: iOSapi.UIKit.UIImageView;
FLayout: TLayout;
FImageWrapMode: TImageWrapMode;
procedure SetImageWrapMode(const Value: TImageWrapMode);
function GetForm: TCustomForm;
function GetLayoutRect: TRect;
function getFrame: CGRect;
public
constructor Create(const ALayout: TLayout);
destructor Destroy; override;
procedure SetBitmap(const ABitmap: TBitmap);
procedure Resize;
property ImageWrapMode: TImageWrapMode read FImageWrapMode
write SetImageWrapMode;
property frame: CGRect read getFrame;
property ImageView: iOSapi.UIKit.UIImageView read FUIImageView;
end;
implementation
uses
Macapi.Helpers, FMX.Helpers.iOS, iOSapi.Foundation, FMX.Platform.iOS,
System.SysUtils, FMX.Types;
{ TUIImageView }
constructor TUIImageView.Create(const ALayout: TLayout);
var
AForm: TCustomForm;
begin
FLayout := ALayout;
FUIImageView := iOSapi.UIKit.TUIImageView.Wrap
(iOSapi.UIKit.TUIImageView.Alloc.init);
FUIImageView.retain;
Resize;
AForm := GetForm;
if AForm <> nil then
WindowHandleToPlatform(AForm.Handle).View.addSubview(FUIImageView);
Self.ImageWrapMode := TImageWrapMode.Stretch;
end;
destructor TUIImageView.Destroy;
begin
if FUIImageView <> nil then
begin
FUIImageView.removeFromSuperview;
FUIImageView.release;
FUIImageView := nil;
end;
inherited;
end;
function TUIImageView.GetForm: TCustomForm;
var
Parent: TFmxObject;
begin
Parent := FLayout.Parent;
while True do
begin
if Parent = nil then
Exit(nil);
if Parent is TForm then
Exit(Parent as TForm);
Parent := Parent.Parent;
end;
end;
function TUIImageView.getFrame: CGRect;
begin
Result := FUIImageView.frame;
end;
function TUIImageView.GetLayoutRect: TRect;
var
ATopLeft, ABottomRight: TPoint;
begin
if FLayout = nil then
begin
Log.d('Layout = nil');
Exit(Rect(0, 0, 0, 0));
end;
ATopLeft := FLayout.LocalToAbsolute(PointF(0, 0)).Truncate;
ABottomRight := ATopLeft.Add(PointF(FLayout.width, FLayout.height).Truncate);
Result := System.Classes.Rect(ATopLeft, ABottomRight);
end;
procedure TUIImageView.Resize;
begin
FUIImageView.setFrame(Macapi.Helpers.RectToNSRect(GetLayoutRect));
end;
procedure TUIImageView.SetBitmap(const ABitmap: TBitmap);
var
Image: UIImage;
AutoreleasePool: NSAutoreleasePool;
begin
AutoreleasePool := TNSAutoreleasePool.Create;
try
Image := FMX.Helpers.iOS.BitmapToUIImage(ABitmap);
FUIImageView.setImage(Image);
finally
AutoreleasePool.release
end;
end;
procedure TUIImageView.SetImageWrapMode(const Value: TImageWrapMode);
begin
FImageWrapMode := Value;
case Value of
TImageWrapMode.Fit: // コントロールの四角形にちょうど合うように調整します(画像の比率は保たれます)。
FUIImageView.setContentMode(UIViewContentModeScaleAspectFit);
TImageWrapMode.Stretch: // 画像を引き伸ばして、コントロールの四角形全体を埋めます。
FUIImageView.setContentMode(UIViewContentModeScaleToFill);
TImageWrapMode.Original: // 画像を元のサイズで表示します。
FUIImageView.setContentMode(UIViewContentModeTopLeft);
TImageWrapMode.Center: // 画像をコントロールの四角形の中央に表示します。
FUIImageView.setContentMode(UIViewContentModeCenter);
TImageWrapMode.Tile: // 画像を敷き詰めて(画像の数を増やして)、コントロールの四角形全体を覆います。
raise System.SysUtils.ENotImplemented.Create('TImageWrapMode.Tile');
end;
end;
end.
サンプルプログラム
TWebBrowserコントロールはネイティブコントロールのため、その上にコンポーネントを配置できません。
このサンプルプログラムでは、TWebBrowserコントロールの上にTUIImageViewを配置して、画像を表示します。
実行例は次のようになります。
フォームにTWebBrowserコントロールとTLayoutコントロールを配置します。
TLayoutコントロールはTUIImageViewの配置場所になります。
メニューの「プロジェクト」→「リソースと画像」を選択し、表示する画像を追加します。
今回使用した画像は次の画像です。
画像を読み込む関数を作成します。
function GetImage: TBitmap;
var
RS: TResourceStream;
begin
Result := TBitmap.Create;
RS := TResourceStream.Create(HInstance, 'PngImage_1', RT_RCDATA);
try
Result.LoadFromStream(RS);
finally
RS.Free;
end;
end;
フォームにprivate変数にTUIImageViewを追加します。
type
TForm1 = class(TForm)
WebBrowser1: TWebBrowser;
Layout1: TLayout;
procedure FormCreate(Sender: TObject);
private
{ private 宣言 }
FUIImageView: TUIImageView;
public
{ public 宣言 }
end;
フォームのOnCreateイベントで、TWebBrowserコントロールにURLを指定してアクセスします。
procedure TForm1.FormCreate(Sender: TObject);
begin
WebBrowser1.Navigate('http://www.gesource.jp/weblog/');
end;
フォームのOnCreateイベントにTUIImageViewを作成する処理を追加します。
uses
FMX.Objects;
procedure TForm1.FormCreate(Sender: TObject);
var
Bitmap: TBitmap;
begin
WebBrowser1.Navigate('http://www.gesource.jp/weblog/');
FUIImageView := FMX.iOS.UIImageView.TUIImageView.Create(Layout1);
FUIImageView.ImageWrapMode := TImageWrapMode.Fit;
Bitmap := GetImage;
try
FUIImageView.SetBitmap(Bitmap);
finally
Bitmap.Free;
end;
end;
アプリケーションを実行すると、ブラウザの上に画像が表示されます。