swift實現仿知乎搖一搖彈出框

寫程式碼的少年發表於2019-03-20

前言:在玩知乎的時候,總是一不小心搖動了下手機就彈出了一個反饋視窗(好吧,這並不是一個良好的使用者體驗),思考了一下它是怎麼實現的,本來以為搖一搖這個功能比較複雜,沒想到動手實現了一下發現,蘋果已經完全的封裝好了,只需要簡單的實現它的代理方法即可。 先上效果圖

swift實現仿知乎搖一搖彈出框

這個彈出框的實現也非常簡單,需要注意的幾個點,適配彈出框的高度,由於頂部Label和下面TableView的高度是不固定的,所以我們需要注意適配彈出框的高度,這裡我用SnapKit做佈局,將tableView的底部和容器View的底部對齊,再讓容器View的高度大於等於某個值,這樣系統可以根據tableView的高度來自適應容器View的高度。下面我們看看程式碼具體是怎麼實現的:

首先定義一個協議FSCAlertViewDelegate,裡面含有一個方法alertViewSlectedAction,做為點選tableView中某一項的回撥

protocol FSCAlertViewDelegate { func alertViewSlectedAction(row: Int) }

宣告彈出框所需的UI和資料來源:

//背景容器
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裡了。複製程式碼

相關文章