在 iOS 中模拟提醒应用“添加”页脚
Posted
技术标签:
【中文标题】在 iOS 中模拟提醒应用“添加”页脚【英文标题】:Emulating the Reminders App "Add" Footer in iOS 【发布时间】:2017-02-03 13:48:40 【问题描述】:我可以使用一些指针来尝试创建类似于 iPhone 上的提醒应用程序的“添加”页脚,无论是通过 Interface Builder 和/或代码。
更具体地说,我有一个数据列表,并希望有一个始终可用的可编辑“添加”行,如下所示:
当列表底部可见时,您会在底部看到“添加” 当不可见时,“添加”行浮动并在视图底部保持可见/可访问 显示键盘时,“添加”行位于键盘正上方到目前为止,我已经尝试使用表格视图控制器并将 EditFieldView 放在表格页脚中。这需要照顾一个功能。但是如果不编写代码,我不确定从那里去哪里。我对 ios UI 还是有点陌生,希望避免重新发明已经存在的功能。
【问题讨论】:
Reminders 正在使用键盘附件在键盘上方显示“添加”按钮。它很可能会监听键盘通知并隐藏并显示表格页脚。你也可以让你的桌子用键盘调整它的框架,所以如果它实际上是一个页脚,那么你的页脚也会向上移动。没什么特别的。 【参考方案1】:使您的视图位于键盘上方但在键盘不可见时仍位于表格底部的示例。
我添加了一个红色的 UIView。当您点击它时,键盘将显示,您可以看到它动画到键盘上方的位置。当您点击单元格本身时,您可以看到键盘关闭并且视图移回表格底部。
还有其他方法可以做到这一点,例如使用键盘附件视图和附加到底部的视图。不过,我不会深入。
使用键盘通知的示例:
//
// ViewController.swift
// SO
//
// Created by Brandon T on 2017-02-03.
// Copyright © 2017 XIO. All rights reserved.
//
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate
var table: UITableView!
var tableFooter: UIView!
var bottomConstraint: NSLayoutConstraint!
var dummyTextField: UITextField?
deinit
NotificationCenter.default.removeObserver(self)
override func viewDidLoad()
super.viewDidLoad()
//Notifications
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name:NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name:NSNotification.Name.UIKeyboardWillHide, object: nil)
//Setup Views
self.table = UITableView(frame: self.view.frame, style: .grouped)
self.table.delegate = self
self.table.dataSource = self
self.tableFooter = UIView()
self.tableFooter.backgroundColor = UIColor.red
let recognizer = UITapGestureRecognizer(target: self, action: #selector(onViewTap(recognizer:)))
recognizer.numberOfTapsRequired = 1
recognizer.numberOfTouchesRequired = 1
self.tableFooter.addGestureRecognizer(recognizer)
//Constraints
self.view.addSubview(self.table)
self.view.addSubview(self.tableFooter)
self.table.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
self.table.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true
self.table.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
self.tableFooter.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
self.tableFooter.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true
self.tableFooter.topAnchor.constraint(equalTo: self.table.bottomAnchor).isActive = true
self.tableFooter.heightAnchor.constraint(equalToConstant: 50.0).isActive = true
self.bottomConstraint = self.tableFooter.bottomAnchor.constraint(equalTo: self.view.bottomAnchor)
self.bottomConstraint.isActive = true
self.table.translatesAutoresizingMaskIntoConstraints = false
self.tableFooter.translatesAutoresizingMaskIntoConstraints = false
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
func keyboardWillShow(notification: Notification)
if let userInfo = notification.userInfo
let endFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
let duration:TimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber
let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIViewAnimationOptions.curveEaseInOut.rawValue
let animationCurve:UIViewAnimationOptions = UIViewAnimationOptions(rawValue: animationCurveRaw)
self.view.layoutIfNeeded()
UIView.animate(withDuration: duration, delay: TimeInterval(0), options: animationCurve, animations:
if (self.bottomConstraint.constant <= 0.0)
self.bottomConstraint.constant = -endFrame!.size.height
self.view.layoutIfNeeded()
, completion: (finished) in
)
func keyboardWillHide(notification: Notification)
if let userInfo = notification.userInfo
let endFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
let duration:TimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber
let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIViewAnimationOptions.curveEaseInOut.rawValue
let animationCurve:UIViewAnimationOptions = UIViewAnimationOptions(rawValue: animationCurveRaw)
self.view.layoutIfNeeded()
UIView.animate(withDuration: duration, delay: TimeInterval(0), options: animationCurve, animations:
self.bottomConstraint.constant = 0.0
self.view.layoutIfNeeded()
, completion: (finished) in
)
//TableView
func numberOfSections(in tableView: UITableView) -> Int
return 1
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return 10
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
return 100.0
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
return 0.00001
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat
return 0.00001
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
var cell = tableView.dequeueReusableCell(withIdentifier: "cellID")
if (cell == nil)
cell = UITableViewCell(style: .default, reuseIdentifier: "cellID")
cell!.selectionStyle = .none
self.dummyTextField = UITextField(frame: CGRect(x: 100, y: 25.0, width: 100, height: 50))
cell!.contentView.addSubview(self.dummyTextField!)
cell!.backgroundColor = UIColor.white
cell!.textLabel?.text = "Test - \(indexPath.row)"
return cell!
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
self.dummyTextField!.resignFirstResponder()
self.dummyTextField!.endEditing(true)
self.view.resignFirstResponder()
self.view.endEditing(true)
func onViewTap(recognizer: UITapGestureRecognizer)
self.dummyTextField?.becomeFirstResponder()
【讨论】:
感谢您为我指明了正确的方向。我正在更彻底地研究附件视图。以上是关于在 iOS 中模拟提醒应用“添加”页脚的主要内容,如果未能解决你的问题,请参考以下文章