当前位置: 首页 > 面试题库 >

Swift 3:设置Finder标签颜色

盖玉石
2023-03-14
问题内容

我正在尝试设置取景器显示的彩色标签。我知道的唯一功能是setResourceValue。但这需要本地化名称!

我也可以想象自己的母语和英语,但我不知道其他所有人。我不敢相信,这应该是这样。

是are转换函数,它接受诸如enum或int的标准参数并提供本地化的颜色名称吗?

我参与其中,但是只支持两种语言(德语和英语):

let colorNamesEN = [ "None", "Gray", "Green", "Purple", "Blue", "Yellow", "Red", "Orange" ]
let colorNamesDE = [ "",     "Grau", "Grün",  "Lila",   "Blau", "Gelb",   "Rot", "Orange" ]

public enum TagColors : Int8 {
    case None = -1, Gray, Green, Purple, Blue, Yellow, Red, Orange, Max
}

//let theURL : NSURL = NSURL.fileURLWithPath("/Users/dirk/Documents/MyLOG.txt")

extension NSURL {
    // e.g.  theURL.setColors(0b01010101)
    func tagColorValue(tagcolor : TagColors) -> UInt16 {
        return 1 << UInt16(tagcolor.rawValue)
    }

    func addTagColor(tagcolor : TagColors) -> Bool {
        let bits : UInt16 = tagColorValue(tagcolor) | self.getTagColors()
        return setTagColors(bits)
    }

    func remTagColor(tagcolor : TagColors) -> Bool {
        let bits : UInt16 = ~tagColorValue(tagcolor) & self.getTagColors()
        return setTagColors(bits)
    }

    func setColors(tagcolor : TagColors) -> Bool {
        let bits : UInt16 = tagColorValue(tagcolor)
        return setTagColors(bits)
    }

    func setTagColors(colorMask : UInt16) -> Bool {
        // get string for all available and requested bits
        let arr = colorBitsToStrings(colorMask & (tagColorValue(TagColors.Max)-1))

        do {
            try self.setResourceValue(arr, forKey: NSURLTagNamesKey)
            return true
        }
        catch {
            print("Could not write to file \(self.absoluteURL)")
            return false
        }
    }

    func getTagColors() -> UInt16 {
        return getAllTagColors(self.absoluteURL)
    }
}


// let initialBits: UInt8 = 0b00001111
func colorBitsToStrings(colorMask : UInt16) -> NSArray {
    // translate bits to (localized!) color names
    let countryCode = NSLocale.currentLocale().objectForKey(NSLocaleLanguageCode)!

    // I don't know how to automate it for all languages possible!!!!
    let colorNames = countryCode as! String == "de" ? colorNamesDE : colorNamesEN

    var tagArray = [String]()
    var bitNumber : Int = -1   // ignore first loop
    for colorName in colorNames {
        if bitNumber >= 0 {
            if colorMask & UInt16(1<<bitNumber) > 0 {
                tagArray.append(colorName)
            }
        }
        bitNumber += 1
    }
    return tagArray
}


func getAllTagColors(file : NSURL) -> UInt16 {
    var colorMask : UInt16 = 0

    // translate (localized!) color names to bits
    let countryCode = NSLocale.currentLocale().objectForKey(NSLocaleLanguageCode)!
    // I don't know how to automate it for all languages possible!!!!
    let colorNames = countryCode as! String == "de" ? colorNamesDE : colorNamesEN
    var bitNumber : Int = -1   // ignore first loop

    var tags : AnyObject?

    do {
        try file.getResourceValue(&tags, forKey: NSURLTagNamesKey)
        if tags != nil {
            let tagArray = tags as! [String]

            for colorName in colorNames {
                if bitNumber >= 0 {
                    // color name listed?
                    if tagArray.filter( { $0 == colorName } ).count > 0 {
                        colorMask |= UInt16(1<<bitNumber)
                    }
                }
                bitNumber += 1
            }
        }
    } catch {
        // process the error here
    }

    return colorMask
}

问题答案:

要设置单一颜色,setResourceValue确实应该使用API​​调用。但是,您应该使用的资源密钥是NSURLLabelNumberKeyURLResourceKey.labelNumberKey在Swift
3中(不是NSURLTagNamesKey):

enum LabelNumber: Int {
    case none
    case grey
    case green
    case purple
    case blue
    case yellow
    case red
    case orange
}

do {
    // casting to NSURL here as the equivalent API in the URL value type appears borked:
    // setResourceValue(_, forKey:) is not available there, 
    // and setResourceValues(URLResourceValues) appears broken at least as of Xcode 8.1…
    // fix-it for setResourceValues(URLResourceValues) is saying to use [URLResourceKey: AnyObject], 
    // and the dictionary equivalent also gives an opposite compiler error. Looks like an SDK / compiler bug. 
    try (fileURL as NSURL).setResourceValue(LabelNumber.purple.rawValue, forKey: .labelNumberKey)
}
catch {
    print("Error when setting the label number: \(error)")
}

(这是一个Swift 3端口,用于回答相关的Objective-C问题。已在Xcode 8.1,macOS Sierra
10.12.1上进行了测试)

要设置多种颜色,您可以使用通过标签键设置资源值时使用的API。此处介绍了这两种编码之间的区别:http
:
//arstechnica.com/apple/2013/10/os-x-10-9/9/
–基本上,标签键在内部设置了扩展属性“com.apple”。元数据:_kMDItemUserTags”,将这些标签字符串的数组存储为二进制plist,而上面显示的单色选项正在设置32字节长的扩展属性值“com.apple.FinderInfo”的第10个字节。

该键名称中的“本地化”在从用户设置的标签名称中实际设置的是用户选择的标签集的意义上有点混乱。这些标签值确实已本地化,但仅限于在您最初创建帐户时根据本地化设置进行设置的程度。为了演示,这些是Finder在我的系统上使用的标签值,我将其设置为芬兰语本地化作为测试,然后重新启动Finder,重新启动机器等:

➜  defaults read com.apple.Finder FavoriteTagNames
(
    "",
    Red,
    Orange,
    Yellow,
    Green,
    Blue,
    Purple,
    Gray
)

数据在该二进制plist值中的编码方式只是最喜欢的标记名称,后跟其在数组中的索引(固定为长度8,实际值从1开始,即按红色顺序匹配七个颜色,橙色,黄色,绿色,蓝色,紫色,灰色)。例如:

xattr -p com.apple.metadata:_kMDItemUserTags foobar.png | xxd -r -p | plutil -convert xml1 - -o -
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
    <string>Gray
1</string>
    <string>Purple
3</string>
    <string>Green
2</string>
    <string>Red
6</string>
</array>
</plist>

因此,不考虑系统本地化,实际上,在标签中设置任何字符串,后跟一个换行符,再跟一个1–7之间的数字将在Finder中显示,并带有标签索引指示的颜色。但是,要知道正确的当前值以从收藏夹标签集中获取要应用的标签(以便颜色和标签匹配),则需要从Finder首选项(该键来自“
FavoriteTagNames”)中读取该键。域“ com.apple.Finder”,该编码对那些喜欢的标记名称的数组进行编码,如上所示)。

如果您想获得正确的标签名称
颜色,则需要忽略从Finder首选项域中读取的内容(取决于您的应用是否被沙盒化,这可能会或可能不会做),从而忽略上述麻烦。使用多种颜色,这是一个示例解决方案,可以直接使用扩展属性值设置颜色(我使用SOExtendedAttributes以避免麻烦的xattr
C API):

enum LabelNumber: Int {
    case none
    case gray
    case green
    case purple
    case blue
    case yellow
    case red
    case orange

    // using an enum here is really for illustrative purposes:
    // to know the correct values to apply you would need to read Finder preferences (see body of my response for more detail).
    var label:String? {
        switch self {
        case .none: return nil
        case .gray: return "Gray\n1"
        case .green: return "Green\n2"
        case .purple: return "Purple\n3"
        case .blue: return "Blue\n4"
        case .yellow: return "Yellow\n5"
        case .red: return "Red\n6"
        case .orange: return "Orange\n7"
        }
    }

    static func propertyListData(labels: [LabelNumber]) throws -> Data {
        let labelStrings = labels.flatMap { $0.label }
        let propData = try! PropertyListSerialization.data(fromPropertyList: labelStrings,
                                                           format: PropertyListSerialization.PropertyListFormat.binary,
                                                           options: 0)
        return propData
    }
}

do {
    try (fileURL as NSURL).setExtendedAttributeData(LabelNumber.propertyListData(labels: [.gray, .green]),
                                                     name: "com.apple.metadata:_kMDItemUserTags")
}
catch {
    print("Error when setting the label number: \(error)")
}


 类似资料:
  • 我正在使用mpandroid图表库创建饼图。 我想格式化饼图上的文本标签,但我不知道如何做到这一点 但是,它只改变数据的值,而不是标签。此外,我想成为饼图中的标签。我还尝试使用以下代码, 但是,它不起作用。 我的代码如下: 简而言之,我想做的就是 更改饼图中的标签颜色(从白色变为黑色) 防止标签超出饼图。(如图中所示的剩余划痕) 有人能帮我吗? 我还尝试了以下链接中提到的这些解决方案。 链接1链接

  • Since 8.0 setTitleColor 可通过接口调用,改变TitleBar的颜色 使用方法 AlipayJSBridge.call("setTitleColor", { color: 16775138, reset: false //(可选,默认为false) 是否重置title颜色为默认颜色。 }); 代码演示 <div style="padding-top:80px;">

  • 我想知道如何改变由'com.android.support:design:22.2.0'库提供的FAB(浮动操作按钮)小部件的图标颜色从绿色到白色。 style.xml activity_main.xml

  • 我使用TextInputLayout,如果输入字段是强制性的,我希望以编程方式设置提示文本颜色和浮动标签颜色。在转到TextInputLayout之前,我使用以下方法以编程方式设置提示文本颜色 有人能指导我如何通过编程方式为TextInputLayout设置提示文本颜色和浮动标签颜色吗。

  • 操作步骤: ①在"图层管理"模块,选择一个带有数据的标注图层,点击"样式设置"。 ②选择"散点图" ,点击应用。 ③应用后,数据显示。 操作动图: [查看原图]

  • 所以我想在条形图中选择一个条形图,当我选择一个条形图时,它会改变条形图的颜色(我知道怎么做),但也会改变相应x轴标签的颜色。有没有办法做到这一点,如果有,谁能帮帮我吗?