You can do it like this   
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
   guard let textFieldText = textField.text,
       let rangeOfTextToReplace = Range(range, in: textFieldText) else {
               return false
       }
   let substringToReplace = textFieldText[rangeOfTextToReplace]
   let count = textFieldText.count - substringToReplace.count + string.count
   let allowedCharacters = ".-+1234567890"
   let allowedCharcterSet = CharacterSet(charactersIn: allowedCharacters)
   let typedCharcterSet = CharacterSet(charactersIn: string)
        if  allowedCharcterSet.isSuperset(of: typedCharcterSet)
                   , count <= 20 {
                 return true
              } else {
                 return false
              }
 }
Or you can use this Subclass of UITextField 
class JDTextField: UITextField {
    @IBInspectable var maxLength: Int = 0 // Max character length
    var valueType: ValueType = ValueType.none // Allowed characters
    /************* Added new feature ***********************/
    // Accept only given character in string, this is case sensitive
    @IBInspectable var allowedCharInString: String = ""
    func verifyFields(shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        switch valueType {
        case .none:
            break // Do nothing
        case .onlyLetters:
            let characterSet = CharacterSet.letters
            if string.rangeOfCharacter(from: characterSet.inverted) != nil {
                return false
            }
        case .onlyNumbers:
            let numberSet = CharacterSet.decimalDigits
            if string.rangeOfCharacter(from: numberSet.inverted) != nil {
                return false
            }
        case .phoneNumber:
            let phoneNumberSet = CharacterSet(charactersIn: "+0123456789")
            if string.rangeOfCharacter(from: phoneNumberSet.inverted) != nil {
                return false
            }
        case .alphaNumeric:
            let alphaNumericSet = CharacterSet.alphanumerics
            if string.rangeOfCharacter(from: alphaNumericSet.inverted) != nil {
                return false
            }
        case .fullName:
            var characterSet = CharacterSet.letters
            print(characterSet)
            characterSet = characterSet.union(CharacterSet(charactersIn: " "))
            if string.rangeOfCharacter(from: characterSet.inverted) != nil {
                return false
            }
        }
        if let text = self.text, let textRange = Range(range, in: text) {
            let finalText = text.replacingCharacters(in: textRange, with: string)
            if maxLength > 0, maxLength < finalText.utf8.count {
                return false
            }
        }
        // Check supported custom characters
        if !self.allowedCharInString.isEmpty {
            let customSet = CharacterSet(charactersIn: self.allowedCharInString)
            if string.rangeOfCharacter(from: customSet.inverted) != nil {
                return false
            }
        }
        return true
    }
}
How to use it 
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    // Verify all the conditions
    if let sdcTextField = textField as? JDTextField {
        return sdcTextField.verifyFields(shouldChangeCharactersIn: range, replacementString: string)
    } else {
        return true
    }
}
And in viewDidLoad() you set characteristics in just one line
override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    self.textField.delegate = self
    self.textField.maxLength = 10
    self.textField.allowedCharInString = ".-+1234567890"
}