让 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 故事板结构和约束
所以我不得不稍微调整它,但通过执行以下操作让它工作:
- 将 UIButton 拉出到视图继承中的同一级别
表格视图。
- 在视图中嵌入表格视图和按钮
- 将上面的视图嵌入到另一个视图中
- 将视图 #3(固定视图)的边缘固定到超级视图
- 将视图 #2(调整视图大小)的顶部、左侧和右侧边缘固定到视图 #3 边缘。并设置一个等高的约束以查看 #3。
- 在视图控制器中为等高约束设置一个出口
IB 中的视图继承应如下所示:
现在在视图控制器代码中,您需要做以下事情:
为键盘偏移值创建实例变量
var keyboardOffset: CGFloat = 0
为键盘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)
在keyboardWillShow中,缓存键盘高度值。
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
keyboardOffset = keyboardSize.height
}
在 keyboardOffset 变量上创建 didSet 方法,并在每次设置视图高度时根据该值设置动画高度
var keyboardOffset: CGFloat = 0 {
didSet {
resizingViewHeight.constant = -keyboardOffset
UIView.animate(withDuration: 0.2) {
self.view.layoutIfNeeded()
}
}
}
确保在 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 中有三个不同的设置函数。
- 用于设置标准 table 视图单元格 ->
.setDefault(text: text)
- 用于设置我的清理缓存按钮 ->
.setCache(text: text)
- 推送版本信息的最后一个 ->
.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())
}
}
我有一个由原型单元格组成的 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 故事板结构和约束
所以我不得不稍微调整它,但通过执行以下操作让它工作:
- 将 UIButton 拉出到视图继承中的同一级别 表格视图。
- 在视图中嵌入表格视图和按钮
- 将上面的视图嵌入到另一个视图中
- 将视图 #3(固定视图)的边缘固定到超级视图
- 将视图 #2(调整视图大小)的顶部、左侧和右侧边缘固定到视图 #3 边缘。并设置一个等高的约束以查看 #3。
- 在视图控制器中为等高约束设置一个出口
IB 中的视图继承应如下所示:
现在在视图控制器代码中,您需要做以下事情:
为键盘偏移值创建实例变量
var keyboardOffset: CGFloat = 0
为键盘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)
在keyboardWillShow中,缓存键盘高度值。
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue { keyboardOffset = keyboardSize.height }
在 keyboardOffset 变量上创建 didSet 方法,并在每次设置视图高度时根据该值设置动画高度
var keyboardOffset: CGFloat = 0 { didSet { resizingViewHeight.constant = -keyboardOffset UIView.animate(withDuration: 0.2) { self.view.layoutIfNeeded() } } }
确保在 keyboardWillHide
中将偏移量设置回 0keyboardOffset = 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 中有三个不同的设置函数。
- 用于设置标准 table 视图单元格 ->
.setDefault(text: text)
- 用于设置我的清理缓存按钮 ->
.setCache(text: text)
- 推送版本信息的最后一个 ->
.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())
}
}