是否可以在UIAlertController 的左右两侧添加图标?

Is it possible to add icon at the both right and left sides of UIAlertController?

目前,这是我在 UIAlertController 左侧添加图标的方式。

let chooseImage = UIImage(systemName: "photo")

let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let chooseImageAction = UIAlertAction(title: "choose_image".localized, style: .default) { _ in
    self.chooseImage()
}
chooseImageAction.setValue(chooseImage, forKey: "image")

alert.addAction(chooseImageAction)

这是它的样子

不过,我还想在右侧添加一个图标,如红圈所示。

请问是否可以实现?谢谢

我认为使用默认按钮是不可能的,但您可以自定义一个,对于我的商品,我使用导航按钮来调用自定义操作 sheet(您可以使用一个简单的按钮),在 viewDidLoad 中设置我的按钮并调用 handleAS func 来呈现我的自定义操作 sheet:

navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Show ActionSheet", style: .plain, target: self, action: #selector(handleAS))

从上面的按钮调用的函数:

@objc fileprivate func handleAS() {
    
    let controller = CustomActionSheet(title: nil, message: nil, preferredStyle: .actionSheet)
    controller.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) // controller cancel Action
    self.present(controller, animated: true, completion: nil)
}

现在创建您的 CustomActionSheet class:

class CustomActionSheet: UIAlertController {

private var controller : UITableViewController

let cellId = "cellID"

override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
    
    controller = UITableViewController(style: .plain)
    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    
    controller.tableView.register(ActionSheetCell.self, forCellReuseIdentifier: cellId) // register your custom cell
    controller.tableView.dataSource = self
    controller.tableView.delegate = self
    controller.tableView.addObserver(self, forKeyPath: "contentSize", options: [.initial, .new], context: nil)
    self.setValue(controller, forKey: "contentViewController")
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}
deinit {
    controller.tableView.removeObserver(self, forKeyPath: "contentSize")
}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    guard keyPath == "contentSize" else {
        return
    }

    controller.preferredContentSize = controller.tableView.contentSize
 }
}

tableViewDelegate 和数据源的 CustomActionSheet 扩展

extension CustomActionSheet: UITableViewDataSource, UITableViewDelegate {

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    guard let cell = tableView.cellForRow(at: indexPath) as? ActionSheetCell else { return }
    print("This is:", cell.loadingLabel.text ?? "")
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 4 // number of action in actionSheet
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: cellId) as! ActionSheetCell

    switch(indexPath.row) {
    case 0:
        cell.loadingLabel.text = "Choose image"
        cell.myImageView.image = UIImage(systemName: "photo")?.withRenderingMode(.alwaysTemplate)
        cell.myImageView2.image = UIImage(systemName: "clock")?.withRenderingMode(.alwaysTemplate)
        break
    case 1:
        cell.loadingLabel.text = "Take a photo"
        cell.myImageView.image = UIImage(systemName: "camera")?.withRenderingMode(.alwaysTemplate)
        cell.myImageView2.image = UIImage(systemName: "car")?.withRenderingMode(.alwaysTemplate)
        break
    case 2:
        cell.loadingLabel.text = "Drawing"
        cell.myImageView.image = UIImage(systemName: "paintbrush.pointed")?.withRenderingMode(.alwaysTemplate)
        cell.myImageView2.image = UIImage(systemName: "paintbrush")?.withRenderingMode(.alwaysTemplate)
        break
    case 3:
        cell.loadingLabel.text = "Recording"
        cell.myImageView.image = UIImage(systemName: "mic")?.withRenderingMode(.alwaysTemplate)
        cell.myImageView2.image = UIImage(systemName: "cloud")?.withRenderingMode(.alwaysTemplate)
        break
    default:
        fatalError()
    }
    
    cell.selectionStyle = .none // comment if do you want selection of row

    return cell
 }
}

创建您的自定义单元格:

class ActionSheetCell: UITableViewCell {

let loadingLabel: UILabel = {
    let label = UILabel()
    label.text = "Loading Results..."
    label.textColor = #colorLiteral(red: 0, green: 0.4199056029, blue: 0.9801818728, alpha: 1)
    label.textAlignment = .center
    label.font = .systemFont(ofSize: 18, weight: .regular)
    label.heightAnchor.constraint(equalToConstant: 55).isActive = true
    
    return label
}()

let myView: UIView = {
    let iv = UIView()
    iv.backgroundColor = .clear
    iv.translatesAutoresizingMaskIntoConstraints = false
    iv.contentMode = .scaleAspectFit
    iv.widthAnchor.constraint(equalToConstant: 55).isActive = true
    iv.clipsToBounds = true
    
    return iv
}()

let myView2: UIView = {
    let iv = UIView()
    iv.backgroundColor = .clear
    iv.translatesAutoresizingMaskIntoConstraints = false
    iv.contentMode = .scaleAspectFit
    iv.widthAnchor.constraint(equalToConstant: 55).isActive = true
    iv.clipsToBounds = true
    
    return iv
}()

let myImageView: UIImageView = {
    let iv = UIImageView()
    iv.image = UIImage(systemName: "car")?.withRenderingMode(.alwaysTemplate)
    iv.tintColor = #colorLiteral(red: 0, green: 0.4199056029, blue: 0.9801818728, alpha: 1)
    iv.contentMode = .scaleAspectFit
    iv.translatesAutoresizingMaskIntoConstraints = false
    
    return iv
}()

let myImageView2: UIImageView = {
    let iv = UIImageView()
    iv.image = UIImage(systemName: "clock")?.withRenderingMode(.alwaysTemplate)
    iv.tintColor = #colorLiteral(red: 0, green: 0.4199056029, blue: 0.9801818728, alpha: 1)
    iv.contentMode = .scaleAspectFill
    iv.translatesAutoresizingMaskIntoConstraints = false
    
    return iv
}()

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
    
    myView.addSubview(myImageView)
    myImageView.centerYAnchor.constraint(equalTo: myView.centerYAnchor).isActive = true
    myImageView.centerXAnchor.constraint(equalTo: myView.centerXAnchor).isActive = true
    myImageView.widthAnchor.constraint(equalToConstant: 24).isActive = true
    myImageView.heightAnchor.constraint(equalToConstant: 24).isActive = true
    
    myView2.addSubview(myImageView2)
    myImageView2.centerYAnchor.constraint(equalTo: myView2.centerYAnchor).isActive = true
    myImageView2.centerXAnchor.constraint(equalTo: myView2.centerXAnchor).isActive = true
    myImageView2.widthAnchor.constraint(equalToConstant: 24).isActive = true
    myImageView2.heightAnchor.constraint(equalToConstant: 24).isActive = true
    
    let stackView = UIStackView(arrangedSubviews: [myView, loadingLabel, myView2])
    stackView.distribution = .fill
    stackView.translatesAutoresizingMaskIntoConstraints = false
    
    contentView.addSubview(stackView)
    stackView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
    stackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
    stackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
    stackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
    
}

required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
 }
}

在didSelectRowAt中可以调用其他函数...

这是结果: