fix: 修复首页位置上报图标渲染
This commit is contained in:
@ -16,21 +16,24 @@ enum HomeMenuIconFactory {
|
|||||||
|
|
||||||
private static let imageCache = NSCache<NSString, UIImage>()
|
private static let imageCache = NSCache<NSString, UIImage>()
|
||||||
|
|
||||||
/// 优先加载 Assets 资源图;否则加载 SF Symbol,并统一渲染到固定画布。
|
/// 优先加载 Assets 资源图并归一化画布;SF Symbol 保留系统符号表示与分层渲染。
|
||||||
static func image(named iconName: String) -> UIImage? {
|
static func image(named iconName: String) -> UIImage? {
|
||||||
let cacheKey = iconName as NSString
|
let cacheKey = iconName as NSString
|
||||||
if let cachedImage = imageCache.object(forKey: cacheKey) {
|
if let cachedImage = imageCache.object(forKey: cacheKey) {
|
||||||
return cachedImage
|
return cachedImage
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let sourceImage = UIImage(named: iconName)
|
let image: UIImage?
|
||||||
?? UIImage(systemName: iconName, withConfiguration: symbolConfiguration) else {
|
if let assetImage = UIImage(named: iconName) {
|
||||||
return nil
|
image = renderOnFixedCanvas(assetImage)
|
||||||
|
} else {
|
||||||
|
image = UIImage(systemName: iconName, withConfiguration: symbolConfiguration)
|
||||||
}
|
}
|
||||||
|
|
||||||
let normalizedImage = renderOnFixedCanvas(sourceImage)
|
if let image {
|
||||||
imageCache.setObject(normalizedImage, forKey: cacheKey)
|
imageCache.setObject(image, forKey: cacheKey)
|
||||||
return normalizedImage
|
}
|
||||||
|
return image
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func renderOnFixedCanvas(_ image: UIImage) -> UIImage {
|
private static func renderOnFixedCanvas(_ image: UIImage) -> UIImage {
|
||||||
|
|||||||
@ -18,20 +18,20 @@ final class HomeMenuIconFactoryTests: XCTestCase {
|
|||||||
XCTAssertNil(UIImage(systemName: "home_menu_space"))
|
XCTAssertNil(UIImage(systemName: "home_menu_space"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testSystemSymbolsUseFixedCanvas() {
|
func testSystemSymbolsPreserveSymbolRepresentation() {
|
||||||
let iconNames = [
|
let iconNames = [
|
||||||
"ellipsis",
|
"ellipsis",
|
||||||
"dot.radiowaves.left.and.right",
|
"dot.radiowaves.left.and.right",
|
||||||
"rectangle.stack.badge.plus",
|
"rectangle.stack.badge.plus",
|
||||||
|
"mappin.circle.fill",
|
||||||
]
|
]
|
||||||
|
|
||||||
for iconName in iconNames {
|
for iconName in iconNames {
|
||||||
let image = HomeMenuIconFactory.image(named: iconName)
|
let image = HomeMenuIconFactory.image(named: iconName)
|
||||||
|
|
||||||
XCTAssertNotNil(image)
|
XCTAssertNotNil(image)
|
||||||
XCTAssertEqual(image?.size, HomeMenuIconFactory.canvasSize)
|
XCTAssertTrue(image?.isSymbolImage ?? false)
|
||||||
XCTAssertEqual(image?.renderingMode, .alwaysTemplate)
|
XCTAssertNotNil(image?.symbolConfiguration)
|
||||||
XCTAssertFalse(image?.isSymbolImage ?? true)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,6 +39,13 @@ final class HomeMenuIconFactoryTests: XCTestCase {
|
|||||||
XCTAssertNotNil(HomeMenuIconFactory.image(named: "dot.radiowaves.left.and.right"))
|
XCTAssertNotNil(HomeMenuIconFactory.image(named: "dot.radiowaves.left.and.right"))
|
||||||
XCTAssertNotNil(HomeMenuIconFactory.image(named: "rectangle.stack.badge.plus"))
|
XCTAssertNotNil(HomeMenuIconFactory.image(named: "rectangle.stack.badge.plus"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testLocationReportIconKeepsSystemSymbolLayers() {
|
||||||
|
let image = HomeMenuIconFactory.image(named: "mappin.circle.fill")
|
||||||
|
|
||||||
|
XCTAssertNotNil(image)
|
||||||
|
XCTAssertTrue(image?.isSymbolImage ?? false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 首页常用应用 cell 的图标布局与复用测试。
|
/// 首页常用应用 cell 的图标布局与复用测试。
|
||||||
@ -50,6 +57,7 @@ final class HomeMenuCellTests: XCTestCase {
|
|||||||
let menus = [
|
let menus = [
|
||||||
HomeMenuItem(uri: "space", title: "空间设置", iconName: "home_menu_space"),
|
HomeMenuItem(uri: "space", title: "空间设置", iconName: "home_menu_space"),
|
||||||
HomeMenuItem(uri: "live", title: "直播管理", iconName: "dot.radiowaves.left.and.right"),
|
HomeMenuItem(uri: "live", title: "直播管理", iconName: "dot.radiowaves.left.and.right"),
|
||||||
|
HomeMenuItem(uri: "location", title: "位置上报", iconName: "mappin.circle.fill"),
|
||||||
HomeMenuItem(uri: "more", title: "更多功能", iconName: "ellipsis"),
|
HomeMenuItem(uri: "more", title: "更多功能", iconName: "ellipsis"),
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -60,11 +68,19 @@ final class HomeMenuCellTests: XCTestCase {
|
|||||||
cell.layoutIfNeeded()
|
cell.layoutIfNeeded()
|
||||||
|
|
||||||
let iconView = try XCTUnwrap(findImageView(in: cell, identifier: menu.iconName))
|
let iconView = try XCTUnwrap(findImageView(in: cell, identifier: menu.iconName))
|
||||||
XCTAssertEqual(iconView.bounds.size, CGSize(width: 24, height: 24))
|
let alignmentSize = iconView.alignmentRect(forFrame: iconView.frame).size
|
||||||
|
XCTAssertEqual(alignmentSize.width, 24, accuracy: 0.001)
|
||||||
|
XCTAssertEqual(alignmentSize.height, 24, accuracy: 0.001)
|
||||||
XCTAssertEqual(iconView.superview?.bounds.size, CGSize(width: 40, height: 40))
|
XCTAssertEqual(iconView.superview?.bounds.size, CGSize(width: 40, height: 40))
|
||||||
XCTAssertEqual(iconView.image?.size, HomeMenuIconFactory.canvasSize)
|
|
||||||
XCTAssertEqual(iconView.contentMode, .center)
|
XCTAssertEqual(iconView.contentMode, .center)
|
||||||
XCTAssertNil(iconView.preferredSymbolConfiguration)
|
XCTAssertNil(iconView.preferredSymbolConfiguration)
|
||||||
|
|
||||||
|
if menu.iconName == "home_menu_space" {
|
||||||
|
XCTAssertEqual(iconView.image?.size, HomeMenuIconFactory.canvasSize)
|
||||||
|
XCTAssertFalse(iconView.image?.isSymbolImage ?? true)
|
||||||
|
} else {
|
||||||
|
XCTAssertTrue(iconView.image?.isSymbolImage ?? false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user