Preface: When playing on zhihu, always inadvertently shaken down phone window will pop up a feedback (ok, this is not a good user experience), think about how it is done, thought shake this feature is more complex, have never thought to realize the discovery, apple has been completely sealed, only need a simple way to implement it agent. Let’s start with the renderings

Since the height of the top Label and the bottom TableView are not fixed, we need to pay attention to the height of the adaptation of the pop-up box. Here I use SnapKit for layout, align the bottom of the TableView with the bottom of the container View. And let the height of the container View be greater than or equal to some value, so that the system can adapt to the height of the container View based on the height of the tableView. Let’s see how the code is implemented:

First, define a protocol called FSCAlertViewDelegate, which contains a method called alertViewSlectedAction as a callback for clicking on an item in the tableView

protocol FSCAlertViewDelegate { func alertViewSlectedAction(row: Int) }

Declare the UI and data source needed for the popup:

Var backgroundView: UIView! Var titleLabel: UILabel! Var Label var messageLabel: UILabel! Var message: String tableView var tableView: UITableView! // Table data source var labelStrings: [String] // Click the button to call back var delegate: FSCAlertViewDelegate? // Initialize the related controls // Note that in order to make the height of the pop-up adaptive, the height of the pop-up can not be written dead, 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 is behind the relevant data sources and agent / / 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 ()} // It is also easy to implement the "swing" function. First, let your class implement the AVAudioPlayerDelegate protocol. Override func motionEnded(_ Motion: uievent. EventSubtype, with event: UIEvent?) {fscAlertView = fscAlertView (frame: self.view.bounds, title: "What's the problem?" , message: "You can also find this feature in the feedback help center on individual pages ", labelStrings: [" Help center "," encountered an exception "," feedback "," participated in the Beta "," closed a little bit "," nothing "]) fscalertView.delegate = self self.view.addSubView (fscAlertView)} Attached is a link to the project: https://github.com/sichangfeng/FSCAlertView.git, program downloading use, general shake in the project events should be global monitor, related methods should be implemented in the AppDelegate, can obtain the view under the UIWindow, A dialog box is displayed. I'll put the project instance code in the ViewController for your convenience.Copy the code