The reason is interesting as well. Paraphrasing from this blog post[0]
When you format the ASCII table in four columns, you can see `ESC` and `[` on the same row. Holding `CTRL` essentially ~lops off the first three bits~ subtracts 64, resulting in `ESC`
...
...
0011000 CAN 0111000 8 1011000 X 1111000 x
0011001 EM 0111001 9 1011001 Y 1111001 y
0011010 SUB 0111010 : 1011010 Z 1111010 z
0011011 ESC 0111011 ; 1011011 [ 1111011 {
0011100 FS 0111100 < 1011100 \ 1111100 |
0011101 GS 0111101 = 1011101 ] 1111101 }
0011110 RS 0111110 > 1011110 ^ 1111110 ~
0011111 US 0111111 ? 1011111 _ 1111111 DEL
> Holding `CTRL` essentially lops off the first three bits
No, it inverts the 7th bit (or subtracts 64).
The Linux `ascii(7)` man page has a similar table, but with 2 columns. The first 32 control characters listed there have their "caret notation" character in the opposite column.
I missed the lowercase i on first read. I'll comment anyway in case this helps others. Hacker's Keyboard from f-droid has an escape key. If using the compact layout you can get to it by holding the tab key. I think on the full layout it has a more traditional placement.
I'm not sure what alternative keyboards iOS has.