uipickerview的格式化对齐方式
Posted
技术标签:
【中文标题】uipickerview的格式化对齐方式【英文标题】:Formatting alignment of uipickerview 【发布时间】:2015-08-15 15:12:48 【问题描述】:我已经搜索并找不到任何可以帮助我格式化我的pickerview 中每一行的对齐方式的东西。
目前看起来是这样的:
我想要做的是右对齐左£行和左对齐右便士行,这样就没有差距,当前值将是 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
【问题讨论】:
【参考方案1】:也许是更好的方法....以下方法可能会有所帮助:
// Swift
// UIPickerView Delegate method
func pickerView(pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat
return CGFloat(50.0)
使用它,可以消除代码的“膨胀”,并通过 2 个组件实现以下目标:
默认情况下,组件将居中对齐,并且看起来整个选择器也将居中对齐。
【讨论】:
【参考方案2】:我用它来右对齐选择器视图中的文本:
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!
【讨论】:
这应该是选择的答案,比当前选择的要干净。只应注意 data[row] 应更改为您的数据变量。【参考方案3】:这应该让你开始:
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.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.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]
它实际上指向正确的字典项目,即英镑或便士。我实际上查看了您的代码,更多,我发现您已经有了 pickerData[component][row],所以我重新格式化,然后将它们用于可变属性的字符串调用者。查看修改后的代码,这确实是您的代码,但进行了更正
【讨论】:
谢谢...。不幸的是,当我使用前两位代码时,这类似于我在@makeapple.com 找到的代码...我得到一个 Swift 编译器错误...找不到'NSAttributedString' 类型的初始化程序,它在 let myTitle 行中都接受类型为 '(string: ([(String)]), attributes: [String : NSObject])' 的参数列表 是的,在 MakeApple.com 上也是一样,让我为你检查错误部分,一秒钟 谢谢...... 顺便说一句...我可能在我的问题中引入了混淆。我的选择器视图有两个微调器(列),而不是我所说的行。用户可以将 £ 列 (£0 - £99) 独立旋转到便士列 (.00 - .99),以便他们可以选择从 £0.00 到 (£99.99) 的任何金额。我需要的是这些列的对齐方式。 当然,np,我刚刚发布的解决方案将允许您独立调整两个选择器,您只需将 POUNDS 整数的 NSTextAlignment 调整为 RIGHT,然后将 PENCE 调整为 LEFT你应该拥有它【参考方案4】:对于任何尝试对齐多个组件(例如在 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委托中设置它的宽度
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 作为边距。请看下面我的选择器现在的示例:
【讨论】:
【参考方案5】:您应该通过实现该方法来实现这一点:
func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView!) -> UIView
【讨论】:
以上是关于uipickerview的格式化对齐方式的主要内容,如果未能解决你的问题,请参考以下文章