Changing the size of a UIView dynamically

SaundoSaundo AUMember

I have a custom view in my PCL and I have built custom renderers on UWP, IOS and Android to render this view. I am having some issues with getting the view to layout correctly in IOS. I am creating a button that uses an SVG as a background (xam.svg on android and Mntone.SvgForXaml on UWP is what i use to get the SVG to actually display and paintcode is what I will use for IOS). I have code that sets the bindable WidthAndHeight property on the PCL view after i find out the dimensions on the screen.

I have tried all manner of methods to get the view in IOS to size correctly. I have tried updating the Control.Bounds, Control.Frame, TheButton.Frame, TheButton.Bounds but nothings gets the view to resize. I have set a break point and it appears as if the values are get set but then nothing is updated. I have included the Android renderer as an example of exactly what I am doing there to set the view size correctly on that platform.

**Here is the code for the UIview. I havent done anything other than change the background so that i can see the view on the screen. **
[Register("HexagonButtonIOS")]
public class HexagonButtonIOS : UIView
{
public HexagonButtonIOS()
{
Initialize();
}

    public HexagonButtonIOS(RectangleF bounds) : base(bounds)
    {
        Initialize();
    }

    void Initialize()
    {
       BackgroundColor = UIColor.Red;
    }
}

Here is the custom renderer on IOS
[assembly: ExportRenderer(typeof(HexagonButtonForms), typeof(HexagonButtonRendererIOS))]
namespace WASP_APP.iOS
{
class HexagonButtonRendererIOS: ViewRenderer<HexagonButtonForms, HexagonButtonIOS>
{
HexagonButtonIOS TheButton;

    protected override void OnElementChanged(ElementChangedEventArgs<HexagonButtonForms> e)
    {
        base.OnElementChanged(e);

        if (e.NewElement == null)
            return;

        TheButton = new HexagonButtonIOS();

        SetNativeControl(TheButton);
    }

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);

        if (string.Equals("WidthAndHeight", e.PropertyName))
        {
            HexagonButtonForms senderAsAButton = (HexagonButtonForms)sender;

            //change the width and height to the value of senderAsAButton.WidthAndHeight.
        }
    }
}

}

Here is the custom renderer on android
[assembly: ExportRenderer(typeof(HexagonButtonForms), typeof(HexagonButtonRendererAndroid))]
namespace WASP_APP.Droid
{
class HexagonButtonRendererAndroid: ViewRenderer<HexagonButtonForms, HexagonButtonAndroid>
{
.....
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);

        if (Control == null || Element == null)
            return;

        if (string.Equals("WidthAndHeight", e.PropertyName))
        {
            HexagonButtonForms senderasBTN = (HexagonButtonForms)sender;
            var param = TheButton.Wrapper.LayoutParameters;

            double pixelsPerOneDp = (double)((int)Forms.Context.Resources.DisplayMetrics.DensityDpi / 160f);
            int widthDp = (int)Math.Round(senderasBTN.WidthAndHeight * pixelsPerOneDp);
            int heightDp = (int)Math.Round(senderasBTN.WidthAndHeight * pixelsPerOneDp);

            param.Height = heightDp;
            param.Width = widthDp;

            TheButton.Wrapper.LayoutParameters = param;

            int leftandRightMargin = (int)(widthDp * 0.05);

            var buttonParams = new Android.Widget.RelativeLayout.LayoutParams(LayoutParams.MatchParent, LayoutParams.MatchParent);
            buttonParams.SetMargins(leftandRightMargin, 0, leftandRightMargin, 0);
            internalButton.LayoutParameters = buttonParams;

            TheButton.RequestLayout();
        }

    }

I am sorry if this is a nube question, however I have hunted all over and could not fund anything that works.

Thanks,

Answers

  • LarryOBrienLarryOBrien USXamarin Team Xamurai
    edited October 2016

    My guess is that you need to call SetNeedsLayout() on the containing UIView. (i.e, "I need to layout my child views").

    Also, it may be useful to size your button by assigning the Transform property of your HexagonButtonIOS a la:

    myButton.Transform = CGAffineTransform.MakeScale(2.0f, 2.0f); 
    

    That may make your layout code easier.

  • SaundoSaundo AUMember

    @LarryOBrien

    Thanks. That did work in allowing me to resize to UIview. I have to setup a the UIview with a CGRect in the initialize in order to get it to work.

    The CGAffineTransform.MakeScale has no effect at all if I used a UIButton instead of a UIVIew, however. Are you aware of why this would work for a UIView and not for a UIButton?

  • LarryOBrienLarryOBrien USXamarin Team Xamurai

    Hmm... I just tried it locally and confirmed that the Transform works on a button's Frame. Could it be that the frame is changing but the contents of the button (font size, etc.) are not?

    Another possibility is that the IntrinsicContentSize is somehow coming in to play, which could happen if the containing view had a layout that resized its child views. (That doesn't sound like your situation, but it's one aspect that can be confusing.)

Sign In or Register to comment.