Change canvas heights based on text drawn inside

In my desktop app (multiple choice exam), I have several canvases (1 for the question and 4 for the answer choices). These resize based on the text that is present in the canvas with the use of drawing a picture of the text. This works well. I am now trying to accomplish the same in iOS but am not quite getting it right. The Q and As are in a container control, which is embedded in a ScrollableArea on the screen. The code below is in a method in the container control and is just for the question. Figured if I can get this to work, I can get the answer choices to do the same. The question’s height is set to min 25 ( >= 25), not sure if this matters. The first run works well (displays an appropriate height of the canvas to fit all the text), but when I navigate through the questions, if the next one is less text, the canvas does get smaller accordingly, but if a future question is lengthier, it does not expand and stays at the last smallest height. What am I missing?

dim tempQHeight as new Picture(canQuestion.Width, canQuestion.Height)

dim htQ as Double

txQuestion = rs.Column("Question").StringValue 'set the text
tempQHeight.Graphics.Font = font.SystemFont(18) 'set size
htQ = tempQHeight.Graphics.TextHeight(txQuestion, canQuestion.Width) 'get height of this text with wrapping

dim constHgtQ as new iOSLayoutConstraint(canQuestion, _
iOSLayoutConstraint.AttributeTypes.Height, _
iOSLayoutConstraint.RelationTypes.Equal, _
nil, _
iOSLayoutConstraint.AttributeTypes.None, _
1.0, _
htQ + 25)
canQuestion.AddConstraint(constHgtQ)

canQuestion.Refresh

Why use a canvas to draw text?

You lose ability for people with accessibility problems to select the text and have the device speak out what’s written.

As I understand, the user should be able to click on one of the four answers. This is definitely what a button is supposed to do.
To change the styling of the button you can either use declares or iOSdesignExtensions which is free on github.

Thanks Jeremie. I chose the canvas because I want the user to tap on the answer choice to make their selection. In my old app, which I am replacing, I have a canvas next to a label (tap to make a selection), and the label contains the choice. Also canvas over a button because some text in the answer choices can actually be lengthy, more than one line of text. I am not aware of a button being able to support text wrapping, or can it?

Yes, it is possible.

I will share an example when I get back to my computer.

I would be interested in seeing if this would work but also might still like to explore a solution with using the canvas. Thanks Jeremie!

So actually I was wrong… :face_with_hand_over_mouth:
I thought that iOS could automatically adapt the height depending on the length of the caption. But it doesn’t seem to work.

Anyway, if your captions aren’t too long, you could certainly use something like this:

Using iOSDesignExtensions
Add a button in a MobileScreen and set the Height constraint to 70.

In the Open event of the button add this code:

Button1.SetLineBreakModeXC(ControlExtensionsXC.NSLineBreakMode.TruncateTail) //This works better than wordwrap in this situation
Button1.SetTextAlignmentXC(ControlExtensionsXC.NSTextAlignment.center) //Aligns the text in the center
Button1.SetNumberOfLinesXC(3) //Forces the button to wrap text on 3 lines
Button1.AdjustsFontSizeToFitWidthXC //Adjusts the font size to fit all text

Add some styling and you get this:

Screenshot 2022-01-26 at 13.24.49

I had that same setup with labels and pictures inside a canvas, but what drove me away from
the canvas was…

  1. Jeremie’s recommendation to use buttons instead and
  2. the Canvas reacts much more sensitive on a tap than a button. I had lots of feedback that there’s too many accidental taps on the Canvases.
  3. Also, as soon as the user puts the finger on the Canvas, it will fire the PointerDown and PointerUp events, even if you move the finger outside of the Canvas before releasing it. The PointerUp will fire anyway. With a button, the Pressed fires only if you tap it and keep your finger on the button until releasing it.

I’m attaching a screenshot where you see what you can do with a button and Jeremie’s iOSDesignExtensions. The players are all custom table cells with white buttons, labels and pictures on it.

Of course you could do the same with transparent buttons, just like a canvas.

1 Like

In order to adapt the height of a multi-line button, I will set the button caption to “”, add a label in front of the button with a min height constraint where the text will go and then add a height constraint to the button being equal to the label’s height.

Thanks for the replies. I already have iOSDesignExtensions in the project and will try out the buttons as my answer choices. The accidental touch on a choice is not a big deal. The user has to still hit Submit after they make their selection and can change the answer before hitting Submit

Chris - That’s quite an awesome looking app! Well done on the design!