如何在 Swift 的分段控件中调整 textLabel 的大小? [英] How to resize textLabel in segmented control in Swift?

查看:29
本文介绍了如何在 Swift 的分段控件中调整 textLabel 的大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

UIViewController 中,有一个位于视图顶部的分段控制器.约束:左:0,右:0,顶:0,高度:90.

每次发布​​ UIApplicationDidBecomeActive 通知时,分段控件应通过调用 func updateUI()

用最新日期更新其视图

在第一次加载时,当调用 viewDidLoad 时,每个段中的文本都按预期显示.
但是,如果应用程序进入后台,当它回到前台时,分段控件的标签不容纳文本并显示 3 个点......之后.请参阅下面的附件和 gif.

Scope:每次发布 .UIApplicationDidBecomeActive 通知时更新每个段的分段控件标题.公共 Github 项目

解决方案

该问题仅在 10.3 iOS 版本中重现.解决方案:

存储分段标签的初始属性:

fileprivate var 高度:CGFloat!文件私有变量宽度:CGFloat!

getNextDays 之前添加到 ViewDidLoad:

let label = segmentedControl.subviews[0].subviews[0] as!用户界面标签高度 = label.frame.height宽度 = label.frame.width

设置文字:

值在 0...5 {segmentedControl.setTitle(stringDates[value], forSegmentAt: value)}

然后修复框架:

let labels = segmentedControl.subviews.map{ $0.subviews[1] } as![用户界面标签]labels.forEach {(标签)在label.numberOfLines = 0让框架 = label.framelabel.frame = CGRect(x: frame.origin.x, y: frame.origin.y, width: width, height: height)}

具有一些崩溃保护的示例代码

In a UIViewController there is a Segmented Controller placed at the top of the view. Constraints: left: 0, right:0, top: 0, height:90.

Every time a UIApplicationDidBecomeActive notification is posted, segmented control should update it's view with the newest date by calling func updateUI()

On first load, when viewDidLoad is called the text in each segment is displayed as expected.
However, if the app goes in background, when it comes back in foreground, the label of the segmented control does not accommodate the text and shows 3 dots... after. See attachment and gif below.

Scope: update segmented control title for each segment every time .UIApplicationDidBecomeActive notification is posted. Public Github project https://github.com/bibscy/testProject

 class ViewController: UIViewController {

   var stringDates = [String]()

   var dateNow: Date {
     return Date()
   }
      @IBOutlet weak var segmentedControl: UISegmentedControl!

       func updateUI() {
    //create string dates and set the title of for each segment in segmented control
          self.getNextDays()  
     }

   override func viewDidLoad() {
      super.viewDidLoad()

      NotificationCenter.default.addObserver(self, selector: #selector(updateUI), name: .UIApplicationDidBecomeActive, object: nil)

     UILabel.appearance(whenContainedInInstancesOf: [UISegmentedControl.self]).numberOfLines = 0

      self.getNextDays()
   }
}


  extension ViewController {

//for each segment, construct a string date with the currentDate() being first, followed by 5 consecutive days
func getNextDays()  {

    stringDates.removeAll() //clear any previous data

    for i in 0...5 {
        let dateFormatter = DateFormatter()
        let today = dateNow
        let calendar = Calendar.current

        if i == 0 {
            let dayComponent = Calendar.current.component(.weekday,from: today)
            let day = Calendar.current.component(.day, from: today) //Int
            let dayString = dateFormatter.shortWeekdaySymbols[dayComponent-1] //Symbol


            let month = Calendar.current.component(.month, from: today)
            let monthSymbol = dateFormatter.shortMonthSymbols[month-1]
            let dayMonthString =  dayString + " " + String(day) + " " + monthSymbol
            stringDates.append(dayMonthString)


        } else {
            var components = DateComponents()
            components.weekday = i

            let nextDay = calendar.date(byAdding: components, to: today)
            let nextDayComponent = Calendar.current.component(.weekday,from: nextDay!)
            let day = Calendar.current.component(.day, from: nextDay!)
            let dayString = dateFormatter.shortWeekdaySymbols[nextDayComponent-1] // Symbol


            let month = Calendar.current.component(.month, from: nextDay!)
            let monthSymbol = dateFormatter.shortMonthSymbols[month-1]
            let dayMonthString = dayString + " " + String(day) + " " + monthSymbol
            stringDates.append(dayMonthString)
        }
    }


      //set the title for each segment from stringDates array
       for value in 0...5 {
         self.segmentedControl.setTitle(self.stringDates[value], forSegmentAt: value)
      }
   } //end of getNextDays()  
}

解决方案

The problem is only reproduced in 10.3 iOS version. Solution:

Store initial properties of a segmented label:

fileprivate var height: CGFloat! 
fileprivate var width: CGFloat!

Add to ViewDidLoad just before getNextDays:

let label = segmentedControl.subviews[0].subviews[0] as! UILabel 
height = label.frame.height 
width = label.frame.width

Set text :

for value in 0...5 {
   segmentedControl.setTitle(stringDates[value], forSegmentAt: value)
}

And fix frames after that:

let labels = segmentedControl.subviews.map{ $0.subviews[1] } as! [UILabel]
    labels.forEach { (label) in
        label.numberOfLines = 0
        let frame = label.frame
        label.frame = CGRect(x: frame.origin.x, y: frame.origin.y, width: width, height: height)
    }

Sample code with some crash protection

这篇关于如何在 Swift 的分段控件中调整 textLabel 的大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆