Trying to get an UIActivityViewController to animate like in iOS Photos on iPad:
Code so far:
if UIDevice.current.userInterfaceIdiom == .pad {
activityViewController.preferredContentSize = CGSize(width: 540, height: 720)
activityViewController.popoverPresentationController?.sourceRect = CGRect(x: UIScreen.main.bounds.width / 2 - 280, y: UIScreen.main.bounds.height, width: 540, height: 720)
activityViewController.popoverPresentationController?.permittedArrowDirections = []
}
viewController.present(activityViewController, animated: true, completion: nil)
Checking for iPad and setting size and (final) position. That's how far I got. Tried adding an UIView.animate block to animate the view after it is being presented (changinging the initial position of course). Also tried creating a CATransition with activityViewController.view.layer.add(transition, forKey: nil). No success.
Related
I am trying to make a drawing app and I want to add the activity view controller. It works on the iPhone, but it will not show the entire view controller on the iPad. I have tried many different approaches based off what I have read, but the result is the same. Any help is appreciate.
Code:
#IBAction func actionsTapped(_ sender: Any) {
// Setting description
let message = "Actions for your drawing"
// Get the image to save
let image = getImage()
let activityViewController : UIActivityViewController = UIActivityViewController(activityItems: [message, image], applicationActivities: nil)
// Ipad popup
activityViewController.popoverPresentationController?.sourceView = (self.view)
// Remove Ipad arrow
activityViewController.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection.down
activityViewController.popoverPresentationController?.sourceRect = CGRect(x: 150, y: 150, width: 0, height: 0)
// Pre-configuring activity items
activityViewController.activityItemsConfiguration = [
UIActivity.ActivityType.message,
UIActivity.ActivityType.print,
UIActivity.ActivityType.saveToCameraRoll,
UIActivity.ActivityType.airDrop
] as? UIActivityItemsConfigurationReading
// Exclude
activityViewController.excludedActivityTypes = [
UIActivity.ActivityType.postToWeibo,
UIActivity.ActivityType.addToReadingList,
UIActivity.ActivityType.postToFlickr,
UIActivity.ActivityType.postToVimeo,
UIActivity.ActivityType.postToTencentWeibo,
UIActivity.ActivityType.postToFacebook
]
activityViewController.isModalInPresentation = true
self.present(activityViewController, animated: true, completion: nil)
}
As someone pointed out, which I tried changing the height and width in the sourceRect does not work. See below where I changed
activityViewController.popoverPresentationController?.sourceRect = CGRect(x: 150, y: 150, width: 0, height: 0)
to
activityViewController.popoverPresentationController?.sourceRect = CGRect(x: 150, y: 150, width: 500, height: 500)
My initial thought was that x and y would change the position of the popup and height and width change the size, but it seems that it's the reverse in sourceRect.
It sounds like you're misunderstanding what the sourceRect is. It has nothing to do, in and of itself, with the size of the activity view controller. It determines where the arrow points to.
The activity view controller always has its own full size. I suspect that what's going wrong here is due to this line:
activityViewController.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection.down
That forces the whole activity view controller to appear above the source rect (i.e. more toward the top of the screen) — but there isn't room. If you just cut that line, the activity view controller may be able to appear where there is room.
Sharing on teams bugs out modal like this
I have implemented UIActivityController where I am sharing an image along with a link but excluding image when sharing it to any app and using the image just for saving it to camera roll. When I try to share to Microsoft Teams, this is what I could see which happens randomly (inconsistent). What could be the cause of this issue? Thank You :)
Try that:
if UIDevice.current.userInterfaceIdiom == .phone {
present(activityView, animated: true) {
}
} else {
// Change Rect to position Popover
popup = UIPopoverController(contentViewController: activityView)
popup.present(from: CGRect(x: view.frame.size.width / 2, y: view.frame.size.width / 2, width: 100, height: 100), in: view, permittedArrowDirections: .any, animated: true)
}
I'm trying to animate SCNView height, but it seems like there are some visual issue.
When content is growing it looks like everything is ok, but when I'm trying to decrease the height, view just jumps to final height instantly.
let newHeight = scene.frame.height + (open ? 100.0 : -100.0)
UIView.animate(withDuration: 1.0, animations: {
self.scene.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: newHeight)
}) { finished in
self.open = !self.open
}
See
Code Running in Sumulator
With regular view everything works fine.
Set contentMode of SCNView to .scaleToFill where needed (e.g. in viewDidLoad). It works as expected.
let view: SCNView
...
view.contentMode = .scaleToFill
There is a relationship between this behavior and the content mode of scene. You may try:
scene.contentMode = .scaleToFill
Link to my github account with files, simply download zip: https://github.com/jzhang172/modalTest
When I click on the "popover" link, I would like to center the popover in the center of the screen.
I tried referencing some stackoverflow questions such as:
how to center a popoverview in swift
but no luck. I'm a noob in swift and I'm only using swift, not objective C.
Screenshot of what I see:
Replacing
controller?.sourceRect = CGRectMake(0.0, self.view.layer.bounds.height * 0.5,0.0,0.0)
with
controller?.sourceRect = CGRectMake(self.view.layer.bounds.width * 0.5, self.view.layer.bounds.height * 0.5,0.0,0.0)
will center the popover content horizontally and vertically.
You can center the UIPopover in your view with the code below.
let controller = vc.popoverPresentationController
controller?.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)
controller?.sourceView = self.view
controller?.sourceRect = CGRectMake(0.0, self.view.layer.bounds.height * 0.5,0.0,0.0)
vc.preferredContentSize=CGSize(width: 400, height: 200)
Swift 3:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let popoverPresentationController = segue.destination.popoverPresentationController {
let controller = popoverPresentationController
controller.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)
controller.sourceView = self.view
controller.sourceRect = CGRect(x: UIScreen.main.bounds.width * 0.5 - 200, y: UIScreen.main.bounds.height * 0.5 - 100, width: 400, height: 200)
segue.destination.preferredContentSize=CGSize(width: 400, height: 200)
}
}
I am trying to animate between two full screen views (same view controller) in swift using CATransition. Looking to replicate (or get close to) navigation view controller push transition. Running into issue where view2 (the new view to present) is sliding over correctly, but view1 (the view underneath) disappears. Basically the view that is being animated is sliding over a white screen, but I want it to slider over the previous screen.
var pushAnimationEffect = CATransition()
override func viewDidLoad() {
super.viewDidLoad()
pageToUIView[i] = UIView()
view1.frame = CGRect(x: 0, y: 0, width: screenSize.width, height: screenSize.height)
view1.center = CGPointMake(screenSize.width/2, screenSize.height/2)
view2.frame = CGRect(x: 0, y: 0, width: screenSize.width, height: screenSize.height)
view2.center = CGPointMake(screenSize.width/2, screenSize.height/2)
view1.layer.addAnimation(pushAnimationEffect, forKey: nil)
view2.layer.addAnimation(pushAnimationEffect, forKey: nil)
self.view.addSubview(view1)
pushAnimationEffect.delegate = self
pushAnimationEffect.duration = 0.4
pushAnimationEffect.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
}
func nextPage() {
pushAnimationEffect.type = kCATransitionMoveIn
pushAnimationEffect.subtype = kCATransitionFromRight
self.view.addSubview(view2)
view1.removeFromSuperview()
}
func prevPage() {
pushAnimationEffect.type = kCATransitionMoveIn
pushAnimationEffect.subtype = kCATransitionFromLeft
self.view.addSubview(view1)
view2.removeFromSuperview()
}
Simplified the code a bit so its easier to read.
Is there a better way to do this? Is there something wrong with the code?
You need to do the view remove on after the animation completes. Use the animationDidStop:finished: delegate method.