带有属性字符串的 UIPickerView

Posted

技术标签:

【中文标题】带有属性字符串的 UIPickerView【英文标题】:UIPickerView with attributes string 【发布时间】:2018-09-24 20:03:13 【问题描述】:

根据 Apple 的文档,有一个名为 pickerView(_:attributedTitleForRow:forComponent:) 的 UIPickerView 委托函数。但是,我试图让它工作,但我似乎在这里做错了什么。我希望有人可以帮助我。

为了简单起见,我有一个简单的程序,它在选择器视图的两个组件中显示两个数组的内容。该程序只是一个视图控制器和一个选择器视图。代码呈现给她:

import UIKit

类 ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource

var familyNames = [String]()
var fontName = ""
let firstArray = Array(0...99)
let secondArray = Array(0...99)
let fontCount = 0

@IBOutlet weak var samplePickerView: UIPickerView!
@IBOutlet weak var fontLabel: UILabel!

override func viewDidLoad() 
    super.viewDidLoad()

    familyNames = UIFont.familyNames.sorted()
    let fontNames = UIFont.fontNames(forFamilyName: familyNames[17])
    fontName = fontNames.first!

    samplePickerView.delegate = self
    samplePickerView.dataSource = self


func numberOfComponents(in pickerView: UIPickerView) -> Int 
    return 2


func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int 

    if component == 0 
        return firstArray.count
     else 
        return secondArray.count
    


func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? 

    var rowTitle = ""
    let font = UIFont(name: fontName, size: 18.0)
    let stringDictionary = [NSAttributedString.Key.font: font]

    switch component 
    case 0:
        rowTitle = String(format: "%03d", firstArray[row])
    case 1:
        rowTitle = String(format: "%03d", secondArray[row])
    default:
        break
    

    let returnString = NSAttributedString(string: rowTitle, attributes: stringDictionary as [NSAttributedString.Key : Any])
    print(returnString)
    return returnString

选择器视图现在应该在 Bradley Hand 中显示标题,因此很容易发现它有效。 不幸的是,选择器视图没有显示属性字符串中的标题。委托方法返回的字符串是一个属性字符串,所以它应该可以工作。图片显示情况并非如此。我究竟做错了什么?

【问题讨论】:

您确定font 不是nil?您需要将字体名称而不是家族名称传递给 UIFont 初始化程序。 控制台记录了什么?此外,您可以通过使用类型声明字符串字典来避免强制转换。 @rmaddy familyNames 是 [String] @Carpsen90 是的,但是是family 的名字还是font 的名字? 哦,这是姓氏,我知道了 【参考方案1】:

在没有找到解决方案后,我向 Apple 申请了 DTS,以了解我做错了什么。显然,我没有做错任何事情,但是方法“pickerView(_ pickerView: UIPickerView, attributesTitleForRow row: Int, forComponent component: Int) -> NSAttributedString?”不允许您在属性字符串上进行太多操作。 Apple 的回答是:“UIPickerView 的属性TitleForRow 委托不会改变字体属性,但会适用于字体颜色等其他属性。”

幸运的是,由于我想改变字体大小和字体,有一种方法可以在 UIPickerView 中获得不同的字体和字体大小。 Apple 提供的解决方案:“如果要使用 NSAttributedString 中可用的所有字体属性,请使用 viewForRow 并返回 UILabel 作为替代。”

现在的代码如下所示: var familyNames = 字符串 变种字体名称 = "" 让 firstArray = Array(0...99) 让 secondArray = Array(0...99) 让 fontCount = 0

@IBOutlet weak var samplePickerView: UIPickerView!
@IBOutlet weak var fontLabel: UILabel!

override func viewDidLoad() 
    super.viewDidLoad()

    familyNames = UIFont.familyNames.sorted()
    let fontNames = UIFont.fontNames(forFamilyName: familyNames[17])
    fontName = fontNames.first!

    samplePickerView.delegate = self
    samplePickerView.dataSource = self


func numberOfComponents(in pickerView: UIPickerView) -> Int 
    return 2


func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int 

    if component == 0 
        return firstArray.count
     else 
        return secondArray.count
    


func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView 

    var rowTitle = ""
    let pickerLabel = UILabel()

    pickerLabel.textColor = UIColor.blue

    switch component 
        case 0:
            rowTitle = String(format: "%03d", firstArray[row])
        case 1:
            rowTitle = String(format: "%03d", secondArray[row])
        default:
            break
    

    pickerLabel.text = rowTitle
    pickerLabel.font = UIFont(name: fontName, size: 24.0)
    pickerLabel.textAlignment = .center

    return pickerLabel

结果如下所示: 这是我想对选择器视图中的文本进行的操作。

【讨论】:

【参考方案2】:

问题来了

familyNames = UIFont.familyNames.sorted()

您得到字体系列的名称,但UIFont 初始化程序将字体名称作为参数,而不是它的系列名称。来自Apple Documentation:

姓氏

字体系列名称对应于字体的基本名称,例如 Times New Roman。您可以将返回的字符串传递给fontNames(forFamilyName:) 方法以检索该系列可用的字体名称列表。 然后您可以使用相应的字体名称来检索实际的字体对象。

因此,如果您想获取给定姓氏的字体名称,请使用以下方法。然后您可以使用它们来创建字体。

UIFont.fontNames(forFamilyName: String)

另外,不要通过像familyNames[17] 这样的神奇索引号来访问您的字体系列名称,这是一种不好的方法。您可能会越界,这会使您的应用崩溃。

我会将我的字体名称存储在一个常量中,例如

let pickerFontName = "MyAwesomeFont"

// later in your program
let font = UIFont(name: pickerFontName, size: 18.0)

【讨论】:

您好 Juri,感谢您的帮助。姓氏确实不是正确的名称。是的,使用索引确实不是正确的方法,但这不是实际的应用程序,它是一个测试 UIPickerView 的属性字符串的演示。我把代码改成了字体名,还是不行。

以上是关于带有属性字符串的 UIPickerView的主要内容,如果未能解决你的问题,请参考以下文章

带有重音字符的 Java 属性文件

带有属性字符串的 UIPickerView

在 HTML 属性中调用带有字符串参数的函数的正确语法是啥? [复制]

带有属性注释的属性文件生成

在属性 href 中查找所有带有特定字符串的“A”标签?

带有 TextView 的属性文本导致崩溃