I've been trying to find a solution to this problem over the past few weeks. I've tried everything I've seen on this site including the accepted answer in this post. Even though it works great to reduce line height, I wasn't able to set leading and trailing padding. Here's what worked for me (one caveat is that padding has to be applied to the CustomText view, it will not constrain to any padding set by any containers higher up).
Working off of the accepted answer, I created a CustomText view, but I used it as a container (thinking it should act as a UIView for the UILabel to constrain to):
struct CustomText: View {
    private let text: String
    private let font: UIFont
    private let textAlignment: NSTextAlignment?
    private let lineHeight: CGFloat
    private let padding: EdgeInsets?
    private let containerWidth: CGFloat?
    
    /// - Parameters
    ///     - text `(String)`: String to display.
    ///     - font `(UIFont)`: Applies font to UILabel.
    ///     - textAlignment `(NSTextAlignment)` Will apply text alignment to UILabel.
    ///     - lineHeight: `(CGFloat)` Sets min and max line height in UILabel's attributed string paragraph style.
    ///     - padding `(EdgeInsets?)` Used to apply padding to the container and calculate the width of the nested UILabel. Defaults to 0s for all values.
    ///     - containerWidth: `(CGFloat?)` containerWIdth - leading and trailing padding will be used to set the width of nested the UILabel. Defaults to screen width.
    init(
        text: String,
        font: UIFont,
        textAlignment: NSTextAlignment? = .left,
        lineHeight: CGFloat,
        padding: EdgeInsets? = nil,
        containerWidth: CGFloat? = nil
    ) {
        self.text = text
        self.font = font
        self.textAlignment = textAlignment
        self.lineHeight = lineHeight
        self.padding = padding
        self.containerWidth = containerWidth
    }
    
    var body: some View {
        /// Putting the UILabel in a VStack mimics putting in a UIView which gives it something to constrain to
        VStack {
            CustomTextRepresentable(
                text: text,
                font: font,
                textAlignment: textAlignment ?? .left,
                lineHeight: lineHeight,
                containerWidth: containerWidth ?? UIScreen.main.bounds.width,
                padding: padding ?? EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)
            )
            /// scaledToFit prevents the UILabel from expanding vertically
            .scaledToFit()
        }
        /// Applying padding to the outside creates the constraints for the wrapper which the UILabel must constrain to
        .padding(padding ?? EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
    }
}
There are some comments there but part of the solution was to wrap the CustomTextRepresentable inside a VStack and apply padding to the VStack. When doing this however, the UILabel via UIViewRepresentable will be pushed left or right by its container's padding. So, I had to modify the UILabel width to fit within the padded parent container:
struct CustomTextRepresentable: UIViewRepresentable {
    let text: String
    let font: UIFont
    let textAlignment: NSTextAlignment
    let lineHeight: CGFloat
    let containerWidth: CGFloat
    let padding: EdgeInsets
    
    func makeUIView(context: Context) -> UILabel {
        return UILabel()
    }
    
    func updateUIView(_ uiLabel: UILabel, context: Context) {
        /// Resizing the label width prevents it from getting shifted in either direction when padding is applied to its container
        let widthWithPadding: CGFloat = containerWidth - (padding.leading + padding.trailing)
        let attributedString = NSMutableAttributedString(string: text)
        let paragraphStyle = NSMutableParagraphStyle()
        
        uiLabel.font = font
        uiLabel.numberOfLines = 0
        uiLabel.lineBreakMode = .byWordWrapping
        uiLabel.translatesAutoresizingMaskIntoConstraints = false
        uiLabel.preferredMaxLayoutWidth = widthWithPadding        
        
        paragraphStyle.alignment = textAlignment
        paragraphStyle.minimumLineHeight = lineHeight
        paragraphStyle.maximumLineHeight = lineHeight
        
        attributedString.addAttribute(
            NSAttributedString.Key.paragraphStyle,
            value: paragraphStyle,
            range: NSRange(location: 0, length: attributedString.length)
        )
        
        uiLabel.attributedText = attributedString
    }
}
Example usage:
CustomText(
    text: "Hey this is some text for a demo", 
    font: .someFont,
    lineHeight: 10,
    padding: EdgeInsets(top: 10, leading: 24, bottom: 14, trailing: 24)
)
I'd love to have a version of this that will just resize to its parent without using GeometryReader because that was causing some other issues for me when using multiple CustomText in a VStack, but this is working OK for my needs.
I hope this is helpful to someone. I'm relatively new to SwiftUI and have somewhat limited experience with Swift and iOS development outside of React Native and a year spent building iOS apps with Swift and Interface Builder back in 2015. If anyone can make this solution better and/or more elegant please feel free to contribute!