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:
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
Swift: Google Maps Draw Waypoint Polyline
Load Image from Url on Watchkit
If-Let Any to Rawrepresentable<String>
Get Compiler Error in Swift Indexof()
Swift: How to Fix Infinite Loop When Adding a Value to a Firebase Variable
Firebase Access Keys in Queryorderby
Does Nsnumberformatter.Stringfromnumber Ever Return Nil
Swift 2, Protocol Extensions & Respondstoselector
Display Table View When Searchbar (From Searchcontroller) Begin Edited Swift
Fail to Import Restkit with Cocoapods Dynamic Frameworks
Swift 4.2, String Firstindex() Function Error in Xcode Playground
Error with Parse Query Findobjectsinbackgroundwithblock
How to Segue Values When My Viewcontroller Is Embedded in an Uinavigationcontroller
Inline Kvo of a Property in Another View Controller
Moving Keyboard When Editing Multiple Textfields with Constraints Swift