如何在 Swift 的分段控件中调整 textLabel 的大小?
Posted
技术标签:
【中文标题】如何在 Swift 的分段控件中调整 textLabel 的大小?【英文标题】:How to resize textLabel in segmented control in Swift? 【发布时间】:2018-05-29 07:55:14 【问题描述】:在UIViewController
中,视图顶部有一个分段控制器。约束:左:0,右:0,上:0,高度:90。
每次发布UIApplicationDidBecomeActive
通知时,分段控件应通过调用func updateUI()
将其视图更新为最新日期
首次加载时,当调用 viewDidLoad
时,每个段中的文本都会按预期显示。
但是,如果应用程序进入后台,当它返回前台时,分段控件的标签不包含文本并显示 3 个点......之后。请参阅下面的附件和 gif。
范围:每次发布.UIApplicationDidBecomeActive
通知时更新每个段的分段控件标题。
公共 Github 项目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()
【问题讨论】:
隐藏这个extension Claim func updateUI() self.getNextDays() // UILabel.appearance(whenContainedInInstancesOf: [UISegmentedControl.self]).numberOfLines = 0
并检查
@Anbu.karthik 如果我在扩展名self.getNextDays()
和UILabel.appearance(whenContainedInInstancesOf: [UISegmentedControl.self]).numberOfLines = 0
中注释掉,文本将按预期呈现在每个段中。基本上,如果我调用 self.getNextDays()
,标签不会调整大小。这反过来意味着当在 self.getNextDays()
内部调用 self.segmentedControl.setTitle(self.stringDates[value], forSegmentAt:
时,标签没有正确调整大小,这是我的理解。
【参考方案1】:
该问题仅在 ios 10.3 版本中重现。 解决方案:
存储分段标签的初始属性:
fileprivate var height: CGFloat!
fileprivate var width: CGFloat!
在 getNextDays
之前添加到 ViewDidLoad:
let label = segmentedControl.subviews[0].subviews[0] as! UILabel
height = label.frame.height
width = label.frame.width
设置文字:
for value in 0...5
segmentedControl.setTitle(stringDates[value], forSegmentAt: value)
然后修复帧:
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
【讨论】:
我在 Xcode 版本 8.3.3 (8E3004b) 上运行。在界面生成器中设置分段控件的高度是不可能的。所有约束框都是灰色的,不可选择。见截图imgur.com/a/W8nGJ4i 我无法设置约束的原因是分段控件放置在导航栏上。谢谢 如我所见,您将它放在导航项中。尝试将其放在主视图中。 当应用程序第一次启动时,我得到的结果如上图所示。但是,当应用程序在后台运行,然后在前台运行时,标签上的文本看起来很糟糕。基本上,当应用程序进入前台时,我调用updateUI()
,它调用getNextDays()
,它又调用segmentedControl.setTitle(self.stringDates[value], forSegmentAt: value)
,这又是它出错的地方。你在模拟器中运行过一个简单的项目吗?
是的,我做到了。我认为问题在于自动布局与 tableView 或 safeArea 冲突。尝试使用没有 tableView 的分段控制器实现 clear ViewController。以上是关于如何在 Swift 的分段控件中调整 textLabel 的大小?的主要内容,如果未能解决你的问题,请参考以下文章
在 Swift 的标头中使用分段控件更改 UICollectionView 的内容
Swift 自定义分段控件 SegmentedControl