1

I want to put the image to the right in an ActionSheet as seen on the AppStore. I know how to add an image and change the titleText style but I am unable to figure out how to change the positions of these two.

Third party libraries are not appreciated.

Screenshot - AppStore

Screenshot

Thanks!

Sham Dhiman
  • 1,348
  • 1
  • 21
  • 59

3 Answers3

3

Updated to swift 4.2 and added images. Go through below link for more info.

How to customize UIAlertController with UITableView or is there any default control available like this UI in Pages app?

import Foundation
import UIKit

class CustomActionSheet: UIAlertController{

    private var controller : UITableViewController


    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {

        controller = UITableViewController(style: .plain)
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        controller.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        controller.tableView.dataSource = 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
    }

}

extension CustomActionSheet: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 4
    }

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

        switch(indexPath.row) {
        case 0:
            cell.textLabel?.text = "Share Link via iCloud"
            cell.accessoryView = UIImageView(image:UIImage(named:"image1.png")!)
            break
        case 1:
            cell.textLabel?.text = "Send a Copy"
           cell.accessoryView = UIImageView(image:UIImage(named:"image2.png")!)
            break
        case 2:
            cell.textLabel?.text = "Open in Another App"
            cell.accessoryView = UIImageView(image:UIImage(named:"image3.png")!)
            break
        case 3:
            cell.textLabel?.text = "Move to..."
            cell.accessoryView = UIImageView(image:UIImage(named:"image4.png")!)
            break
        default:
            fatalError()
        }

        return cell
    }
}

You can use this custom class from your view controller

let controller = CustomActionSheet(title: nil, message: nil, preferredStyle: .actionSheet)
        controller.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
        self.present(controller, animated: true, completion: nil)
channu
  • 223
  • 3
  • 10
  • Thanks, This is good but I am trying to figure out how to make the cell height the same as the cancel button – Kurt L. Aug 02 '20 at 19:46
0

Using the standard UIAlertController API, that is not possible.

Roll your own alert, or rethink your aversion against 3rd party libs.

From the documentation:

Important

The UIAlertController class is intended to be used as-is and does not support subclassing. The view hierarchy for this class is private and must not be modified.

Note that the other answers, while appearing to work, violate this restriction. If you do follow them, be aware that they might stop working at any time, and your app might even get rejected by Apple.

Community
  • 1
  • 1
Gereon
  • 17,258
  • 4
  • 42
  • 73
0

It's a bit tricky, but it's achievable; first of all do not use UIActionSheet it's been deprecated since iOS8 use UIAlertController with preferredStyle = .actionSheet

then place manually the image:

let imageView = UIImageView(image: UIImage(named: "yourImage"))
imageView.frame = CGRect(x: alertController.view.frame.width-25-24, y: 18, width: 24, height: 24)
alertController.view.addSubview(imageView)

play with alertController.view.frame.width-25-24 to place your image

Note: this will place the image in your top alert action. If you want to put images in multiple actions you need to play with the y coordinate(for example)

let imageViewAction2 = UIImageView(image: UIImage(named: "yourSecondImage"))
alertController.view.addSubview(imageViewAction2)
imageViewAction2.frame = CGRect(x: alertController.view.frame.width-25-24, y: 75, width: 24, height: 24)
Alastar
  • 1,284
  • 1
  • 8
  • 14