前言:在玩知乎的时候,老是一不当心摇动了下手机就弹出了一个反馈窗口(好吧,这并非一个良好的用户体验),思考了一下它是怎么实现的,原本觉得摇一摇这个功能比较复杂,没想到动手实现了一下发现,苹果已经彻底的封装好了,只须要简单的实现它的代理方法便可。 先上效果图 git
这个弹出框的实现也很是简单,须要注意的几个点,适配弹出框的高度,因为顶部Label和下面TableView的高度是不固定的,因此咱们须要注意适配弹出框的高度,这里我用SnapKit作布局,将tableView的底部和容器View的底部对齐,再让容器View的高度大于等于某个值,这样系统能够根据tableView的高度来自适应容器View的高度。下面咱们看看代码具体是怎么实现的:github
首先定义一个协议FSCAlertViewDelegate,里面含有一个方法alertViewSlectedAction,作为点击tableView中某一项的回调ide
protocol FSCAlertViewDelegate { func alertViewSlectedAction(row: Int) }布局
声明弹出框所需的UI和数据源:spa
//背景容器
var backgroundView: UIView!
//标题Label
var titleLabel: UILabel!
//标题
var title:
//详情Label
var messageLabel: UILabel!
//详情
var message: String
//表格View
var tableView: UITableView!
//表格数据源
var labelStrings: [String]
//点击按钮回调
var delegate: FSCAlertViewDelegate?
//初始化相关的控件
//注意为了让弹出框的高度能够自适应,弹出框的高度不能够写死,让他大于等于某个高度便可
func initView() {
self.backgroundColor = UIColor.lightGray
self.alpha = 1
backgroundView = UIView(frame: CGRect.zero)
backgroundView.backgroundColor = UIColor.white
backgroundView.layer.cornerRadius = 20
backgroundView.clipsToBounds = true
addSubview(backgroundView)
backgroundView.snp.makeConstraints { (make) in
make.center.equalToSuperview()
make.width.equalTo(screenWidth - 80)
make.height.greaterThanOrEqualTo(0)
}
titleLabel = UILabel(frame: CGRect.zero)
titleLabel.text = title
titleLabel.textAlignment = .center
titleLabel.font = UIFont.systemFont(ofSize: 22)
titleLabel.textColor = UIColor.black
titleLabel.numberOfLines = 0
backgroundView.addSubview(titleLabel)
titleLabel.snp.makeConstraints { (make) in
make.left.equalTo(16)
make.right.equalTo(-16)
make.top.equalTo(16)
make.height.greaterThanOrEqualTo(20)
}
messageLabel = UILabel(frame: CGRect.zero)
messageLabel.text = message
messageLabel.textAlignment = .center
messageLabel.font = UIFont.systemFont(ofSize: 17)
messageLabel.textColor = UIColor.darkGray
messageLabel.numberOfLines = 0
backgroundView.addSubview(messageLabel)
messageLabel.snp.makeConstraints { (make) in
make.top.equalTo(titleLabel.snp.bottom).offset(8)
make.left.equalTo(16)
make.right.equalTo(-16)
make.height.greaterThanOrEqualTo(20)
}
tableView = UITableView(frame: CGRect.zero)
tableView.dataSource = self
tableView.delegate = self
backgroundView.addSubview(tableView)
tableView.snp.makeConstraints { (make) in
make.left.equalTo(0)
make.right.equalTo(0)
make.top.equalTo(messageLabel.snp.bottom).offset(10)
make.height.equalTo(50*labelStrings.count)
make.bottom.equalToSuperview()
}
}
//后面是tableView相关的数据源和代理
//MARK: - TableViewDataSource and Delegate
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return labelStrings.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
cell.textLabel?.text = labelStrings[indexPath.row]
cell.textLabel?.textAlignment = .center
cell.textLabel?.textColor = UIColor.blue
cell.textLabel?.font = UIFont.systemFont(ofSize: 20)
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 50
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
delegate?.alertViewSlectedAction(row: indexPath.row)
self.removeFromSuperview()
}
//实现摇一摇的功能也简单,首先让你的类实现AVAudioPlayerDelegate协议,代理有相关方法motionEnded,在代理方法中,弹出提示框便可
override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
fscAlertView = FSCAlertView(frame: self.view.bounds, title: "请问须要反馈什么问题?", message: "你也能够在我的页的反馈帮助中心找到这个功能", labelStrings: ["帮助中心","遇到异常","意见反馈","参与Beta版本","关闭摇一摇","没啥事"])
fscAlertView.delegate = self
self.view.addSubview(fscAlertView)
}
附上项目连接:https://github.com/sichangfeng/FSCAlertView.git,项目下载便可用,通常在项目里摇一摇事件应该是全局监控的,相关的方法应该在AppDelegate中实现,能够获取UIWindow下的view,再弹出提示框。项目实例代码为了方便,我就写在ViewController里了。复制代码