Modern 32-bit arm also have movw and movt, which load the bottom and top 16 bits of a register. Combining the two you can load any 32-bit value in two instructions. Classic 8-bit+rotation immediates are still used for arithmetic immediates though.
ARM64 is different. For arithmetic, you get a 12-bit value with an optional left-shift by 12, for bitwise instructions you get an arbitrary string of 1's at any position you want (including rotated), which turns out to be very useful, while for loading values, just like in modern ARM-32, you load 16 bits at a time using movw, movt and movk to reach the higher parts of a register. You have to string together four of those to load a fully general 64-bit value, but that's pretty rare in practice.
In aarch64, the bitwise operation immediates are a bit more complicated. From the documentation
Is the bitmask immediate. Such an immediate is a 32-bit or 64-bit pattern viewed as a vector of identical elements of size e = 2, 4, 8, 16, 32, or 64 bits. Each element contains the same sub-pattern: a single run of 1 to e-1 non-zero bits, rotated by 0 to e-1 bits. This mechanism can generate 5,334 unique 64-bit patterns (as 2,667 pairs of pattern and their bitwise inverse). Because the all-zeros and all-ones values cannot be described in this way, the assembler generates an error message.
In addition to those, there's PC relative loads from a literal pool. This is what you end up using 9 times out of ten to load a full register rather than filling it in piecemeal with immediates.
Modern 32-bit arm also have movw and movt, which load the bottom and top 16 bits of a register. Combining the two you can load any 32-bit value in two instructions. Classic 8-bit+rotation immediates are still used for arithmetic immediates though.
ARM64 is different. For arithmetic, you get a 12-bit value with an optional left-shift by 12, for bitwise instructions you get an arbitrary string of 1's at any position you want (including rotated), which turns out to be very useful, while for loading values, just like in modern ARM-32, you load 16 bits at a time using movw, movt and movk to reach the higher parts of a register. You have to string together four of those to load a fully general 64-bit value, but that's pretty rare in practice.