Это происходит потому, что вы добавляете символ, а затем возвращаете true (во всех случаях, кроме новой строки).
Если после добавления символа вы возвращаете false, он должен работать так, как вы хотите.
Попробуйте это:
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if text == " " {
textView.text.append(("#"))
return false
}
if text == "\n" {
textView.resignFirstResponder()
return false
}
return true
}