为什么 UI 段控制中的字体会自动恢复为系统字体?

Why are fonts in UI segment control reverting to system fonts automatically?

我在一个 iOS 应用程序中有几个 UI 段控件,用 swift 编写。

在 iOS 设备上进行模拟时,在初始加载时,他们使用代码中设置的正确自定义字体,但在某些情况下,当我转到其他视图并返回时,段控制选项卡中的字体似乎自动恢复为系统字体。

是什么导致了这个问题?

我正在每个视图控制器中使用此功能创建我所有的分段控件。这是设置自定义字体的地方。

    override func viewDidLoad() {
    super.viewDidLoad()
    isHirer = AppSettings.boolValue(.isHirer)
    setupUI()
    setupSegmentControl()
    downloadData()
    configureLocationManager()
    
}



    func setupSegmentControl() {
    var items = [String]()
    
    items = AppSettings.boolValue(.isHirer) ? ["Posts", "Manage"] : ["Search", "Manage"]
    
    let segmentedControl = UISegmentedControl(items: items)
    segmentedControl.selectedSegmentIndex = 0
    UISegmentedControl.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor:UIColor.init(displayP3Red: 0/255, green: 0/255, blue: 0/255, alpha: 1), NSAttributedString.Key.font : UIFont.init(name: "Cabin-SemiBold", size: 16)!], for: .selected)
    UISegmentedControl.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor:UIColor.init(displayP3Red: 138/255, green: 145/255, blue: 172/255, alpha: 0.7), NSAttributedString.Key.font : UIFont.init(name: "Cabin-SemiBold", size: 16)!], for: .normal)
    segmentedControl.frame = CGRect.init(x: 0, y: 42, width: tableView.frame.width/2-20, height: 48)
    
    
    if AppSettings.boolValue(.isHirer) {
        segmentedControl.setContentOffset(CGSize(width: 0, height: -5), forSegmentAt: 0)
        segmentedControl.setContentOffset(CGSize(width: 0, height: -5), forSegmentAt: 1)
    } else {
        segmentedControl.setContentOffset(CGSize(width: 5, height: -5), forSegmentAt: 0)
        segmentedControl.setContentOffset(CGSize(width: 0, height: -5), forSegmentAt: 1)
    }

    
    segmentedControl.setBackgroundImage(backgroundWithColor(color: .backgroundGray, frame: CGRect(x: 0, y: 0, width: segmentedControl.frame.width, height: segmentedControl.frame.height)), for: .normal, barMetrics: .default)
    segmentedControl.setDividerImage(imageWithColor(color: UIColor.white), forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
    segmentedControl.addTarget(self, action: #selector(showSection), for: .valueChanged)
    seg = segmentedControl
}

@objc func showSection(sender: UISegmentedControl) {
    switch sender.selectedSegmentIndex {
    case 0:
        isSegment0 = true
        tableView.reloadData()
    case 1:
        isSegment0 = false
        tableView.reloadData()
    default:
        break
    }
}

然后在 table 视图的 ViewForHeaderInSection 函数中将段添加到 header 视图。

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    
    if section == 0 && AppSettings.boolValue(.isHirer) || section == 0 && !AppSettings.boolValue(.isHirer) {
        let headerView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.width, height: 90))
        headerView.backgroundColor = .backgroundGray
   

        
        let segmentControl = seg
        segmentControl.tag = section

        headerView.addSubview(segmentControl)

        return headerView

请尝试修改您的代码如下:

之前:

UISegmentedControl.appearance().setTitleTextAttributes(...)

之后:

segmentedControl.setTitleTextAttributes(...)

即不要在 UISegmentedControl class

上使用外观代理

外观代理通常会在应用程序生命周期的早期 class 的任何控件实例化之前完成一次。例如,您可以改为在 AppDelegates didFinishLaunching() API 中使用外观代理,这将取代在代码中其他地方调用 setTitleTextAttributes() 的需要。

如果有帮助,请反馈。