【问题标题】:Resize table header when using dynamic types使用动态类型时调整表头大小
【发布时间】:2017-07-20 23:54:31
【问题描述】:

我有一个带有标题的TableViewController。 此标头是一个容器,它链接到另一个名为 Header.storyboard 的故事板

Header.storyboard 包含一个带有一些标签的堆栈视图,这些标签是动态类型的。

标签文本来自数据库。

不考虑文本尺寸或大小,我想正确地对其进行可视化。

我已经使用 SO 的一些答案来正确调整标题的大小,但没有运气:

import UIKit

class TableViewController: UITableViewController {

    @IBOutlet weak var tableHeaderView: UIView!

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

        // Dynamic sizing for the header view
        if let headerView = tableHeaderView {
            headerView.setNeedsLayout()
            headerView.layoutIfNeeded()

            let height = headerView.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height
            var headerFrame = headerView.frame

            // If we don't have this check, viewDidLayoutSubviews() will get
            // repeatedly, causing the app to hang.
            if height != headerFrame.size.height {
                headerFrame.size.height = height
                headerView.frame = headerFrame
                tableHeaderView = headerView
           }
       }
   }
}

【问题讨论】:

  • 你试过在 UITableViewDelegate 中的 func tableView(UITableView, heightForHeaderInSection: Int) 吗?
  • 您的意思是它使用动态类型作为 Apple 技术(例如 UIFontTextStyle)还是您的意思是它们只是具有不同的字体大小?
  • @Alistra,我的意思是 Apple 定义的动态类型——storyboard 中使用的 UIFontTextStyle。当应用程序运行时,我想更改可访问性的字体,并且我想相应更改 tableHeader 的高度,以便文本可见
  • 你有没有试过听标题上的UIContentSizeCategoryDidChangeNotificationinvalidateIntrinsicContentSize
  • 从这个useyourloaf.com/blog/auto-adjusting-fonts-for-dynamic-type了解到“将adjustsFontsForContentSizeCategory设置为true会导致字体在用户更改文本内容大小时自动更新。您不再需要观察内容大小类别确实更改通知。”。我不知道在哪里打电话invalidateIntrinsicContentSize

标签: swift xcode uitableview storyboard


【解决方案1】:

对于 Xcode 11、iOS 13 - 我只需在 Interface Builder 中勾选这两个框:

【讨论】:

  • sectionView 的标头与 tableView 中的 tableHeaderView 属性不同
【解决方案2】:

首先,你应该给标签一个高度,而不是给视图一个高度

class ViewController : UITableViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 40
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 4
}

override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

    cell.backgroundColor = UIColor.yellow
    cell.textLabel?.text = "Baran"

    return cell

}

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
{
    return heightForView()
}

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let headerView : UIView = UIView(frame: CGRect(x: 0, y: 20, width: self.view.frame.width, height: self.heightForView()))
    headerView.backgroundColor = UIColor.black

    let label : UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.heightForView()))
    label.numberOfLines = 0
    label.textAlignment = NSTextAlignment.center
    label.text = "Size To Fit Tutorial"
    label.font = UIFont(name: "Helvetica", size: 50)
    label.textColor = UIColor.white
    headerView.addSubview(label)

    return headerView
}

//Self Sizing height ....
func heightForLabel(text:String, font:UIFont, width:CGFloat) -> CGFloat{
    let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude))
    label.numberOfLines = 0
    label.lineBreakMode = NSLineBreakMode.byCharWrapping
    label.font = font
    label.text = text
    label.sizeToFit()
    return label.frame.height
}

func heightForView() -> CGFloat{

    let screenSize = UIScreen.main.bounds
    let screenWidth = screenSize.width

    let text = "Size To Fit Tutorial"
    let font : UIFont!
    switch UIDevice.current.userInterfaceIdiom {
    case .pad:
        font = UIFont(name: "Helvetica", size: 35)
    case .phone:
        font = UIFont(name: "Helvetica", size: 50)
    default:
        font = UIFont(name: "Helvetica", size: 24)
    }
    let height = heightForLabel(text: text, font: font, width: screenWidth)

    return height
}
}

希望对您有所帮助

【讨论】:

  • 这不是我想要的。我想退出应用程序,并从设置中更改字体,并且我需要自动调整标题的大小,以便在使用更大的字体时,这应该是可见的。另外,我不能像您建议的那样对代码进行太多更改,因为我处理的是遗留代码。另外,我的标题在一个容器内,由于那里的逻辑很大,我不想更改它。感谢您的提问和回答
【解决方案3】:

表格视图标题可以自动调整大小

但对于容器,它可能无法正常工作

使用自定义视图代替 viewForHeaderInSection

class ViewController: UITableViewController {
    override func viewDidLoad() {
        tableView.estimatedSectionHeaderHeight = 10
        tableView.sectionHeaderHeight = UITableViewAutomaticDimension
    }
    override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let lab = UILabel()
        lab.text = "text \(section)"
        lab.font = UIFont.systemFont(ofSize: 10 * CGFloat(section) + 1)
        return lab
    }
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 5
    }
    //this method overriding is not necessary
    override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return UITableViewAutomaticDimension
    }
}

【讨论】:

  • 我无法删除容器,因为它是旧代码。
  • 我的代码中的 viewDidLayoutSubviews 实际上会自动调整容器的大小,但它似乎并不关心字体是否已更改。
  • autoLayout autoheigh 在容器、嵌入式视图控制器和其他类似的东西上效果不佳。我看到的唯一方法:通过 systemLayoutSizeFitting 以编程方式计算高度并通过 heightForHeaderInSection
  • systemLayoutSizeFitting,不关心字体大小。它总是给我相同的尺寸。
  • 你可以尝试获取实际大小的视图,在它呈现在屏幕上之后,然后用 heightForHeaderInSection 设置它的高度
【解决方案4】:

尝试实施

tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) 

tableView(_ tableView: UITableView, viewForHeaderInSection section: Int)
你的代码应该是这样的:

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return tableHeaderView.bounds.size.height
}

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    return tableHeaderView
}

【讨论】:

  • 不,它不起作用。 :( 我想要的是当字体从可访问性更改时自动调整标题的大小。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-29
  • 1970-01-01
  • 2021-04-06
  • 1970-01-01
  • 1970-01-01
  • 2012-01-06
  • 1970-01-01
相关资源
最近更新 更多