I am trying to figure out how to create a user interactive post or tweet kind of like SoundCloud's here below:
The portion highlighted in yellow is the part that interests me because as far as I can tell when it comes to UIActivityViewController (which is what Sound Cloud uses for this) the only objects that work for sharing are images and strings.
Further more, if you were to tap the portion highlighted in yellow this screen would pop up on twitter:
HOW DO THEY DO THAT!? THEY HAVE A PAUSE BUTTON AND EVERYTHING!
This is my attempt to do that...
func displayShareSheet(shareContent:String) {
let someView:CustomView = CustomView() // CustomView is a subclass of UIView
let activityViewController = UIActivityViewController(activityItems: [someView], applicationActivities: nil)
presentViewController(activityViewController, animated: true, completion: {})
}
...which doesn't work. The UIActivityViewController sheet pops up with no share options indicated.
I understand that some may consider this a broad question but if you could at least point me in the right direction I would be very grateful. Thank You.
This works. For the full list of sharing destinations run it on your device and not the simulator. The simulator gives you a smaller list.
func createActivityController() -> UIActivityViewController {
let someText:String = textView.text
let google = NSURL(string:"http://google.com/")!
// let's add a String and an NSURL
var activityViewController = UIActivityViewController(
activityItems: [someText, google],
applicationActivities: nil)
activityViewController.completionHandler = {(activityType, completed:Bool) in
if !completed {
print("cancelled")
return
}
if activityType == UIActivityTypePostToTwitter {
print("twitter")
}
if activityType == UIActivityTypeMail {
print("mail")
}
}
// you can specify these if you'd like.
// activityViewController.excludedActivityTypes = [
// UIActivityTypePostToTwitter,
// UIActivityTypePostToFacebook,
// UIActivityTypePostToWeibo,
// UIActivityTypeMessage,
// UIActivityTypeMail,
// UIActivityTypePrint,
// UIActivityTypeCopyToPasteboard,
// UIActivityTypeAssignToContact,
// UIActivityTypeSaveToCameraRoll,
// UIActivityTypeAddToReadingList,
// UIActivityTypePostToFlickr,
// UIActivityTypePostToVimeo,
// UIActivityTypePostToTencentWeibo
// ]
return activityViewController
}
For the first part it's only play button that clicks you to popup the player view.
Second: You can do this by just popping a new viewController, use any popup pod: CWPOP as ex. Or whatever suits you or as Twitter here i'm not sure but probably they're doing their own, and you just build a normal view which has the play and everything.
They used do it better before and let you play the music during going through tweets, that was way better to me at least.
Related
I am setting GIF in UIImageView as per following code in Splash Screen.
let url = Bundle.main.url(forResource: "Splash", withExtension: "gif")
self.imgGifSplash.sd_setImage(with: url!, completed: { (img, error, type, url) in
// this block is called when Gif is loaded in UIImageView, not when image is completed playing once.
DispatchQueue.main.asyncAfter(deadline: .now() + 3.2) { // Change `2.0` to the desired number of seconds.
if let _ = UserData.shared.loginData?.token {
let VC = mainStoryboard.instantiateViewController(withIdentifier: "HomeVCNav") as! UINavigationController
objAppDelegate.window?.rootViewController = VC
}
else
{
let VC = mainStoryboard.instantiateViewController(withIdentifier: "LoginNav") as! UINavigationController
objAppDelegate.window?.rootViewController = VC
}
}
}
I want Gif to be played only once.. So i tried using timer of 3.2 seconds but when i am using different devices then i am getting different results like sometimes it played only once, sometime twice, sometime not even completing once.
How can i achieve a perfect animated splash screen that plays GIF only once ?
Hope to get perfect answer. Thanks in advance.
I call the function. Alright
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
let index = viewControllers?.index(of: viewController)
if index == 2 {
let layout = UICollectionViewFlowLayout()
let photoSelectorController = PhotoSelectorController(collectionViewLayout: layout)
let navController = UINavigationController(rootViewController: photoSelectorController)
present(navController, animated: true, completion: nil)
return false }
return true
}
Photos not showing on first time
I have all of the right things asking for permission and everything..
I then call for the images with these functions. It works, but the second time I hit the button after canceling posting a post..
I'm not sure how to get the images from the library for the first call.
After that it works like a charm, but most users have been telling me this isn't a good experience , if they have to try twice.
I'm trying to reduce friction in the app usage.
It should show the pictures right after the user "Allows" the app access to the pictures so they can post, but I'm not sure what I'm doing wrong for it to show the pictures soon as someone grants access.
var selectedImage: UIImage?
var images = [UIImage]()
var assets = [PHAsset]()
fileprivate func assetsFetchOptions() -> PHFetchOptions {
let fetchOptions = PHFetchOptions()
fetchOptions.fetchLimit = 100
let sortDescriptor = NSSortDescriptor(key: "creationDate", ascending: false)
fetchOptions.sortDescriptors = [sortDescriptor]
return fetchOptions
}
fileprivate func fetchPhotos() {
let allPhotos = PHAsset.fetchAssets(with: .image, options: assetsFetchOptions())
DispatchQueue.global(qos: .background).async {
allPhotos.enumerateObjects { (asset, count, stop) in
print(asset)
let imageManager = PHImageManager.default()
let targetSize = CGSize(width: 200, height: 200)
let options = PHImageRequestOptions()
options.isSynchronous = true
imageManager.requestImage(for: asset, targetSize: targetSize, contentMode: .aspectFit, options: options, resultHandler: { (image, info) in
if let image = image {
self.images.append(image)
self.assets.append(asset)
if self.selectedImage == nil {
self.selectedImage = image
}
}
if count == allPhotos.count - 1 {
DispatchQueue.main.async {
self.collectionView?.reloadData()
}
}
})
}
}
}
If you fetchAssets before the user grants privacy access to your app, you'll get a PHFetchResult that's empty.
However, if before making that fetch you register as a photo library observer, you'll get a photoLibraryDidChange callback as soon as the user approves privacy access for the app... from that callback you can access an updated version of your original fetch result (see changeDetails(for:)) that has all of the assets your fetch should have found. Then you can tell your UI to update and display those assets. (This is how Apple's canonical PhotoKit example code works.)
Also, once you have a populated fetch result, please don't request thumbnails for the whole thing the way you're doing.
Users commonly have photo libraries with tens of thousands of assets, many of which are in iCloud and not on the local device. If you synchronously get all thumbnails, you'll take forever, use tons of memory and CPU resources, and generate all kinds of network traffic (slowing things down even more) for resources your user may never see.
PhotoKit is designed to allow easy use in conjunction with UI elements like UICollectionView. A collection view only loads cells that are currently (or soon to be) on screen, even if you've told it you have zillions of items in your collection — similarly, you can request thumbnails only for assets that are visible in your collection view. Wherever you have your per-cell UI setup logic is where you should have your PHImageManager request. (Again, this is what the canonical PhotoKit example code does.)
You can optimize even further by "preheating" the thumbnail fetch/generation process for assets that are soon to be onscreen. And then by managing your "preheating" to cancel such work in progress when further UI updates (e.g. fast scrolling of large collection) make it unnecessary. PHCachingImageManager does this. (And yet again, it's what the canonical Apple sample does. Actually, that sample's a bit out of date, and as such does more work than it needs to on this front — it does its own calculation of what cells are just outside the scroll rect, but since iOS 10 the UICollectionViewDataSourcePrefetching protocol manages that for you.)
I want to prevent taking screenshot of a page in app.
how to do it programmatically so that screenshots cannot be taken.
Found code to detect screenshot. Can it be deleted as soon as a screenshot is taken?
let mainQueue = NSOperationQueue.mainQueue()
NSNotificationCenter.defaultCenter().addObserverForName(UIApplicationUserDidTakeScreenshotNotification,
object: nil,
queue: mainQueue) { notification in
// executes after screenshot
}
There is no way to prevent ScreenShots but you can prevent Screen Recording
through this code.
func detectScreenRecording(action: #escaping () -> ()) {
let mainQueue = OperationQueue.main
NotificationCenter.default.addObserver(forName: UIScreen.capturedDidChangeNotification, object: nil, queue: mainQueue) { notification in
// executes after screenshot
action()
}
}
//Call in vewWillApper
detectScreenRecording {
print(UIScreen.main.isCaptured)
if UIScreen.main.isCaptured {
//your vier hide code
print("self.toHide()")
} else {
// self.sceneDeleg(ate?.window?.isHidden = false
//your view show code
print("self.toShow()")
}
}
There is absolutely no way to completely prevent user from taking screenshot during the app process, and that's because you do not have access to delete photos in the photo gallery of the user. It would totally be a security issue if you could access your user's photos.
However, there are ways to partially prevent screenshots, as described here: Prevent screen capture in an iOS app
Technically that is possible, via the Photos framework, the docs for which can be found here.
Example code can be found here.
However, this will ask the user's permission first, and then again to confirm deletion; so possibly not the ideal solution. Unfortunately this is as good as it gets as Apple has the Camera Roll fairly locked down.
You cannot prevent user from taking screenshot, however, you can hide the content while a screenshot is taken, Use this code to do so..
extension UIView {
func hideContentOnScreenCapture() {
DispatchQueue.main.async {
let field = UITextField()
field.isSecureTextEntry = true
self.addSubview(field)
field.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
field.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
self.layer.superlayer?.addSublayer(field.layer)
field.layer.sublayers?.first?.addSublayer(self.layer)
}
}
}
Usage:
yourView.hideContentOnScreenCapture()
I am creating a pdf in my ios9 app and would like to be able to save it to iBooks with the UIActivityViewController. Unfortunately, with the code I'm currently using (assuming that all options using :
applicationActivities: nil
for what I can do with the file will show up) only the "Message" and "Mail" items show up. I'm not excluding any activities, so hypothetically UIActivityTypeOpenInIBooks should show up just fine. However, I can't get iBooks or anything but Message and Mail show up. (For future reference I will refer to this outcome as outcome A ) Is there another recommended way of doing this?
The code I'm using is below:
// creating pdf image from the UIView
let pdf = self.getPDFImageFromDrawingView()
let activityViewController = UIActivityViewController(activityItems: [pdf], applicationActivities: nil) //should include any and all available activities right?
self.presentViewController(activityViewController, animated: true, completion: nil)
Is there something obvious I'm forgetting? How do you include iBooks as an option for saving files?
EDIT :
In debugging this issue, I've saved the UIView content as a JPG AND as a pdf file. When I use ONLY the generated UIImage as such:
(outcome B)
let image = self.getUIImageFromDrawingView() // generate a UIImage object
let activityViewController = UIActivityViewController(activityItems: [image], applicationActivities: nil)
self.presentViewController(activityViewController, animated: true, completion: nil)
all the possible options show up, including open in iBooks (YES! But I need the much-higher resolution image generated by creating a PDF.)
When I add BOTH the image and the pdf to the activityItems (as such:
(outcome C)
let image = self.getUIImageFromDrawingView() // UIImage
let pdf = self.getPDFImageFromDrawingView() //produces an NSData object
let activityViewController = UIActivityViewController(activityItems: [image, pdf], applicationActivities:nil)
), I get more options then the original mail and message options - like FB, Pinterest and Evernote - but no iBooks.
Finally, when I go back to using only the PDF, I have the same things as before - only mail and messages. What could be causing this?
(BTW, interesting if not useless aside - when using both the JPG and the PDF, and testing the applicationActivities with Mail - I get the email of a jpg and a pdf, as expected. So the files are being generated as expected).
What could be causing this weird behavior?
EDIT 2 :
I Thought that may be the problem was that I was using NSData to send the pdf. So, I saved the object as an NSURL and used that. I got the same result as in (C) above - more options then just Messages and Mail, but no iBooks. This outcome came with using both the UIImage + NSURL combination, AND when using NSURL alone. When I used UIImage alone, I had many many options, as in the previous situation, including iBooks.
I've tried this every which way, and couldn't get it to work with the UIActivityController.
However, it worked like a charm when I used the UIDocumentInteractionController:
let pdfData = self.getPDFasNSData() // get the NSData object
let fileURL = self.getCurrentPDFURLName() //get the NSURL
self.docController = UIDocumentInteractionController(URL: fileURL)
if (fileURL != nil)
{
pdfData.writeToURL(fileURL, atomically: true);
self.docController.presentOptionsMenuFromBarButtonItem(self.organizeBarButton, animated: true)
}
Now the "open in iBooks" option shows up.
I am new cocos2dx developer.I am using the version cocos2dx 2.2.6.Now i want to share image on gmail and facebook.I refer many site and suggestion but still i am not clear about sharing.
We can use the UIActivityViewController to create a sharing dialog and use some CCRenderTexture code to take a screenshot. When the share button is tapped, a number of options for sharing are available depending on what applications the user has available on their phone.
You can create a sharing popup using the following code:
func openShareDialog() {
var scene = CCDirector.sharedDirector().runningScene
var node: AnyObject = scene.children[0]
var screenshot = screenShotWithStartNode(node as! CCNode)
let sharedText = "Text"
let itemsToShare = [screenshot, sharedText]
var excludedActivities = [ UIActivityTypeAssignToContact,
UIActivityTypeAddToReadingList, UIActivityTypePostToTencentWeibo]
var controller = UIActivityViewController(activityItems: itemsToShare, applicationActivities: nil)
controller.excludedActivityTypes = excludedActivities
UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(controller, animated: true, completion: nil)
}
Then we can take a screenshot using a CCRenderTexture:
func takeScreenshotWithNode(node: CCNode) -> UIImage {
CCDirector.sharedDirector().nextDeltaTimeZero = true
var viewSize = CCDirector.sharedDirector().viewSize()
var rtx = CCRenderTexture(width: Int32(viewSize.width), height: Int32(viewSize.height))
rtx.begin()
node.visit()
rtx.end()
return rtx.getUIImage()
}
Here's an example of what the popup would actually look like when displayed:
You can find more information on the UIActivityViewController in Apple's docs.
You can might find it handy to start by reading the docs here.
There are additional detailed instructions in the cocos2d-x.org site including ones for iOS.