有没有一种方法可以将字符串插值与带有修饰符的SF符号一起使用



我想在应用了rotationEffect(_:anchor:)修饰符的SF符号上使用字符串插值。有可能做到这一点吗?

如果没有修饰符,这种类型的字符串插值效果很好(在Swift 5.0中(:

struct ContentView: View {
var body: some View {
Text("Some text before (Image(systemName: "waveform.circle")) plus some text after.")
}
}

但是应用这样的修改器:

struct ContentView: View {
var body: some View {
Text("Some text before (Image(systemName: "waveform.circle").rotationEffect(.radians(.pi * 0.5))) plus some text after.")
}
}

不编译并给出以下错误:

实例方法"appendInterpolation"要求"some View"符合"_FormatSpecifable">

文本插值需要Image。当.rotationEffect...则它变为View,而这是无效的。

因此,一种替代方案是在SF用于Image之前旋转SF。这就是我最终尝试的,使用Swift中的Rotating UIImage中的一个答案中的代码以旋转CCD_ 6并在CCD_。

这有点复杂,你可能会必须调整锚/位置。也许有人会想出一个更好的解决方案。直到那时它似乎对我有用。

struct ContentView: View {
var body: some View {
Text("Some text before (img) plus some text after.")
}

var img: Image {
if let uimg = UIImage(systemName: "waveform.circle"),
let rotImage = uimg.rotate(radians: .pi/4) {
return Image(uiImage: rotImage)
} else {
return Image(systemName: "waveform.circle")
}
}

}
// from: https://stackoverflow.com/questions/27092354/rotating-uiimage-in-swift
extension UIImage {
func rotate(radians: Float) -> UIImage? {
var newSize = CGRect(origin: CGPoint.zero, size: self.size).applying(CGAffineTransform(rotationAngle: CGFloat(radians))).size
// Trim off the extremely small float value to prevent core graphics from rounding it up
newSize.width = floor(newSize.width)
newSize.height = floor(newSize.height)
UIGraphicsBeginImageContextWithOptions(newSize, false, self.scale)
let context = UIGraphicsGetCurrentContext()!
// Move origin to middle
context.translateBy(x: newSize.width/2, y: newSize.height/2)
// Rotate around middle
context.rotate(by: CGFloat(radians))
// Draw the image at its center
self.draw(in: CGRect(x: -self.size.width/2, y: -self.size.height/2, width: self.size.width, height: self.size.height))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
}

正如workingdog_support_Ukraine在这里指出的,字符串插值将适用于Image,但修饰符将更改它们所应用的类型。因此,我们需要在不擦除Image类型的情况下旋转图像。

对于简单的orientation旋转,我们可以创建这样的旋转Image类型:

extension Image {
init(systemName: String, orientation: UIImage.Orientation) {
guard
let uiImage = UIImage(systemName: systemName),
let cgImage = uiImage.cgImage
else {
self.init(systemName: systemName)
return
}
self.init(uiImage: UIImage(cgImage: cgImage, scale: uiImage.scale, orientation: orientation))
}
}

然后,我们在字符串插值中使用旋转的图像(在这种情况下,顺时针旋转90度(,如下所示:

struct ContentView: View {
var body: some View {
Text("Some text before (Image(systemName: "waveform.circle", orientation: .right)) plus some text after.")
}
}

这将使旋转后的图像在文本基线上对齐。

最新更新