选择行

时间:2019-01-24 13:19:07

标签: ios swift uitableview fonts accessibility

当我选择一行时,我在UITableView中的节标题更改大小时遇到​​问题,这使表节在您点击一行时跳来跳去。

该应用程序使用具有动态大小的自定义字体。我用

设置字体
UIFontMetrics(forTextStyle: <textStyle>).scaledFont(for: <font>, maximumPointSize: <maximumPointSize>)

我可以使用默认设置解决此问题,但是该问题会以较大的辅助功能字体大小返回。

该表分为两部分。本节标题使用标准组件。第一部分(通常包含三个单元格)使用标准的UITableViewCell。第二部分有一个自定义单元格,在选中该单元格时会在第二个自定义单元格中插入一个选择器(参见开始时间单元格在iOS日历应用中打开日期选择器的方式)。使用带有insertRows的beginUpdates / endUpdates块插入多余的单元格。

发生了什么:第一次渲染表时,标题的contentView比带有标题的UILabel大得多。如果我点击第2部分中打开第二个单元格的单元格,则标题contentView的大小将减小以匹配标签的大小。除非我在第一部分中选择一个单元格,否则它将保持这种方式。到那时,标题将再次调整大小,现在contentSize小于原始大小,但大于最小大小。

这是我尝试过的:

我最初使用

指定表标题的字体大小
UILabel.appearance(whenContainedInInstancesOf: [UITableViewHeaderFooterView.self])
AppDelegate中的

,这是我处理其他类型的组件的地方。但是,似乎UITableView在重新加载表数据时不会系统地观察到这一点,即字体大小本身在表重新加载期间会改变(而不仅仅是contentView的大小)。

我更改了代码,改为在willDisplayHeaderView中指定字体大小,即类似以下内容:

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {

        if let header = view as? UITableViewHeaderFooterView {
            if let textlabel = header.textLabel {
                textlabel.font = UIFontMetrics(forTextStyle: .body).scaledFont(for:Theme.font, maximumPointSize: 30)
            }
            if section == 0 {
              header.accessibilityLabel = ...
              header.accessibilityHint = ...
            } else {
              header.accessibilityLabel = ... 
              header.accessibilityHint = ... 
            }

这消除了重新绘制表格时字体大小改变的问题。它还消除了标题的contentView大小更改为默认字体大小的问题。但是一旦在辅助功能设置中切换了字体大小,就会出现标题contentView大小更改问题。

我试图设置sectionHeaderHeight(“设置”是UITableView)

self.settings.sectionHeaderHeight = UITableView.automaticDimension
self.settings.estimatedSectionHeaderHeight = 60

这也没有区别。

如果我要猜测的话,标题有时会根据显示更大的UILabel来调整自身大小,但是为什么大小取决于表的重绘方式呢?

我猜下一步是用自定义视图替换表标题,但这似乎有些过头。

我想念什么?

1 个答案:

答案 0 :(得分:0)

不添加自定义标头就无法使其正常工作,所以这就是我所采用的解决方案。自定义标头使用了一种难看的解决方法来控制标头的高度。

我的原始实现具有以下组合:

   Document root = new Document();
    Document rootMenu = new Document();
    ArrayList rootMenuItems = new ArrayList();
    Document rootMenuItems0 = new Document();
    ArrayList rootMenuItems0Sub_items = new ArrayList();
    Document rootMenuItems0Sub_items0 = new Document();
    Document rootMenuItems0Sub_items1 = new Document();
    Document rootMenuItems1 = new Document();
    ArrayList rootMenuItems1Sub_items = new ArrayList();
    Document rootMenuItems1Sub_items0 = new Document();
    Document rootMenuItems2 = new Document();
    ArrayList rootMenuItems2Sub_items = new ArrayList();
    Document rootMenuItems2Sub_items0 = new Document();
    Document rootMenuItems2Sub_items1 = new Document();

    rootMenuItems0.append("id", 1);

    rootMenuItems0.append("code", "hot1_sub1_mnu");

    rootMenuItems0.append("name", "Mutton");

    rootMenuItems0.append("status", "1");

    rootMenuItems0Sub_items0.append("id", "01");

    rootMenuItems0Sub_items0.append("name", "Mutton Pepper Fry");

    rootMenuItems0Sub_items0.append("price", "100");

    rootMenuItems0Sub_items1.append("id", "02");

    rootMenuItems0Sub_items1.append("name", "Mutton Curry");

    rootMenuItems0Sub_items1.append("price", "100");

    rootMenuItems1.append("id", "2");

    rootMenuItems1.append("code", "hot1_sub2_mnu");

    rootMenuItems1.append("name", "Sea Food");

    rootMenuItems1.append("status", "1");

    rootMenuItems1Sub_items0.append("id", "01");

    rootMenuItems1Sub_items0.append("name", "Fish Fry");

    rootMenuItems1Sub_items0.append("price", "150");

    rootMenuItems2.append("id", "3");

    rootMenuItems2.append("code", "hot1_sub3_mnu");

    rootMenuItems2.append("name", "Noodles");

    rootMenuItems2.append("status", "1");

    rootMenuItems2Sub_items0.append("id", "01");

    rootMenuItems2Sub_items0.append("name", "Chicken Noodles");

    rootMenuItems2Sub_items0.append("price", "70");

    rootMenuItems2Sub_items1.append("id", "02");

    rootMenuItems2Sub_items1.append("name", "Egg Noodles");

    rootMenuItems2Sub_items1.append("price", "60");

    if (!rootMenuItems.isEmpty()) {
        rootMenu.append("items", rootMenuItems);
    }
    if (!rootMenuItems0Sub_items.isEmpty()) {
        rootMenuItems0.append("sub_items", rootMenuItems0Sub_items);
    }
    if (!rootMenuItems0Sub_items0.isEmpty()) {
        rootMenuItems0Sub_items.add(rootMenuItems0Sub_items0);
    }
    if (!rootMenuItems0Sub_items.isEmpty()) {
        rootMenuItems0.append("sub_items", rootMenuItems0Sub_items);
    }
    if (!rootMenuItems0Sub_items1.isEmpty()) {
        rootMenuItems0Sub_items.add(rootMenuItems0Sub_items1);
    }
    if (!rootMenuItems0Sub_items.isEmpty()) {
        rootMenuItems0.append("sub_items", rootMenuItems0Sub_items);
    }
    if (!rootMenuItems0.isEmpty()) {
        rootMenuItems.add(rootMenuItems0);
    }
    if (!rootMenuItems.isEmpty()) {
        rootMenu.append("items", rootMenuItems);
    }
    if (!rootMenuItems1Sub_items.isEmpty()) {
        rootMenuItems1.append("sub_items", rootMenuItems1Sub_items);
    }
    if (!rootMenuItems1Sub_items0.isEmpty()) {
        rootMenuItems1Sub_items.add(rootMenuItems1Sub_items0);
    }
    if (!rootMenuItems1Sub_items.isEmpty()) {
        rootMenuItems1.append("sub_items", rootMenuItems1Sub_items);
    }
    if (!rootMenuItems1.isEmpty()) {
        rootMenuItems.add(rootMenuItems1);
    }
    if (!rootMenuItems.isEmpty()) {
        rootMenu.append("items", rootMenuItems);
    }
    if (!rootMenuItems2Sub_items.isEmpty()) {
        rootMenuItems2.append("sub_items", rootMenuItems2Sub_items);
    }
    if (!rootMenuItems2Sub_items0.isEmpty()) {
        rootMenuItems2Sub_items.add(rootMenuItems2Sub_items0);
    }
    if (!rootMenuItems2Sub_items.isEmpty()) {
        rootMenuItems2.append("sub_items", rootMenuItems2Sub_items);
    }
    if (!rootMenuItems2Sub_items1.isEmpty()) {
        rootMenuItems2Sub_items.add(rootMenuItems2Sub_items1);
    }
    if (!rootMenuItems2Sub_items.isEmpty()) {
        rootMenuItems2.append("sub_items", rootMenuItems2Sub_items);
    }
    if (!rootMenuItems2.isEmpty()) {
        rootMenuItems.add(rootMenuItems2);
    }
    if (!rootMenuItems.isEmpty()) {
        rootMenu.append("items", rootMenuItems);
    }
    if (!rootMenu.isEmpty()) {
        root.append("menu", rootMenu);
    }

    System.out.println(root.toJson());

这是解决方法。

  1. 注册自定义标题
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        if section == 0 {
            return "One"
        } else if section == 1 {
            return "Two"
        } else {
            // Should not happen
            return "Other"
        }
    }

    func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {

        if let header = view as? UITableViewHeaderFooterView, let textlabel = header.textLabel {
            textlabel.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: ..., maximumPointSize: 23)
        }   
    }
  1. “自定义”标题带有不可见的标签,用于控制大小
<UITableView>.register(TableHeaderView.self, forHeaderFooterViewReuseIdentifier: "Header")
  1. 使用viewForHeaderInSection加载自定义标头
class TableHeaderView: UITableViewHeaderFooterView {

    // Dummy invisible label that controls the size of the header
    let label = UILabel()

    override init(reuseIdentifier: String?) {
        super.init(reuseIdentifier: reuseIdentifier)

        self.label.text = "M"
        self.label.textColor = UIColor.white.withAlphaComponent(0)

        // Make sure VoiceOver doesn't see it
        self.label.isAccessibilityElement = false

        // Set the font 
        self.label.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: ..., maximumPointSize: 23)
        self.label.translatesAutoresizingMaskIntoConstraints = false
        self.contentView.addSubview(self.label)

        let size = self.label.sizeThatFits(CGSize.zero)

        NSLayoutConstraint.activate([
            self.contentView.heightAnchor.constraint(equalToConstant: size.height + 20),
            self.label.centerYAnchor.constraint(equalTo: self.contentView.centerYAnchor, constant: 20),
            self.label.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: 12.0)])

        self.label.text = " "
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}