skip to Main Content

I am making a section with TextFields and Button("Continue") and then use .disable(isValidAddress) modifier to a whole section to disable the button. The code works well, but I am seeking any solution to make it more succinct with no need to write .hasPrefix() or .hasSuffix() to all parameters one by one.

var isValidAddress: Bool {
    if name.hasPrefix(" ") || street.hasPrefix(" ") || city.hasPrefix(" ") || country.hasPrefix(" ") {
        return false
    } else if name.hasSuffix(" ") || street.hasSuffix(" ") || city.hasSuffix(" ") || country.hasSuffix(" ") {
        return false
    }
        return true
    }

3

Answers


  1. var isValidAddress: Bool {
    [street, name, city, etc..].reduce(true, { result, text in
        if text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
            return false
        } else {
            return result
        }
    })
    

    }

    Login or Signup to reply.
  2. You can add them to an array and trim white space and check if empty in a loop

    func isValidAddress() -> Bool {
        for field in [name, street, city, country] {
            if field.trimmingCharacters(in: .whitespaces).isEmpty { return false }
        }
        return true 
    }
    

    I used a function here but a computed property works just as well.

    Login or Signup to reply.
  3. If you don’t mind moving some complexity into extensions, you can tidy up the call site. This makes it more readable, and less error prone – you can easily add in another field without mistakes for example.

     extension String {
        func hasPrefixOrSuffix(_ s: String) -> Bool {
            hasPrefix(s) || hasSuffix(s)
        }
    
        var noSpacesAtEnds: Bool {
            !hasPrefixOrSuffix(" ")
        }
    }
    
    let isValid = [name, street, city, country]
        .allSatisfy(.noSpacesAtEnds)
    

    If you do mean none of them are "all whitespace strings" then:

    extension String {
        var isNotAllWhitespace: Bool {
            !trimmingCharacters(in: .whitespaces).isEmpty
        }
    }
    
    let isValid = [name, street, city, country]
        .allSatisfy(.isNotAllWhitespace)
    

    One benefit of having named functions for these things is you can test the pieces, so you can write a test to ensure that isNotAllWhitespace works the way you expect. You couldn’t if the logic like name.hasPrefix(" ") || street.hasPrefix(" ") is mixed in with your isValidAddress function.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search