在macOS上用Swift获取字体样式及解决视图渲染与更新问题
字体样式菜单渲染与onChange触发问题
我正在制作一个展示特定字体样式的菜单,目前遇到两个核心问题:
- 注释的ForEach代码无法正常渲染列表:当前按钮代码能正确打印字体样式,但没法通过ForEach遍历渲染样式选项。
getFontStyles()返回数组的数组,内部数组包含字体名称、样式、ID编号等字段,可通过member[1]获取样式内容。 .onChange完全不触发:补充代码和参考代码结构相近,仅变量名不同,我添加了多个.onChange调用,试图在切换字体时更新字体样式列表,但所有.onChange均未生效。
初始代码
struct AddFontStyleItems: View { var dm: DrawModel init(_ dm: DrawModel ) { self.dm = dm } var body: some View { var fontStyles = getFontStyles(for: dm.curFont ) // ForEach(fontStyles, id: \.self) { curStyle in // Button( "xxx" ) { // print( "Style: \(curStyle)") // // print("Type of Member: \(type(of: member)) - \(member[1])") // } // } Button( "xxx" ) { let fontStyles = NSFontManager.shared.availableMembers(ofFontFamily: dm.curFont) print("-\nFont: \(dm.curFont)") if let members = fontStyles { for member in members { print("Style for: \(dm.curFont) - \(member[1])") } } } } } func getFontStyles(for fontFamily: String) -> [String] { let fontManager = NSFontManager.shared guard let availableMembers = fontManager.availableMembers(ofFontFamily: fontFamily) else { return [] } return availableMembers.compactMap { member in return member as? String } }
Edit 1
补充代码中,我尝试在不同位置添加.onChange调用,但均未触发,代码如下:
struct AddFontItems: View { var dm: DrawModel init(_ dm: DrawModel ) { self.dm = dm } var uniqueFontFamilies = NSFontManager.shared.availableFontFamilies.unique() var body: some View { VStack { ForEach(uniqueFontFamilies, id: \.self) { curFont in Button( curFont) { dm.curFont = curFont print( "Set font to: " + dm.curFont ) } .onChange( of: dm.curFont ) { // <--- here // fontStyles = getFontStyles(for: dm.curFont) print( "In onChange1.1" ) } } .onChange( of: dm.curFont ) { // <--- here // fontStyles = getFontStyles(for: dm.curFont) print( "In onChange1.2" ) } .onChange( of: dm.curFont ) { // <--- here // fontStyles = getFontStyles(for: dm.curFont) print( "In onChange1.3" ) } } } } struct AddFontStyleItems: View { var dm: DrawModel init(_ dm: DrawModel ) { self.dm = dm } @State private var fontStyles: [String] = [] // reusable for .onAppear var body: some View { VStack { ForEach(fontStyles, id: \.self) { curStyle in Button(curStyle) { dm.curFontStyle = curStyle print("Set Style:\t \(dm.curFontStyle)") } .onChange( of: dm.curFont ) { // <--- here fontStyles = getFontStyles(for: dm.curFont) print( "In onChange2.1" ) } } .onAppear { // TODO: Called once on app launch. Call on Font change fontStyles = getFontStyles(for: dm.curFont) print( "In onAppear" ) } .onChange( of: dm.curFont ) { // <--- here fontStyles = getFontStyles(for: dm.curFont) print( "In onChange2.2" ) } } .onChange( of: dm.curFont ) { // <--- here // fontStyles = getFontStyles(for: dm.curFont) print( "In onChange2.3" ) } } } func getFontStyles(for font: String) -> [String] { var justStyles: [String] = [] if let fontInfo = NSFontManager.shared.availableMembers(ofFontFamily: font ) { for curFontInfo in fontInfo { if curFontInfo.count > 1 { justStyles.append(curFontInfo[1] as? String ?? "") } } } return justStyles }
内容的提问来源于stack exchange,提问作者Keith
相关产品推荐
相关产品推荐

