uipickerview的格式化对齐

Formatting alignment of uipickerview

我已经搜索过,但没有找到任何可以帮助我格式化 pickerview 中每一行的对齐方式的内容。

目前看起来是这样的:

我想做的是右对齐左 £ 行,左对齐右 pence 行,这样就没有差距,当前值将是 25.31 英镑,或者现在存在的大差距。

我发现了一些格式化背景和字体大小但不对齐的代码。

任何帮助或链接将不胜感激。

这是我的完整 ViewController 代码...

import Foundation
import UIKit

class LocationViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {

    @IBOutlet weak var DisplayStartMileage: UITextField!
    @IBOutlet weak var labelFuelAmount: UILabel!
    @IBOutlet weak var spinFuelAmount: UIPickerView!

    var mileageToPass: String!

    var fuelAmount: Double = 0.00

    var pickerData = [[String]]()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        var poundValues = [String]()
        var penceValues = [String]()
        for var indexP:Int = 0; indexP < 100; indexP += 1 {
            poundValues.append("£ \(indexP)")
            penceValues.append(NSString(format: ".%02d", indexP) as String)
        }

        self.pickerData = [poundValues, penceValues]

        spinFuelAmount.delegate = self
        spinFuelAmount.dataSource = self

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func FuelSegmentChanged(sender: UISegmentedControl) {

        switch sender.selectedSegmentIndex
        {
        case 0:
            labelFuelAmount.hidden = false
            spinFuelAmount.hidden = false

        case 1:
            labelFuelAmount.hidden = true
            spinFuelAmount.hidden = true

        default:
            break; 
        }

    }

    func numberOfComponentsInPickerView(spinFuelAmount: UIPickerView) -> Int {
        return pickerData.count
    }

    func pickerView(spinFuelAmount: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return pickerData[component].count
    }

    func pickerView(spinFuelAmount: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
        return pickerData[component][row]
    }

    func pickerView(spinFuelAmount: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

        var firstComponent = pickerData[0][spinFuelAmount.selectedRowInComponent(0)]
        firstComponent = firstComponent.stringByReplacingOccurrencesOfString( "£ ", withString: "" )

        var secondComponent = pickerData[1][spinFuelAmount.selectedRowInComponent(1)]
        secondComponent = secondComponent.stringByReplacingOccurrencesOfString( ".", withString: "" )

        if let firstValue = firstComponent.toInt(), let secondValue = secondComponent.toInt() {
            let fuelAmount = firstValue + secondValue / 100
        }

    }

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

        let titleData = pickerData[row]
        var myString1 = NSMutableAttributedString(string:titleData)
        let myString1Font1 = UIFont(name:"AvenirNext-Regular", size:24.0)
        let myString1Color1 = UIColor(red: 0.292745, green: 0.461693, blue: 0.998524, alpha: 1.000000)
        let originalNSString = myString1.string as NSString
        let myString1Range1 = originalNSString.rangeOfString(titleData)
        var myString1ParaStyle1 = NSMutableParagraphStyle()
        myString1ParaStyle1.baseWritingDirection = NSWritingDirection.Natural
        myString1ParaStyle1.lineBreakMode = NSLineBreakMode.ByWordWrapping
        myString1.addAttribute(NSUnderlineColorAttributeName, value:myString1Color1, range:myString1Range1)
        myString1.addAttribute(NSParagraphStyleAttributeName, value:myString1ParaStyle1, range:myString1Range1)
        myString1.addAttribute(NSFontAttributeName, value:myString1Font1!, range:myString1Range1)

        if component == 0 {
            myString1ParaStyle1.alignment = NSTextAlignment.Left
        } else if component == 1 {
            myString1ParaStyle1.alignment = NSTextAlignment.Right
        }

        return myString1
    }

    func pickerView(spinFuelAmount: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView!) -> UIView {

        var pickerLabel = view as! UILabel!
        if view == nil {
            pickerLabel = UILabel()
            let hue = CGFloat(row)/CGFloat(pickerData.count)
            pickerLabel.backgroundColor = UIColor(hue: hue, saturation: 1.0, brightness:1.0, alpha: 1.0)
        }
        let titleData = pickerData[row]
        var myString1 = NSMutableAttributedString(string:titleData)
        let myString1Font1 = UIFont(name:"AvenirNext-Regular", size:24.0)
        let myString1Color1 = UIColor(red: 0.292745, green: 0.461693, blue: 0.998524, alpha: 1.000000)
        let originalNSString = myString1.string as NSString
        let myString1Range1 = originalNSString.rangeOfString(titleData)
        var myString1ParaStyle1 = NSMutableParagraphStyle()
        myString1ParaStyle1.baseWritingDirection = NSWritingDirection.Natural
        myString1ParaStyle1.lineBreakMode = NSLineBreakMode.ByWordWrapping
        myString1.addAttribute(NSUnderlineColorAttributeName, value:myString1Color1, range:myString1Range1)
        myString1.addAttribute(NSParagraphStyleAttributeName, value:myString1ParaStyle1, range:myString1Range1)
        myString1.addAttribute(NSFontAttributeName, value:myString1Font1!, range:myString1Range1)
        pickerLabel!.attributedText = myString1

        if component == 0 {
            myString1ParaStyle1.alignment = NSTextAlignment.Left
        } else if component == 1 {
            myString1ParaStyle1.alignment = NSTextAlignment.Right
        }


        return pickerLabel
    }
}

这应该让你开始:

func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView!) -> UIView {
        let pickerLabel = UILabel()
        let titleData = pickerData[row]
        let myTitle = NSAttributedString(string: titleData, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 26.0)!,NSForegroundColorAttributeName:UIColor.blackColor()])
        pickerLabel.attributedText = myTitle
       return pickerLabel
    }

还有这个:

func pickerView(pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
    let titleData = pickerData[row]
    var myTitle = NSAttributedString(string: titleData, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 15.0)!,NSForegroundColorAttributeName:UIColor.blueColor()])
    return myTitle
}

对于 Attributed 字符串,您可以在此处修改文本属性以适合您想要的内容,您可以设置类似这样的东西,您必须弄清楚如何放置 Attributed 字符串,但它非常使用上面的第二种方法很简单:

var myString1 = NSMutableAttributedString(string:".45")

let myString1Font1 = UIFont(name:"AvenirNext-Regular", size:24.0)

let myString1Color1 = UIColor(red: 0.292745, green: 0.461693, blue: 0.998524, alpha: 1.000000)

let originalNSString = myString1.string as NSString
let myString1Range1 = originalNSString.rangeOfString(".45")

var myString1ParaStyle1 = NSMutableParagraphStyle()
myString1ParaStyle1.alignment = NSTextAlignment.Right
myString1ParaStyle1.baseWritingDirection = NSWritingDirection.Natural
myString1ParaStyle1.defaultTabInterval = 0
myString1ParaStyle1.firstLineHeadIndent = 0
myString1ParaStyle1.headIndent = 0
myString1ParaStyle1.hyphenationFactor = 0
myString1ParaStyle1.lineBreakMode = NSLineBreakMode.ByWordWrapping
myString1ParaStyle1.lineHeightMultiple = 0
myString1ParaStyle1.lineSpacing = 0
myString1ParaStyle1.maximumLineHeight = 0
myString1ParaStyle1.minimumLineHeight = 0
myString1ParaStyle1.paragraphSpacing = 0
myString1ParaStyle1.paragraphSpacingBefore = 0
myString1ParaStyle1.tailIndent = 0

myString1.addAttribute(NSUnderlineColorAttributeName, value:myString1Color1, range:myString1Range1)
myString1.addAttribute(NSParagraphStyleAttributeName, value:myString1ParaStyle1, range:myString1Range1)
myString1.addAttribute(NSFontAttributeName, value:myString1Font1!, range:myString1Range1)

这似乎有效:

func pickerView(pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
    let titleData = pickerData[row]

    var myString1 = NSMutableAttributedString(string:titleData)
    let myString1Font1 = UIFont(name:"AvenirNext-Regular", size:24.0)
    let myString1Color1 = UIColor(red: 0.292745, green: 0.461693, blue: 0.998524, alpha: 1.000000)
    let originalNSString = myString1.string as NSString
    let myString1Range1 = originalNSString.rangeOfString(titleData)
    var myString1ParaStyle1 = NSMutableParagraphStyle()
    myString1ParaStyle1.baseWritingDirection = NSWritingDirection.Natural
    myString1ParaStyle1.lineBreakMode = NSLineBreakMode.ByWordWrapping
    myString1.addAttribute(NSUnderlineColorAttributeName, value:myString1Color1, range:myString1Range1)
    myString1.addAttribute(NSParagraphStyleAttributeName, value:myString1ParaStyle1, range:myString1Range1)
    myString1.addAttribute(NSFontAttributeName, value:myString1Font1!, range:myString1Range1)

    if pickerView == myPickerf {
        myString1ParaStyle1.alignment = NSTextAlignment.Left
    } else if pickerView == myPicker {
        myString1ParaStyle1.alignment = NSTextAlignment.Right
    }

    return myString1
}

func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView!) -> UIView {
    var pickerLabel = view as! UILabel!
    if view == nil {
        pickerLabel = UILabel()
        let hue = CGFloat(row)/CGFloat(pickerData.count)
        pickerLabel.backgroundColor = UIColor(hue: hue, saturation: 1.0, brightness:1.0, alpha: 1.0)
    }
    let titleData = pickerData[row]
    var myString1 = NSMutableAttributedString(string:titleData)
    let myString1Font1 = UIFont(name:"AvenirNext-Regular", size:24.0)
    let myString1Color1 = UIColor(red: 0.292745, green: 0.461693, blue: 0.998524, alpha: 1.000000)
    let originalNSString = myString1.string as NSString
    let myString1Range1 = originalNSString.rangeOfString(titleData)
    var myString1ParaStyle1 = NSMutableParagraphStyle()
    myString1ParaStyle1.baseWritingDirection = NSWritingDirection.Natural
    myString1ParaStyle1.lineBreakMode = NSLineBreakMode.ByWordWrapping
    myString1.addAttribute(NSUnderlineColorAttributeName, value:myString1Color1, range:myString1Range1)
    myString1.addAttribute(NSParagraphStyleAttributeName, value:myString1ParaStyle1, range:myString1Range1)
    myString1.addAttribute(NSFontAttributeName, value:myString1Font1!, range:myString1Range1)
    pickerLabel!.attributedText = myString1

    if pickerView == myPickerf {
        myString1ParaStyle1.alignment = NSTextAlignment.Left
    } else if pickerView == myPicker {
        myString1ParaStyle1.alignment = NSTextAlignment.Right
    }


    return pickerLabel
}

这是您重新格式化的代码,这应该可以工作:

import Foundation
import UIKit

class LocationViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {

    @IBOutlet weak var DisplayStartMileage: UITextField!
    @IBOutlet weak var labelFuelAmount: UILabel!
    @IBOutlet weak var spinFuelAmount: UIPickerView!

    var mileageToPass: String!

    var fuelAmount: Double = 0.00

    var pickerData = [[String]]()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        var poundValues = [String]()
        var penceValues = [String]()
        for var indexP:Int = 0; indexP < 100; indexP += 1 {
            poundValues.append("£ \(indexP)")
            penceValues.append(NSString(format: ".%02d", indexP) as String)
        }

        self.pickerData = [poundValues, penceValues]

        spinFuelAmount.delegate = self
        spinFuelAmount.dataSource = self

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func FuelSegmentChanged(sender: UISegmentedControl) {

        switch sender.selectedSegmentIndex
        {
        case 0:
            labelFuelAmount.hidden = false
            spinFuelAmount.hidden = false

        case 1:
            labelFuelAmount.hidden = true
            spinFuelAmount.hidden = true

        default:
            break;
        }

    }

    func numberOfComponentsInPickerView(spinFuelAmount: UIPickerView) -> Int {
        return pickerData.count
    }

    func pickerView(spinFuelAmount: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return pickerData[component].count
    }

    func pickerView(spinFuelAmount: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
        return pickerData[component][row]
    }

    func pickerView(spinFuelAmount: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

        var firstComponent = pickerData[0][spinFuelAmount.selectedRowInComponent(0)]
        firstComponent = firstComponent.stringByReplacingOccurrencesOfString( "£ ", withString: "" )

        var secondComponent = pickerData[1][spinFuelAmount.selectedRowInComponent(1)]
        secondComponent = secondComponent.stringByReplacingOccurrencesOfString( ".", withString: "" )

        if let firstValue = firstComponent.toInt(), let secondValue = secondComponent.toInt() {
            let fuelAmount = firstValue + secondValue / 100
        }

    }

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

        let titleData = pickerData[component][row] //this is bad, you'll have to compute what to do about this, but you get the point
        var myString1 = NSMutableAttributedString(string:titleData)
        let myString1Font1 = UIFont(name:"AvenirNext-Regular", size:24.0)
        let myString1Color1 = UIColor(red: 0.292745, green: 0.461693, blue: 0.998524, alpha: 1.000000)
        let originalNSString = myString1.string as NSString
        let myString1Range1 = originalNSString.rangeOfString(titleData)
        var myString1ParaStyle1 = NSMutableParagraphStyle()
        myString1ParaStyle1.baseWritingDirection = NSWritingDirection.Natural
        myString1ParaStyle1.lineBreakMode = NSLineBreakMode.ByWordWrapping
        myString1.addAttribute(NSUnderlineColorAttributeName, value:myString1Color1, range:myString1Range1)
        myString1.addAttribute(NSParagraphStyleAttributeName, value:myString1ParaStyle1, range:myString1Range1)
        myString1.addAttribute(NSFontAttributeName, value:myString1Font1!, range:myString1Range1)

        if component == 0 {
            myString1ParaStyle1.alignment = NSTextAlignment.Left
        } else if component == 1 {
            myString1ParaStyle1.alignment = NSTextAlignment.Right
        }

        return myString1
    }

    func pickerView(spinFuelAmount: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView!) -> UIView {

        var pickerLabel = view as! UILabel!
        if view == nil {
            pickerLabel = UILabel()
            let hue = CGFloat(row)/CGFloat(pickerData.count)
            pickerLabel.backgroundColor = UIColor(hue: hue, saturation: 1.0, brightness:1.0, alpha: 1.0)
        }
        let titleData = pickerData[component][row]
        var myString1 = NSMutableAttributedString(string:titleData)
        let myString1Font1 = UIFont(name:"AvenirNext-Regular", size:24.0)
        let myString1Color1 = UIColor(red: 0.292745, green: 0.461693, blue: 0.998524, alpha: 1.000000)
        let originalNSString = myString1.string as NSString
        let myString1Range1 = originalNSString.rangeOfString(titleData)
        var myString1ParaStyle1 = NSMutableParagraphStyle()
        myString1ParaStyle1.baseWritingDirection = NSWritingDirection.Natural
        myString1ParaStyle1.lineBreakMode = NSLineBreakMode.ByWordWrapping
        myString1.addAttribute(NSUnderlineColorAttributeName, value:myString1Color1, range:myString1Range1)
        myString1.addAttribute(NSParagraphStyleAttributeName, value:myString1ParaStyle1, range:myString1Range1)
        myString1.addAttribute(NSFontAttributeName, value:myString1Font1!, range:myString1Range1)
        pickerLabel!.attributedText = myString1

        if component == 0 {
            myString1ParaStyle1.alignment = NSTextAlignment.Left
        } else if component == 1 {
            myString1ParaStyle1.alignment = NSTextAlignment.Right
        }


        return pickerLabel
    }
}

您需要检查我的工作并确保在调用 THIS 时:

let titleData = pickerData[component][row]

它实际上指向正确的字典项,即 Pounds 或 Pense。我实际上查看了您的代码,我看到您已经有了 pickerData[component][row],所以我重新格式化,然后将它们用于可变属性字符串调用者。查看修改后的代码,这确实是您的代码,但有更正

您应该通过实施以下方法来实现:

func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView!) -> UIView {

}

也许是更好的方法....以下方法可能会有所帮助:

// Swift
//   UIPickerView Delegate method

func pickerView(pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
    return CGFloat(50.0)
}

使用它,可以删除 "bloat" 代码,并使用 2 个组件实现以下内容:

默认情况下组件会居中对齐,看起来整个选择器也会居中对齐。

对于像在 UIDatePicker 中那样尝试对齐多个组件的任何人,我正在为我的月和年仅选择器视图执行此操作:

我有一个字符串扩展来计算宽度:

extension String {
func width(withConstraintedHeight height: CGFloat, font: UIFont) -> CGFloat {
    let constraintRect = CGSize(width: .greatestFiniteMagnitude, height: height)
    let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil)

    return ceil(boundingBox.width)
}
}

然后我用它来计算每个组件中最大值的宽度,并在pickerview delegate中设置它的宽度

func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
    let componentValues = self.pickerViewDataSource[component]
    var maxWidth = CGFloat(0)

    for value in componentValues {
        let valueWidth = value.width(withConstraintedHeight: 20, font: self.pickerLabelFont)
        if valueWidth > maxWidth {
            maxWidth = valueWidth
        }
    }

    return maxWidth + 5
}

现在我使用用于计算宽度的相同字体创建标签

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

    var pickerLabel = view as? UILabel;

    if (pickerLabel == nil)
    {
        pickerLabel = UILabel()

        pickerLabel?.font = self.pickerLabelFont
        pickerLabel?.textAlignment = NSTextAlignment.center
    }

    if component < self.pickerViewDataSource.count && row < self.pickerViewDataSource[component].count {
        pickerLabel?.text = self.pickerViewDataSource[component][row]
    }

    pickerLabel!.adjustsFontSizeToFitWidth = true
    return pickerLabel!;
}

这使得UIPickerView中的每个组件只使用它需要显示最大值的宽度。默认情况下,UIPickerView 会将组件居中对齐,因此它们会保持彼此靠近,这就是为什么我将 +5 作为边距。请参阅下面我的选择器现在的示例:

我用它来右对齐 pickerview 中的文本:

func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
  var pickerLabel: UILabel? = (view as? UILabel)
  if pickerLabel == nil {
    pickerLabel = UILabel()
    pickerLabel?.font = UIFont.systemFont(ofSize: 20.0)
    pickerLabel?.textAlignment = .right
  }

  pickerLabel?.text = data[row]
  pickerLabel?.textColor = UIColor.red

  return pickerLabel!
}