NSImage 画不出 SVG 里的 <use> 引用,弹窗里的归属地国旗显示错乱。改为构建前渲染成 64×48 的 PNG 打进资源包,FlagImage 直接读 PNG;第三方声明补上国旗与品牌标志的来源。
44 lines
1.7 KiB
Swift
44 lines
1.7 KiB
Swift
import AppKit
|
||
import SwiftUI
|
||
|
||
/// 国旗:使用包内由 flag-icons(MIT)渲染好的 PNG,不使用 emoji。
|
||
/// 不直接读 SVG:系统的 SVG 渲染器对嵌套 <use> 等写法支持不好,中国、乌兹别克斯坦等旗子会画错(见 Scripts/render_flags.sh)
|
||
struct FlagImage: View {
|
||
let countryCode: String
|
||
var height: CGFloat = DS.Space.s3
|
||
|
||
var body: some View {
|
||
if let image = FlagCache.shared.image(for: countryCode) {
|
||
Image(nsImage: image)
|
||
.resizable()
|
||
.aspectRatio(4 / 3, contentMode: .fit)
|
||
.frame(height: height)
|
||
.clipShape(RoundedRectangle(cornerRadius: DS.Radius.sm / 2))
|
||
.overlay(RoundedRectangle(cornerRadius: DS.Radius.sm / 2).strokeBorder(DS.Palette.border, lineWidth: DS.Size.stroke))
|
||
.accessibilityHidden(true)
|
||
}
|
||
}
|
||
}
|
||
|
||
@MainActor
|
||
final class FlagCache {
|
||
static let shared = FlagCache()
|
||
private var images: [String: NSImage] = [:]
|
||
private var missing: Set<String> = []
|
||
|
||
func image(for countryCode: String) -> NSImage? {
|
||
let code = countryCode.lowercased()
|
||
// 只接受两位字母,避免拼出包外路径
|
||
guard code.count == 2, code.unicodeScalars.allSatisfy({ ("a"..."z").contains($0) }) else { return nil }
|
||
if let image = images[code] { return image }
|
||
guard !missing.contains(code) else { return nil }
|
||
guard let url = Bundle.module.url(forResource: code, withExtension: "png", subdirectory: "Flags"),
|
||
let image = NSImage(contentsOf: url) else {
|
||
missing.insert(code)
|
||
return nil
|
||
}
|
||
images[code] = image
|
||
return image
|
||
}
|
||
}
|