質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Null

Nullとは、プログラミング言語やデータベースにおけるデータ表現の一種です。コンテキストによって"空"もしくは"長さ0の文字列"、”未知・不明”を意味します。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

UI

UIはUser Interfaceの略であり、人間がコンピュータとやりとりをするためのシステムです。

Xamarin

Xamarin(ザマリン)は、iPhoneなどのiOSやAndroidで動作し、C# 言語を用いてアプリを開発できるクロスプラットフォーム開発環境です。Xamarin Studioと C# 言語を用いて、 iOS と Android の両方の開発を行うことができます。

Q&A

解決済

1回答

3817閲覧

Xamarin.forms BoxViewに角丸をつける

gucchi28

総合スコア29

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Null

Nullとは、プログラミング言語やデータベースにおけるデータ表現の一種です。コンテキストによって"空"もしくは"長さ0の文字列"、”未知・不明”を意味します。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

UI

UIはUser Interfaceの略であり、人間がコンピュータとやりとりをするためのシステムです。

Xamarin

Xamarin(ザマリン)は、iPhoneなどのiOSやAndroidで動作し、C# 言語を用いてアプリを開発できるクロスプラットフォーム開発環境です。Xamarin Studioと C# 言語を用いて、 iOS と Android の両方の開発を行うことができます。

0グッド

0クリップ

投稿2016/12/20 06:59

こんにちは。
Xamarin.formsのBoxViewコントロールについて質問です。

BoxViewに角丸をつけたいのですが、
方法として、対象がiOSの場合
⑴ カスタムレンダラを使用して、iOSプラットフォームで記述する
⑵ Effects機能を使用して、iOSプラットフォームで記述する
を検討しています。

⑴の場合は、描画時にsharedプロジェクト側で指定した大きさにならず、
⑵の場合は、iOS側でBoxViewをUIViewとして受け取れず(Nullになる)、うまくいきません。

何かソリューションを持っている方いらっしゃいますか?

⑴のsharedプロジェクト側コード

namespace Test { public class MyBoxView : BoxView { public Color StrokeColor { get; set; } //ボーダ色 public Color FillColor { get; set; } //塗りつぶし色 public int LineWidth { get; set; } //ボーダの幅(0px~10px) public float Radius { get; set; } //角丸(0%~50%) public MyBoxView(Color fillColor, Color strokeColor, int lineWidth, float radius) { FillColor = fillColor; StrokeColor = strokeColor; LineWidth = lineWidth; Radius = radius; //デフォルト値でサイズとレイアウトを設定 WidthRequest = 100; HeightRequest = 100; HorizontalOptions = LayoutOptions.Center; VerticalOptions = LayoutOptions.Center; } } public class BoxViewTest : ContentPage { public BoxViewTest() { var layout = new AbsoluteLayout(); var myBox = new MyBoxView(Color.Gray, Color.Yellow, 1, 10); AbsoluteLayout.SetLayoutFlags(myBox, AbsoluteLayoutFlags.All); AbsoluteLayout.SetLayoutBounds(myBox, new Rectangle(0, 0.5, 1, 0.1)); layout.Children.Add(myBox); Padding = new Thickness(0, Device.OnPlatform(20, 0, 0), 0, 0); Content = layout; } } }

⑴のiOSプロジェクト側コード

//MyBoxViewのレンダラーをMyBoxViewRendererに変更する [assembly: ExportRenderer(typeof(MyBoxView), typeof(MyBoxViewRenderer))] namespace Test.iOS { public override void Draw(CGRect rect) { //デフォルトの描画を無効にする //base.Draw(rect); //モデルオブジェクトの取得 var myBoxView = (MyBoxView)Element; //Xamarin.Forms 1.0.6186 では、Modelでした using (var context = UIGraphics.GetCurrentContext()) { //塗りつぶしの色を指定 context.SetFillColor(myBoxView.FillColor.ToCGColor()); //ボーダの色を指定 context.SetStrokeColor(myBoxView.StrokeColor.ToCGColor()); //ボーダの幅を指定 context.SetLineWidth(myBoxView.LineWidth); //ボーダの分だけ四角のサイズを小さくする var rectangle = Bounds.Inset(myBoxView.LineWidth, myBoxView.LineWidth); //サイズ(幅)の半分を50%として、radiusを求める var radius = (float)((rectangle.Width / 2) * (myBoxView.Radius / 50)); //描画 var path = CGPath.FromRoundedRect(rectangle, radius, radius); context.AddPath(path); context.DrawPath(CGPathDrawingMode.FillStroke); } } }

⑵のsharedプロジェクト側コード

namespace Test { public class BoxViewTest : ContentPage { public BoxViewTest() { var layout = new AbsoluteLayout(); var box = new BoxView { BackgroundColor = Color.Blue }; AbsoluteLayout.SetLayoutFlags(box, AbsoluteLayoutFlags.All); AbsoluteLayout.SetLayoutBounds(box, new Rectangle(0.5, 0.5, 0.8, 0.5)); layout.Children.Add(box); box.Effects.Add(Effect.Resolve("Test.TestEffects")); Padding = new Thickness(0, Device.OnPlatform(20, 0, 0), 0, 0); Content = layout; } } }

⑵のiOSプロジェクト側コード

[assembly: ResolutionGroupName("Test")] [assembly: ExportEffect(typeof(TestEffects), "TestEffects")] namespace Test.iOS.Effects { public class TestEffects : PlatformEffect { protected override void OnAttached() { var box = Control; // ここでboxがnull if (box == null) { return; } box.Layer.BorderWidth = 10; box.Layer.BorderColor = UIColor.Black.CGColor; box.Layer.CornerRadius = 10; box.ClipsToBounds = true; } protected override void OnDetached() { } } }

以上、よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

この場合は Control ではなく Container プロパティの方を参照すれば期待通りの動作になると思います。

Effectの Container にはRendererの参照、 Control にはRendererが抱えるネイティブコントロールの参照がセットされます。

iOSの場合、BoxViewRndererは子Viewを持っていないため、Controlプロパティはnullとなります。

Rendererの定義

// iOSのBoxRendererはVisualElementRenderer<T>から派生しており、子を持たない public class BoxRenderer : VisualElementRenderer<BoxView> // 他のほとんどのViewのRendererはViewRenderer<TView, TNativeView>から派生しており // 第2型引数のネイティブコントロールがEffectのControlプロパティに渡される public class ButtonRenderer : ViewRenderer<Button, UIButton>

iOSの場合、RendererはUIViewから派生しているので、Container.Layerに対して角丸等を設定すればOKです。

投稿2016/12/20 07:58

P3PPP

総合スコア359

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gucchi28

2016/12/20 09:12

ご回答いただきありがとうございます。 Containerプロパティを参照することでうまくできました。 大変助かりました、ありがとうございました。
gucchi28

2016/12/22 01:15

すみません、追加質問です。 iOSでは、UIViewで角丸をつけることができましたが、 Androidで、ViewGroupで角丸をつけることに苦戦しておりまして、 調査したところ、XMLで記述すれば角丸をつけることが可能みたいなのですが、 XamarinでXMLを使う方法が不明であり、また、C#で統一して書きたいと思っています。 ソリューションはありますでしょうか?
P3PPP

2016/12/23 14:50

Androidの場合はBackgroundプロパティにGradientDrawableなどをセットして、それに対してCornerRadiusを設定するといいと思います。 ただし、AndroidのBoxRendererではBoxView.Colorの色を(Androidの)View.SetBackgroundColorにマッピングしているため、これをGradientDrawable.SetColorにマッピングする独自のRendererを作ってBoxViewに対応するRendererとして差し替えるようにしないと思った通りの動作にならないかもしれません。 https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Platform.Android/Renderers/BoxRenderer.cs
gucchi28

2016/12/26 00:41

ご回答いただきありがとうございます。 一筋縄ではいかないのですね、、 トライしてみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問