【问题标题】:Formatting alignment of uipickerviewuipickerview的格式化对齐方式
【发布时间】: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
    }
}

【问题讨论】:

    标签: ios swift uipickerview


    【解决方案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 {
        
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-10-25
          • 1970-01-01
          • 1970-01-01
          • 2017-07-22
          • 2023-03-27
          • 1970-01-01
          • 2015-07-29
          相关资源
          最近更新 更多