How to Add Icon to a Share Sheet in Swift

How to add icons to options in action sheets : iOS?

You can add image to UIAlertAction with image key:

let image = UIImage(named: "IMAGE_NAME")
var alertAction = UIAlertAction(title: "TITLE", style: .default, handler: nil)
alertAction.setValue(image, forKey: "image")

iOS13 share sheet: how to set preview thumbnail when sharing UIImage

Just pass the image urls to UIActivityViewController not the UIImage objects.
For example:

let imageURLs: [URL] = self.prepareImageURLs()
let activityViewController = UIActivityViewController(activityItems: imageURLs, applicationActivities: nil)
self.present(activityViewController, animated: true, completion: nil)

You can see that the image name and the image properties are shown in the top of the UIActivityViewController. Hope it helps!

How to attach an image icon to the `UIActivityViewController`?

You need to define the LinkMetadata using activityViewControllerLinkMetadata method:

    @available(iOS 13.0, *)
func activityViewControllerLinkMetadata(_ activityViewController: UIActivityViewController) -> LPLinkMetadata? {
let metadata = LPLinkMetadata()
// define your metadata here
return metadata
}

More info here: https://developer.apple.com/documentation/uikit/uiactivityitemsource/3144571-activityviewcontrollerlinkmetada?language=swift

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

I don't think it's possible with the default one but you can do a custom one, for my commodity I use a navigation button to call custom action sheet (you can use a simple butto), in viewDidLoad set my button and call handleAS func to present my Custom action sheet:

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

function called from button above:

@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)
}

Now create your 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
}
}

CustomActionSheet extension for tableViewDelegate and Datasource

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
}
}

Create your custom 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")
}
}

In didSelectRowAt you can call other functions...

This is the result:

Sample Image

Xcode Swift how to add image to UIAlertController options?

 let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)            
alert.modalPresentationStyle = .popover

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

let image1 = UIImage(named: "icshare")
let imageView1 = UIImageView()
imageView1.image = image1
alert.view.addSubview(imageView1)
imageView1.frame = CGRect(x: 25, y: 75, width: 24, height: 24)

let shareExternal = UIAlertAction(title: NSLocalizedString("Share External Link", comment: ""), style: .default) { action in
}
let shareInApp = UIAlertAction(title: "Share within", style: .default) {
action in
}

alert.addAction(shareInApp)
alert.addAction(shareExternal)

if let presenter = alert.popoverPresentationController
{
presenter.sourceView = button
presenter.sourceRect = button.bounds
}
present(alert, animated: true, completion: nil)


Related Topics



Leave a reply



Submit