让 UIButton 粘在 UITableView 的底部

Make UIButton stick on bottom of UITableView

我有一个由原型单元格组成的 UITableView。我想使用 Interface Builder 在 UITableView 的 底部放置一个 UIButton inside

我在 UITableView 的页脚中添加了 UIButton:

我为页脚视图添加了紫色背景,为 UITableView 添加了绿色背景。在上图中,它显示了页脚底部的按钮。但是,这不等于 UITableView 的底部。

下面的 GIF 显示按钮位于单元格下方,但不在 UITableView 的底部。我希望它显示在 UITableView 的底部 in。不在 UITableView 之下。下面的 GIF 显示了这个问题:

我的问题是:如何在 UITableView底部inside UITableView 中设置 UIButton 使用界面生成器?

这就是我想要实现的(来自 Apple 的 ResearchKit):

编辑:UIButton 应该在 UITableView 中。将 UIButton 放置在 TableView 外部并固定在下方的建议无法实现我的目标。

将包含 UIButton 的视图添加到 UITableView 所在的 UIViewController 底部。给它附加到超级视图的左侧、右侧和底部的约束,并且可能是一个固定的高度。

然后将 UITableView 的底部约束附加到包含 UIButton 的视图的顶部。

您应该会得到想要的效果。

注意:对于按钮,您可以在父视图约束中提供居中的 Y 和 X 以使其居中。

页脚始终出现在 table 视图的最后一个单元格之后,因此您的输出是正确的。

如果您想要 table 视图的按钮底部,请在层次结构中的 table 视图下方添加按钮,而不是作为页脚。但它使您的按钮成为静态的,这意味着您拥有多少单元格都没有关系,按钮始终是 tableView 的按钮,但它不像现在这样可滚动。

您正在设置页脚宽度 wrong.Set 它固定了高度,以便按钮固定在该特定高度(应该固定为 60px)

检查 Demo Code 故事板结构和约束

所以我不得不稍微调整它,但通过执行以下操作让它工作:

  1. 将 UIButton 拉出到视图继承中的同一级别 表格视图。
  2. 在视图中嵌入表格视图和按钮
  3. 将上面的视图嵌入到另一个视图中
  4. 将视图 #3(固定视图)的边缘固定到超级视图
  5. 将视图 #2(调整视图大小)的顶部、左侧和右侧边缘固定到视图 #3 边缘。并设置一个等高的约束以查看 #3。
  6. 在视图控制器中为等高约束设置一个出口

IB 中的视图继承应如下所示:

现在在视图控制器代码中,您需要做以下事情:

  1. 为键盘偏移值创建实例变量

    var keyboardOffset: CGFloat = 0
    
  2. 为键盘willShow和设置通知和观察者 将隐藏

    notificationCenter.addObserver(self, selector: #selector(keyboardWillShow(_:)), name:NSNotification.Name.UIKeyboardWillShow, object: nil)
    notificationCenter.addObserver(self, selector: #selector(keyboardWillHide(_:)), name:NSNotification.Name.UIKeyboardWillHide, object: nil)
    
  3. 在keyboardWillShow中,缓存键盘高度值。

    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
    
        keyboardOffset = keyboardSize.height
    }
    
  4. 在 keyboardOffset 变量上创建 didSet 方法,并在每次设置视图高度时根据该值设置动画高度

    var keyboardOffset: CGFloat = 0 {
        didSet {
            resizingViewHeight.constant = -keyboardOffset
    
            UIView.animate(withDuration: 0.2) { 
                self.view.layoutIfNeeded()
            }
        }
    }
    
  5. 确保在 keyboardWillHide

    中将偏移量设置回 0
    keyboardOffset = 0
    

现在每次出现键盘时,包含 tableview 的视图都会缩小,因此将内容拉上来,提供您正在寻找的缩小 tableview 效果!

我尝试了接受的答案,但无法正常工作。我发现页脚视图始终固定在屏幕底部,无论 TableView 的大小如何(就好像它是 TableView 的兄弟姐妹一样)。我最终遵循了此处建议的方法: 基本思想是您以编程方式确定 TableView 的高度,并根据结果显示 TableView 内部的页脚或显示同级视图TableView 的。

这个问题我有完美的解决方案。使用默认值在我的生活中从来没有那么有意义。

视图下方的按钮也是来自另一个部分的 table 视图单元格,但其 header 高度和内部设计的配置与上面的单元格不同。

所以我有五个不同的部分。其中前三个是标准 table 视图单元格 (SettingTableViewCell),但最后两个(缓存和版本)是自定义按钮。在 header 标题中,我为那些空标题初始化。

 enum Section: Int {
    case adjustSettings
    case about
    case agreements
    case cache
    case version
    
    static var numberOfSections: Int { return 5 }
    
    var reuseIdentifier: String { return "SettingTableCell" }
    
    var headerTitle: String? {
        switch self {
        case .adjustSettings: return "settings.adjust.section.title".localized
        case .about: return "settings.headertitle.about".localized
        case .agreements: return "agreement.title".localized
        case .cache: return ""
        case .version: return ""
        }
    }

然后我配置的单元格将在以下代码的哪个部分。缓存和版本只有一个单元格,这将是我们的按钮。

 var cells: [CellType] {
            switch self {
            case .adjustSettings:return [.notification,.language ]
            case .about: return [.rate, .contact, .invite]
            case .agreements: return [.membership, .kvkk, .illuminate]
            case .cache: return [.cache]
            case .version: return [.version]
            }
        }

我的 settingsTableViewCell 中有三个不同的设置函数。

  1. 用于设置标准 table 视图单元格 -> .setDefault(text: text)
  2. 用于设置我的清理缓存按钮 -> .setCache(text: text)
  3. 推送版本信息的最后一个 -> .setVersion(version: version)

使用上面的 cellForRowAt,我正在切换行并相应地设置它们。我的默认值是 .setDefault

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let section = Section(rawValue: indexPath.section) else {
            assertionFailure()
            return UITableViewCell()
        }
        let row = section.cells[indexPath.row]
        let cell = tableView.dequeueReusableCell(withIdentifier: section.reuseIdentifier) as! SettingTableCell
        switch row {
        case .version:
            cell.setVersion(version: getVersion())
        case .cache:
            ImageCache.default.calculateDiskCacheSize(completion: { size in
                if size == 0 {
                    cell.setCache(text: "settings.clear.data".localized)
                } else {
                    let byte = Int64(size)
                    let fileSizeWithUnit = ByteCountFormatter.string(fromByteCount: byte, countStyle: .file)
                    cell.setCache(text: "settings.cler.data.with.string".localized + "(\(String(describing: fileSizeWithUnit)))")
                }
            })
        default:
            cell.setDefault(text: row.text)
        }
        return cell
    }

您可以通过切换部分调整按钮高度,如下所示。

 func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    guard let section = Section(rawValue: indexPath.section) else { return 0 }
    switch section {
    case .cache: return 44
    case .version: return 44
    default: return 56.0
    }

您可以调整每个按钮之间的间距,如下所示。

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        guard let section = Section(rawValue: section) else { return 0 }
        switch section {
        case .adjustSettings: return 46
        case .about: return 46
        case .agreements: return 46
        case .cache: return 9
        case .version: return 0.5
        default: return 46
        }

最后,这是我的单元格,我在其中设置 .set 函数以根据需要自定义每个单元格。

class SettingTableCell: UITableViewCell {
@IBOutlet weak var line: UIView!
@IBOutlet weak var content: UIView!
@IBOutlet weak var arrowView: UIView!
@IBOutlet weak var labelSetting: UILabel!
override func awakeFromNib() {
    super.awakeFromNib()
    
}
func setVersion(version: String) {
    arrowView.isHidden = true
    line.isHidden = true
    content.backgroundColor = .clear
    labelSetting.label(textStr: version, textColor: KSColor.neutral400.getColor(), textFont: .sfProTextRegular(size: 13), fontSize: 13, lineSpacing: -0.13, paragraphStyle: NSMutableParagraphStyle())
    labelSetting.textAlignment = .center
    self.accessoryType = .none
}

func setCache(text: String) {
    arrowView.isHidden = true
    line.isHidden = true
    content.backgroundColor = KSColor.neutral100.getColor()
    labelSetting.label(textStr: text, textColor: KSColor.neutral700.getColor(), textFont: .sfProTextMedium(size: 14), fontSize: 14, lineSpacing: -0.14, paragraphStyle: NSMutableParagraphStyle())
    labelSetting.textAlignment = .center
    self.accessoryType = .none
}

func setDefault(text: String) {
    labelSetting.label(textStr: text, textColor: KSColor.neutral700.getColor(), textFont: UIFont.sfProTextMedium(size: 16), fontSize: 16, lineSpacing: -0.16, paragraphStyle: NSMutableParagraphStyle())
}

}

结果是我有 5 个部分,但最后两个是按钮。