TL;DR: Some of the problems are irregularities of arrays, not applicable to other collections. While you could do something for arrays, better consider giving the programmer the alternative collections if what they want is not exactly arrays.
The problem with this is, sometimes it is useful to modify a collection while iterating over it. For example, priority queues are always supposed to be read while modifying, and are difficult to use without modifying. They are popped, not iterated. But programmers may opt to use an ordered set or an ordered map for a priority queue, if the features of sets or maps are also required.
Actually, ordered sets and maps are not very useful if you don't intermix reads and writes. In that case, you just append everything into an array, then sort and deduplicate before reading. If it could be read while modifying, it is not very reasonable to specifically forbid reading using iterators.
So I recommend against doing this, because it is against the spirit of some types of the collections.
Things said, some programmers don't know much about the details, and just want to work with collections in any way they want and expect it to work. So there might be something could be done in the language design. But a question is, do you want to prevent this for every type of collection, just arrays, or a specific type called a "collection" to be used for everything for these programmers?
Arrays
If it's only for advanced programmers, actually you could give a straight warning in any situation that something is inserted or removed in the middle of an array, because it is not the right data structure for this. Most other data structures don't skip elements if something is removed in the middle. So if you are supporting this operation anyway, and solving this exact problem of skipping elements, you do it specifically to arrays.
A possible option to keep the iterator at the correct position, is to record the reference to every iterator in the array type, and update each of them when the array is modified, as the number of iterators are usually small.
Another option is to also attach a linked list with the array, and iterate using the linked list. It works best if the array elements are already references and the real data are allocated elsewhere.
If the array works in a way that removed elements might be replaced by another element at the end, like using it to allocate memory, it might be helpful to do both, to move elements in the array but not in the linked list. This might be useful if arrays are the underlying structure of another type of collection, but might not be applicable to just arrays because it changes the iterating order.
If you really want to freeze the array when an iterator is active, it still doesn't do that much damage, if it is specific to arrays and not other collections. To do this, you could choose between unfreezing the array in the iterator's destructor, and disabling the iterator after modification of the array.
For appending, if you want it to not iterate from the new elements, you may initialize the iterator using a subrange covering all the current elements of an array. But it might be equally confusing, as some programmers may expect the opposite to happen.
Some languages may also invalidate iterators and pointers on array resizing. I think this is a problem of its own. If you couldn't change it, you may have to freeze iterators. But it's better to be solved in other ways.
A collection for everything
A good example is PHP, where you could skip indexes in an "array". It's easier to unset the index in a loop, so the array would have some holes, and renumber the elements using array_values only after the loop, than to think of how to keep the indexes continuous all the way. Actually there isn't a builtin to remove in the middle like a normal array, so the programmer could not make mistakes this way.
(Arrays are also automatically shallow-copied, making this not changing much. But the idea would work in a language that arrays are not automatically copied.)
Every type of collection
Most commonly used data structures other than arrays, linked lists, hash tables, has a persistent version that could be shallow-copied with no overhead. So you may make a shallow copy of them automatically if that is what you want, and only deal with arrays and linked lists as special cases.
Hash tables as a data structure itself are not supposed to be iterated, and are only iterated using a built-in auxiliary data structure if it is supported, so you could solve the problem like that auxiliary data structure. It may not have the problems if the auxiliary data structure is not exactly arrays, so it makes sense to simulate the behavior as it is not even if it is.