BLACK FRIDAY: Save 50% on all my Swift books and bundles! >>

SOLVED: Remove or resize an image when selecting an item in a Picker view?

Forums > Swift

Is there a way to remove or resize the image from the tag in the Picker view?

Picker("", selection: $selectedCategory) {
    ForEach(categorySM.categories, id: \.self) { category in
        HStack {
            if let inputImage = UIImage(data: category.image ?? Data()) {
                Image(uiImage: inputImage)
                    .resizable()
                    .scaledToFit()
            }
            Text(category.name ?? "")
        }
        .tag(category as CategoryItem?)
    }
}
.font(.callout)
.pickerStyle(.menu)

As you can see in images 1 and 2 below, the image in the tag from the Beverages category is huge and covers almost the entire screen, it also covers the category name (Beverages). Is there a way to remove or resize the image when displaying it on the tag? Basically to make it look like image #3.

enter image description here

4      

Weird but resizing the UIImage before converting to Image view solved the issue.

    if let inputImage = UIImage(data: category.image ?? Data()) {
        let resizeImage = inputImage.scalePreservingAspectRatio(targetSize: CGSize(width: 25, height: 25))
        Image(uiImage: resizeImage)
        .resizable()
        .scaledToFit()
    }

Code for resizing the UIImage

    extension UIImage {
        func scalePreservingAspectRatio(targetSize: CGSize) -> UIImage {
            // Determine the scale factor that preserves aspect ratio
            let widthRatio = targetSize.width / size.width
            let heightRatio = targetSize.height / size.height

            let scaleFactor = min(widthRatio, heightRatio)

            // Compute the new image size that preserves aspect ratio
            let scaledImageSize = CGSize(
                width: size.width * scaleFactor,
                height: size.height * scaleFactor
            )

            // Draw and return the resized UIImage
            let renderer = UIGraphicsImageRenderer(
                size: scaledImageSize
            )

            let scaledImage = renderer.image { _ in
                self.draw(in: CGRect(
                    origin: .zero,
                    size: scaledImageSize
                ))
            }
            return scaledImage
        }
    }

3      

There is the Instafilter project in the 100 Days of SwiftUI, and part of it helps in the understanding of the relationships between 'Image', 'CIImage', 'CGImage' and 'UIImage' - Integrating Core Image with SwiftUI

3      

Handling JSON keys with spaces, like the example you provided, can be challenging when working with Swift's Codable protocol because Codable expects keys to match the structure you define in your Swift structs. If the JSON keys don't conform to Swift's naming conventions (camelCase or snake_case), you'll need to handle them differently. Here are a few approaches you can consider:

  1. Manual Parsing: One way to handle JSON keys with spaces is to manually parse the JSON using the JSONSerialization class to convert the JSON into a Swift dictionary. Once you have the dictionary, you can extract the values associated with the keys that have spaces.

    if let json = try? JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any] {
       if let value = json["some id"] as? String {
           // Handle the value [https://inshotproapps.com](https://inshotproapps.com)
       }
    }

    This method allows you to access values using keys that have spaces directly. However, it requires more manual handling. Inshot Pro APK].

  2. Data Transformation: If you want to use Codable and maintain a consistent data structure, you can transform the JSON data before decoding it. You can create a custom CodingKey implementation to handle the keys with spaces. This involves creating a struct that conforms to the CodingKey protocol and specifying the key mappings explicitly.

    struct MyData: Codable {
       let someID: String
    
       enum CodingKeys: String, CodingKey {
           case someID = "some id"
       }
    }

    In this example, the CodingKeys enum maps the JSON key "some id" to the Swift property someID. You can then decode your JSON using this structure.

  3. Preprocessing: As you mentioned, preprocessing the JSON to replace keys with spaces before decoding can be a practical solution. You can create a function that takes the JSON data as input, replaces keys with spaces using regular expressions or string manipulation, and then decodes the modified JSON.

    This approach allows you to sanitize the JSON data before parsing it with Codable and ensures that your Swift code works consistently regardless of the JSON source.

While each of these methods has its advantages and drawbacks, your choice depends on your specific use case and how much control you have over the JSON source. If the rogue spaces are rare and predictable, manually specifying CodingKeys may be the most efficient approach. If the JSON data is frequently changing or beyond your control, preprocessing the JSON might be the most flexible option.

3      

Save 50% in my WWDC sale.

SAVE 50% All our books and bundles are half price for Black Friday, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

Save 50% on all our books and bundles!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.