Custom UIActivityViewController not appear image when it is in the "More" menu item - ios

I created custom UIActivity and override variable activityImage used my image.
fileprivate extension UIActivity.ActivityType {
static let extendedMessage =
UIActivity.ActivityType("ExtendedMessage")
}
Custom UIActivity:
fileprivate class ExtendedMessageActivity: UIActivity {
private let phoneNumbers: [String]
private var message: String?
init(phoneNumbers: [String]) {
self.phoneNumbers = phoneNumbers
super.init()
}
override static var activityCategory: UIActivity.Category {
return .share
}
override var activityType: UIActivity.ActivityType? { return .extendedMessage }
override var activityTitle: String? { return NSLocalizedString("Message", comment: "") }
override var activityImage: UIImage? {
return UIImage(named: "message-app-icon")
}
override func canPerform(withActivityItems activityItems: [Any]) -> Bool {
....
}
override func prepare(withActivityItems activityItems: [Any]) {
....
}
override func perform() {
....
}
}
The image appears in the set.
I have a problem the image does not appear when it is in the "More" menu item.
Why the image does not appear?

Had tried to find documentation for the activity settings icon. Not found proper documentation. Just add the below code in your custom UIActivity, Working fine for me with Swift 5.2
#objc var _activitySettingsImage: UIImage? {
return UIImage(named: "activitySettingsIcon")
}
Don't forgot to activitySettingsIcon image set in 29pt.

I solved the same issue by adding the following (in Objective C, but you get the idea).
- (UIImage *)_activitySettingsImage {
return [UIImage imageNamed:#"message-app-icon-for-setting"];
}
Apparently, image for more section should be smaller than the one in _activityImage. At the time of writing (XCode 12.3), 60pt for activityImage and 30pt for activitySettingsImage work for me. (I also added #2x for each image)..

Related

Open in Safari with UIActivityViewController?

I'm sharing a URL via UIActivityViewController. I'd like to see "Open in Safari" or "Open in browser" appear on the share sheet, but it doesn't. Is there a way to make this happen?
Note: I am not interested in solutions that involve adding somebody else's library to my app. I want to understand how to do this, not just get it to happen. Thanks.
Frank
Yes, you could add your custom action to Share sheet in iOS
You would have to copy this class.
class MyActivity: UIActivity {
var _activityTitle: String
var _activityImage: UIImage?
var activityItems = [Any]()
var action: ([Any]) -> Void
init(title: String, image: UIImage?, performAction: #escaping ([Any]) -> Void) {
_activityTitle = title
_activityImage = image
action = performAction
super.init()
}
override var activityTitle: String? {
return _activityTitle
}
override var activityImage: UIImage? {
return _activityImage
}
override var activityType: UIActivity.ActivityType {
return UIActivity.ActivityType(rawValue: "com.someUnique.identifier")
}
override class var activityCategory: UIActivity.Category {
return .action
}
override func canPerform(withActivityItems activityItems: [Any]) -> Bool {
return true
}
override func prepare(withActivityItems activityItems: [Any]) {
self.activityItems = activityItems
}
override func perform() {
action(activityItems)
activityDidFinish(true)
}
}
Please go through the class you might need to change a few things.
This is how you use it.
let customItem = MyActivity(title: "Open in Safari", image: UIImage(systemName: "safari") ) { sharedItems in
guard let url = sharedItems[0] as? URL else { return }
UIApplication.shared.open(url)
}
let items = [URL(string: "https://www.apple.com")!]
let ac = UIActivityViewController(activityItems: items, applicationActivities: [customItem])
ac.excludedActivityTypes = [.postToFacebook]
present(ac, animated: true)
I have done this for one action, and tested it, it works.
Similarly you could do it for other custom actions.
For more on it refer this link.
Link To Detailed Post

ios Swift Protocol Data

I don't use storyboards.
I want to send protocol data using #objc button action.
However, the sent view controller does not run the protocol function.
May I know what the reason is?
In fact, there's a lot more code.
Others work, but only protocol functions are not executed.
The didUpdataChampion function is
Data imported into a different protocol.
I have confirmed that there is no problem with this.
protocol MyProtocolData {
func protocolData(dataSent: String)
func protocolCount(dataInt: Int)
}
class PickViewController: UIViewController,ChampionManagerDelegate{
static let identifier = "PickViewController"
var count = 0
var urlArray = [URL]()
var pickDelegate : MyProtocolData?
override func viewDidLoad() {
super.viewDidLoad()
champions.riot(url: "myURL")
}
#objc func topHand(){
pickDelegate?.protocolData(dataSent: "top")
print(count)
pickDelegate?.protocoCount(dataInt: count)
let cham = ChampViewController()
cham.modalPresentationStyle = .fullScreen
present(cham, animated: true, completion: nil)
}
//Data imported to another protocol
func didUpdataChampion(_ championManager: ChampionManager, champion: [ChampionRiot]) {
print(#function)
count = champion.count
for data in champion {
let id = data.id
guard let url = URL(string: "https://ddragon.leagueoflegends.com/cdn/11.16.1/img/champion/\(id).png") else { return }
urlArray.append(url)
count = urlArray.count
}
}
func didFailWithError(error: Error) {
print(error)
}
}
class ChampViewController: UIViewController,MyProtocolData {
var pickData = ""
var arrayCount = 0
override func viewDidLoad() {
super.viewDidLoad()
}
func protocolData(dataSent: String) {
print(#function)
pickData = dataSent
print(pickData)
}
func protocoCount(dataInt: Int) {
print(#function)
arrayCount = dataInt
print(arrayCount)
}
}
i don't see full code, for instance how you call bind to topHand(), my advice is:
check that topHand - is called
check that pickDelegate isn't nil inside topHand
Create Object fo your PickViewController class and set its delegate to self.
var yourObj = PickViewController()
override func viewDidLoad() {
super.viewDidLoad()
yourObj.delegate = self
}

Delegate function does not get called

I have two ViewControllers and I'm trying to set one as the other's delegate. This is what I have:
ViewController One:
protocol storeChosenDelegate {
func getPopularProductsFor(store id: String)
}
class PopularStoresVC: UIViewController {
//MARK: - Properties
var delegate: storeChosenDelegate?
private let storesView = PopularStoresView()
private let STORE_CELL = "storeCell"
fileprivate var currentStore: Int = 0 {
didSet {
delegate?.getPopularProductsFor(store: "THIS IS WORKING NOW.")
}
}
}
And this is what I have in ViewController Two:
//MARK: - Properties
private let PRODUCT_CELL = "productCell"
private var popularStores = PopularStoresVC()
//MARK: - Initializers
override func viewDidLoad() {
super.viewDidLoad()
popularStores.delegate = self
setupProductsCollection()
}
extension PopularProductsVC: storeChosenDelegate {
func getPopularProductsFor(store id: String) {
//TODO: Show all popular products for the store's id we got.
print("Got store \(id)")
}
}
It seems that the didSet is getting called, and I do set the Second VC as the delegate, but the function just does not getting called. I have no errors or warnings related to that so I don't really understand why this is not working.

How to print SFSafariViewController full web page?

I am opening a pdf file in SFSafariViewController. Now I want to print this PDF from SFSafariViewController.
But Share button of safari view controller does not have print option.
Please tell me how to add print functionality to SFSafariViewController.
You can custom activity.
extension ViewController: SFSafariViewControllerDelegate {
func safariViewController(_ controller: SFSafariViewController, activityItemsFor URL: URL, title: String?) -> [UIActivity] {
let acitivity = CustomActivity()
return [acitivity]
}
func printURL(url: URL) {
}
}
CustomActivity.swift
import Foundation
import UIKit
class CustomActivity: UIActivity {
override class var activityCategory: UIActivityCategory {
return .action
}
override var activityType: UIActivityType? {
return UIActivityType.print
}
override var activityTitle: String? {
return "Print"
}
override var activityImage: UIImage? {
return nil
}
override func canPerform(withActivityItems activityItems: [Any]) -> Bool {
return true
}
override func perform() {
// do something here
}
}

Accessing a function inside a class function in Swift

How would I call darkness and put parameters in it?
class imageProcesses {
class func DefaultProcesses() {
func CompleteDarkness(image: UIImage) -> UIImage {
let dark = Darken(124, image: image)
return dark
}
}
}
iv'e tried this:
ImageProcessor.DefaultProcesses().CompleteDarkness(image!)
but it doesn't work
You can't call a nested function from outside. Move it out to a class function:
class imageProcesses {
class func CompleteDarkness(image: UIImage) -> UIImage {
let dark = Darken(124, image: image)
return dark
}
class func DefaultProcesses() {
// ...
}
}
Why are you declaring a function inside of a function anyway?
class imageProcesses {
class func DefaultProcesses(image: UIImage) {
completeDarkness(image: image)//calls completeDarkness.
}
func CompleteDarkness(image: UIImage) -> UIImage {
let dark = Darken(124, image: image)
return dark
}
}
Later call
ImageProcessor.DefaultProcesses(image: image!)//Now calling DefaultProcesses will run Complete Darkness and anything else you put in there.
Think this is what you want you can stick that in the play ground and have a go with it
func Darken(input:Int, image:UIImage) -> UIImage{
return UIImage()
}
class ImageProcesses {
class func DefaultProcesses() -> ((UIImage) -> UIImage){
func CompleteDarkness(image: UIImage) -> UIImage {
let dark = Darken(124, image: image)
return dark
}
return CompleteDarkness
}
}
let image = UIImage()
ImageProcesses.DefaultProcesses()(image)

Resources