如何在 Swift 的分段控件中调整 textLabel 的大小? [英] How to resize textLabel in segmented control in Swift?
问题描述
在 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屋!