Swift Label.sizeToFit() 大小适应问题

当设置UILabel的sizeToFit()方法后,若字数过多仍然显示省略号,可能是因为初始宽度不够。通过放宽初始化时的frame宽度或约束宽度,让系统重新计算尺寸,可以解决这个问题。sizeToFit()基于sizeThatFits()返回的最佳尺寸来调整大小,如果返回的尺寸不准确或未调整,则可能导致显示异常。适当增加初始宽度可触发正确的尺寸计算和调整。

参考链接:sizeToFit()使用心得_aaa1231722的博客-优快云博客

问题:

              Label.sizeToFit()

              Label.snp.makeConstraints { make in

                    make.width.equalTo(Label.frame.size.width)

                }

设置了 sizeToFit() 自适应宽度属性,字数过多时仍然显示 :字数...  点点点,可以适当放开宽度的初始值

解决:

 初始值放宽即可:如:

            1.    .init(frame: CGRect(x: 0, y: 0, width: 一个大点的值, height: 高度))

            2. Label.snp.makeConstraints { make in

                          make.width.equalTo(一个大点的值)                                   

                }

原因:

具体原因,文档里说明的很清楚了:

- (void)sizeToFit;                      

// calls sizeThatFits: with current view bounds and changes bounds size.

**调用sizeThatFits:使用当前视图边界并更改边界大小。

那么 sizeThatFits是啥?

- (CGSize)sizeThatFits:(CGSize)size;    

// return 'best' size to fit given size. does not actually resize view. Default is return existing view size

**返回“最佳”尺寸以适合给定尺寸。实际上不会调整视图的大小。默认值是返回现有视图大小

猜想,出现这种问题: sizeToFit()方法从sizeThatFits里面,得到了一个最佳尺寸,然后进行大小调整,没改变大小要不就是最佳尺寸计算的不对(需要宽100,结果返回了99),要不就是没有进行调整。反正是有个机制没有被触发,或者返回错误。

所以,你可以设置一个大一点的值,让系统知道这个值明显不适合,然后进行重新计算和调整。

完整点的代码: lazy var topTipsView: UIView = { let view = UIView() view.backgroundColor = UIColor.tpbTopToastBackground view.layer.cornerRadius = 8 view.layer.masksToBounds = true let button = UIButton() button.setImage(TPImageLiteral("common_close_white_forAdd"), for: .normal) button.addTarget(self, action: #selector(closeTips), for: .touchUpInside) view.addSubview(button) button.snp.makeConstraints({ make in make.trailing.equalToSuperview().offset(-12) make.height.width.equalTo(24) make.top.equalToSuperview().offset(4) }) let label = UILabel() label.text = LocalizedString(key: localDeviceVCTopTips) label.translatesAutoresizingMaskIntoConstraints = false label.numberOfLines = 0 label.font = .projectFont(ofSize: 12) label.textColor = .tpbTextWhite view.addSubview(label) label.snp.makeConstraints({ make in make.trailing.equalTo(button.snp.leading).offset(-8) make.leading.equalToSuperview().offset(16) make.top.equalToSuperview().offset(8) make.bottom.equalToSuperview().offset(-8) }) self.tipsViewHeight = Int(getLabelViewHeight(label: label, width: screenWidth - 80) + 16) view.translatesAutoresizingMaskIntoConstraints = false return view }() private var tipsViewHeight = 0 private var showTopTips = false { didSet { if showTopTips { self.topTipsView.isHidden = false tabBarContainerTopConstraint.constant = CGFloat(self.tipsViewHeight + 10) self.view.layoutIfNeeded() } else { self.topTipsView.isHidden = true tabBarContainerTopConstraint.constant = 0 self.view.layoutIfNeeded() } } }
11-21
我现在要继承自同一个组件库TPBSearchBar,按照上述那样的方式对我这里面的searchbar相关部分进行同样的处理, import UIKit import SnapKit class DeviceListNewViewController: SurveillanceCommonTableController { // MARK: - 属性 private lazy var titleView: UILabel = { let label = UILabel() label.text = "设备列表" label.font = .tpm20Medium() // 使用组件库字体规范 label.textColor = .tpbTextPrimary label.textAlignment = .center return label }() private lazy var searchBar: UISearchBar = { let bar = UISearchBar() bar.placeholder = LocalizedString(key: searchPlaceholder) bar.barTintColor = UIColor(white: 0.96, alpha: 1.0) bar.isTranslucent = false bar.searchBarStyle = .prominent bar.layer.cornerRadius = 22 bar.clipsToBounds = true bar.backgroundColor = .clear return bar }() private lazy var tabScrollView: UIScrollView = { let scrollView = UIScrollView() scrollView.showsHorizontalScrollIndicator = false scrollView.backgroundColor = .clear scrollView.translatesAutoresizingMaskIntoConstraints = false return scrollView }() private lazy var tabButtons: [UIButton] = { return tabButtonTitles.enumerated().map { index, title in let btn = UIButton(type: .custom) btn.tag = index btn.setTitle(title, for: .normal) btn.titleLabel?.font = UIFont.tpr14Regular() btn.setTitleColor(.blue, for: .normal) btn.setTitleColor(.tpbPrimary, for: .selected) btn.layer.borderWidth = 1 btn.layer.borderColor = UIColor(white: 0.85, alpha: 1.0).cgColor btn.layer.cornerRadius = 20 btn.contentEdgeInsets = UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16) btn.addTarget(self, action: #selector(onTabTapped(_:)), for: .touchUpInside) return btn } }() private let tabButtonTitles = ["所有设备","收藏页面","站点选择"] private var selectedTabIndex = 0 // MARK: - View override func tpbSetupSubviews() { super.tpbSetupSubviews() setupNav() view.addSubview(titleView) view.addSubview(searchBar) view.addSubview(tabScrollView) // 初始化 tab 按钮 updateTabSelection(index: selectedTabIndex) } private func setupNav() { // 使用组件库封装的方法创建左右按钮(更安全) navigationItem.leftBarButtonItem = tpbCreateLeftBarButtonItem( with: TPImageLiteral("icon_back"), andTarget: self, andAction: #selector(onBack) ) navigationItem.rightBarButtonItem = tpbCreateRightBarButtonItem( with: TPImageLiteral("icon_settings"), andTarget: self, andAction: #selector(onSettings) ) navigationItem.title = "" } override func tpbMakeConstraint() { super.tpbMakeConstraint() titleView.snp.makeConstraints { make in make.top.equalTo(view.safeAreaLayoutGuide).offset(8) make.centerX.equalToSuperview() } searchBar.snp.makeConstraints { make in make.top.equalTo(titleView.snp.bottom).offset(16) make.leading.trailing.equalToSuperview().inset(16) make.height.equalTo(44) } tabScrollView.snp.makeConstraints { make in make.top.equalTo(searchBar.snp.bottom).offset(16) make.leading.trailing.equalToSuperview().inset(0) make.height.equalTo(40) } // 布局 tab 按钮到 scrollview layoutTabButtonsInScrollView() } private func layoutTabButtonsInScrollView() { // 移除旧的 subviews 防止重复添加 tabScrollView.subviews.forEach { $0.removeFromSuperview() } var previousButton: UIButton? var totalWidth: CGFloat = 16 for (index, button) in tabButtons.enumerated() { tabScrollView.addSubview(button) button.snp.makeConstraints { make in make.centerY.equalToSuperview() make.height.equalTo(40) if let prev = previousButton { make.leading.equalTo(prev.snp.trailing).offset(8) } else { make.leading.equalTo(tabScrollView.contentLayoutGuide).offset(16) } make.width.greaterThanOrEqualTo(80) // 最小宽度 } // 异步测量以更新 contentSize DispatchQueue.main.async { totalWidth += button.intrinsicContentSize.width + (index > 0 ? 8 : 0) if index == self.tabButtons.count - 1 { self.tabScrollView.contentSize = CGSize(width: totalWidth + 16, height: 40) } } previousButton = button } } override func viewDidLoad() { super.viewDidLoad() searchBar.delegate = self reloadData() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) bindCollectionViewDelegates() } // MARK: - 数据模型构建 private func reloadData() { var tempSectionArray = [TPBTableSectionModel]() // Section 0: 内容区域 let section0 = TPBTableSectionModel() var cellModels = [TPBBaseTableCellModel]() // Cell 1: Tab ScrollView let tabCellModel = TPBBaseTableCellModel.customContent(with: tabScrollView) cellModels.append(tabCellModel) // Cell 2: 占位 Collection 内容区(后续替换为真实 UICollectionView) let collectionViewPlaceholder = UIView() collectionViewPlaceholder.backgroundColor = .tpbBackground collectionViewPlaceholder.layer.cornerRadius = 12 collectionViewPlaceholder.clipsToBounds = true // 立即配置其子视图(不需要延迟或闭包) setupMockCollectionView(in: collectionViewPlaceholder) // 使用 correct API: customContent(with:) let collectionCellModel = TPBBaseTableCellModel.customContent(with: collectionViewPlaceholder) collectionCellModel.height = TPBTableElementHeight.customHeight(240) // 设置固定高度 section0.cellModelArray = cellModels tempSectionArray.append(section0) sectionArray = tempSectionArray tableView.reloadData() } private func setupMockCollectionView(in container: UIView) { // 未来接入真正的 UICollectionView 或 Compositional Layout // 现在先加个子视图示意 let label = UILabel() label.text = "设备列表占位区域" label.textAlignment = .center label.textColor = .tpbTextSecondaryContent label.font = .tpr14Regular() label.sizeToFit() container.addSubview(label) label.snp.makeConstraints { make in make.center.equalToSuperview() } } // MARK: - 点击事件 @objc private func onBack() { navigationController?.popViewController(animated: true) } @objc private func onSettings() { print("Settings tapped") // TODO: 跳转设置页 } @objc private func onTabTapped(_ sender: UIButton) { guard sender.tag != selectedTabIndex else { return } tabButtons[selectedTabIndex].isSelected = false selectedTabIndex = sender.tag sender.isSelected = true notifyCollectionToUpdate(tabIndex: selectedTabIndex) } private func notifyCollectionToUpdate(tabIndex: Int) { print("Switched to tab: \(tabIndex)") // TODO: 根据 tabIndex 刷新 collectionView 数据 } private func bindCollectionViewDelegates() { // TODO: 绑定 UICollectionView 的 delegate & dataSource } private func updateTabSelection(index: Int) { for (i, btn) in tabButtons.enumerated() { btn.isSelected = (i == index) } } } // MARK: - UISearchBarDelegate extension DeviceListNewViewController: UISearchBarDelegate { func searchBarSearchButtonClicked(_ searchBar: UISearchBar) { searchBar.resignFirstResponder() } }
最新发布
12-02
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

app开发工程师V帅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值