前言:在玩知乎的時候,老是一不當心搖動了下手機就彈出了一個反饋窗口(好吧,這並非一個良好的用戶體驗),思考了一下它是怎麼實現的,原本覺得搖一搖這個功能比較複雜,沒想到動手實現了一下發現,蘋果已經徹底的封裝好了,只須要簡單的實現它的代理方法便可。 先上效果圖 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裏了。複製代碼