Inline button and/or textfield within string which wraps the same as text using Swift

Viewed 266

This is more of a question of how to go about achieving it rather than a specific solution. I would like to have a label which allowed buttons and textfields to be inline and wrap to the next line. An example is the iOS shortcuts app where you can type in the same block as the text, and the textfield wraps along the same line. It is a textfield as there is a caret.

iOS shortcuts app iOS shortcuts app whilst editing

At a highlevel it might look something like this:

enter image description here

where each view follows the line and wraps to the next when needed.

I originally thought about using an NSAttributedString with links that were styled and the link could either act as a button, or open a textfield for input. I tried this and got something which worked but it did not resemble the iOS shortcuts app where the textfield is within the text. I have also thought about using textkit, but I have not gotten that far with this as I am not sure it is the correct approach.

Thank you for any ideas or solutions.

EDIT

I have thought about another way of achieving this but I don't know whether it would work either. The idea would be to use a collectionView of textfields. Some textfields would share the same LayoutManager so that the text is shared across the textfields. I would have to calculate how many textfields to create so that they flowed down the collectionView

enter image description here

In the image, Label 1 is made up of 1 textfield which has editing disabled. TextField 1 is made up of 3 textfields which have editing enabled and the three textfields would share the same LayoutManager. Label 2 is made up of 2 textfields with a shared layout manager, but editing disabled.

Using this approach would mean calculating how many textfields to create for each "Block" (Label or TextField) and updating this each time content changes. With this approach, I am only thinking of labels and textfields but the button can be added at another time.

I just started on this, but realised that sharing layout managers disables editing so I don't know whether this would be possible anymore.

Thanks

1 Answers

This is non trivial task for sure, and I don't think there's a ready-for-use solution.

Using NSLayoutManager you can calculate frames of each line/character of your text, and then forbid touches depending on these frames, and add background under editable text.

You have to use UITextView, because you gonna need to forbid user to select part of the text, and you can do it using something like willChangeSelectionFromCharacterRange:toCharacterRange: delegate method, and ofc you need shouldChangeTextIn: to forbid removing non editable text too.

Related