1

I have a button that I want to be an image that can change colors as needed (loading async). To do this, I thought I could do something like this: I thought I could do something like this:

Button(action: { doAction }) {
  AsyncImage(url: URL(string: "test.com")) { image in
    image
      .resizable()
      .aspectRatio(contentMode: .fit)
      .renderingMode(.template)
  }
}

However, when I try to do this, I get a few errors:

"Cannot infer return type for closure with multiple statements"

"Closure containing control flow statement cannot be used with result builder 'TableRowBuilder' "

I'm not sure why these errors show up only when I add the "renderingMode" modifier. Everything works other than adding that. Any idea what I'm doing wrong?

2 Answers 2

1

renderingMode is a modifier that's only available on Image. The aspectRatio modifier returns a View so you can't use Image-specific modifiers after it.

The fix is easy, just move aspectRatio one line up, right after resizable.

Sign up to request clarification or add additional context in comments.

1 Comment

moving renderingMode to be first fixed it for me. Thank you for explaining
1

There are two problems in your code.

  1. You can’t apply image-specific modifiers, like resizable(capInsets:resizingMode:), directly to an AsyncImage. Instead, apply them to the Image instance that your content closure gets when defining the view’s appearance. From Apple developer guide.

    Button(action: { print("Hello") }) {
        AsyncImage(url: URL(string: imageURL)) { phase in
            if let image = phase.image {
                image
                    .resizable()
                    .aspectRatio(contentMode: .fit)
            } else if phase.error != nil {
                Color.red // Indicates an error.
            } else {
                Color.blue // Acts as a placeholder.
            }
        }
        .frame(width: 100, height: 100)
    }
    
    //OR
    
    Button(action: { print("Hello") }) {
        AsyncImage(url: URL(string: imageURL)) { image in
            image
                .resizable()
                .renderingMode(.template)
                .aspectRatio(contentMode: .fit)
        } placeholder: {
            Color.clear
        }
        .frame(width: 100, height: 100) //Size of your button
    }
    
  2. renderingMode modifier needs to be called on Image and you are calling it after aspectRatio(contentMode:). Place it before and you are good to go.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.