I'm working on an iOS Action Extension that's capable of showing an SKStoreProductViewController. Action Extensions are capable of showing in two sizes, either full screen (NSExtensionActionWantsFullScreenPresentation set to YES) or in a small centered window in the screen (set to NO). I'm opting for the minimal window in the middle, my extension doesn't warrant use of the full screen.
When I show an SKStoreProductViewController modally within my extension as prescribed it ends up large and clipped in the center of the action extension. Has anybody else encountered this or found a way around it?
With NSExtensionActionWantsFullScreenPresentation set to YES, the extension behaves like a UIModalPresentationStyleFormSheet thus:
override func viewDidLoad() {
super.viewDidLoad()
preferredContentSize = CGSize(width: 540, height: 620)
}
Note that the extension is displayed full screen on an iPhone (as expected).
References:
https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/SystemExtensionKeys.html#//apple_ref/doc/uid/TP40014212-SW35
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/index.html#//apple_ref/c/econst/UIModalPresentationFormSheet
Related
I am using a PDFView to display images in my app (built using SwifUI), simply for quick and easy pinch-to-zoom functionality. This worked perfectly in iOS 15, but since updating to iOS 16, the app freezes when attempting to load the image viewer (PhotoDetailView below). The issue persists across both the simulator and a physical device.
Here is the code I'm using:
import SwiftUI
import PDFKit
struct PhotoDetailView: UIViewRepresentable {
let image: UIImage
func makeUIView(context: Context) -> PDFView {
let view = PDFView()
view.document = PDFDocument()
guard let page = PDFPage(image: image) else { return view }
view.document?.insert(page, at: 0)
view.autoScales = true
return view
}
func updateUIView(_ uiView: PDFView, context: Context) {
// empty
}
}
When I run the code on iOS 16.0 in the simulator, I get 2 errors in the console:
[Assert] -[UIScrollView _clampedZoomScale:allowRubberbanding:]: Must be called with non-zero scale
[Unknown process name] CGAffineTransformInvert: singular matrix.
I have been able to isolate the issue to view.autoscales = true. If I print view.scaleFactor, I can see that it is 1.0 before the autoscale and 0.0 afterward (which is what appears to be prompting the errors). These errors also show up in the console when using iOS 15 in the simulator, but the images load as expected.
When view.autoscales = true is commented out, the image loads, albeit at a size that is much larger than the device screen.
Does anyone have any idea what may be causing this? I'd really like to avoid having to build a custom viewer, since I'm just trying to let users quickly pinch to zoom on images.
I managed to resolve this issue. I'm posting my solution here, in case anyone else runs into the same type of problem.
The issue only occurred when using a NavigationLink to navigate to PhotoDetailView. This led me to look more closely at my navigation stack.
After some digging, I found that the problem was related to my use of .navigationViewStyle(.stack) on the NavigationView. I needed this modifier to get things to display correctly on iOS 15, but the same modifier was breaking my image viewer with iOS 16.
My solution was to create a custom container to replace NavigationView, which conditionally uses NavigationStack for iOS 16, or NavigationView + .navigationViewStyle(.stack) for iOS 15. That worked like a charm and my image viewer is back in action.
I found inspiration for my custom container here: https://developer.apple.com/forums/thread/710377
Our code was working with previous versions, but on iOS13 the custom notification content height is not working properly. Everything is visible as it should be, but the buttons are not clickable after a part of view. So for example after 320 pixel the custom views are not clickable. Running the same code on ios12 works.
func didReceive(_ notification: UNNotification) {
let content = notification.request.content
self.preferredContentSize = CGSize(width: self.view.frame.size.width, height: contentH)
self.view.setNeedsUpdateConstraints()
self.view.setNeedsLayout()
}
Any solution? Or is it an iOS13 bug?
##Update :
We are developing our app on iOS14 beta and the issue is still here. Just one thing is new related to this. When we are tapping the screen this is what we get.
NotificationContent[44466:2340668] [Assert]
UIScrollViewDelayedTouchesBeganGestureRecognizer was moved to a view
that isn't a scroll view, so we can't determine if the touch is on a
scroll indicator.
We are adding all the subviews to the viewcontroller's view (no custom containers).
Im not sure where you are setting the heights and widths from but alot has changed following IOS 13 for Notifications and Push notifications both , While push notifications remain a big hassel having to change tockens and more biggest effect for notifications is many of the UIApplicationDelegate lifecycle methods are no longer called.
There are now corresponding lifecycle methods in the UISceneDelegate. This means there is a need to listen to the UIScene.didEnterBackgroundNotification notification under iOS 13. Now that you may think that it does not have a direct effect on a height or a width of a notification , i faced something of that sort and having moving someone them accroding to the New lifecylce methods they rendered properly .
Im Not sure if your issue will be sorted but also take alook at the below link. Might help you.Even i refered to this while i was facing the issues
View controller responds to app delegate notifications in iOS 12 but not in iOS 13
In all versions of iOS — including every beta of iOS 11.0 except the GM, 15A372 — views inside of a UINavigationItem's titleView would receive touch events as normal, making it possible to have buttons in the title view.
In build 15A372, subviews of the titleView do not receive any touch events, so buttons in that view are useless. I've tested with both devices and Simulators running iOS 10 and don't see this behavior. I've opened rdar://34499607 about this and will update this question when I hear back, but I want to know if anyone else has encountered this, or has any temporary solutions.
Apple's documentation about the titleView property specifically notes that "custom views can contain buttons," making this a confusing change.
If this is the intended behavior, it's infuriating that they've waited until the almost-literal eleventh hour to make this significant change and neglect to include it in any documentation or release notes.
You can see this question link
Just override intrinsicContentSize property in your view:
import UIKit
class HeaderView: UIView {
override var intrinsicContentSize: CGSize {
return CGSize(width: 400, height: 55)
}
}
in my app I allow the multitasking mode.
But I need to do some action if my view is too restricted.
Watching Apple documentation I saw this image
You can see that in iPad Pro in SplitView, both views are regular, instead in other iPads both views are compact.
I there something that allow me to know if my current view is regular or compact?
Thanks
This is my solution:
if (self.view.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassRegular){
NSLog(#"REGULAR HORIZONTAL");
return TRUE;
}else{
NSLog(#"COMPACT HORIZONTAL");
return FALSE;
}
If you need to handle it programatically, you can override -traitCollectionDidChange: and look at the self.traitCollection property on that view and make changes depending on the output.
However -viewWillTransitionToSize:withTransitionCoordinator: will get you a more fine grained response to how big the view controller has been resized to.
I am trying to take a screenshot of absolutely everything that is displayed on the iPhone display, in the same way that pressing the home + power buttons together does. The code I currently have to screenshot is this:
func screenShotMethod() {
//hide UI
buttonTrigger.hidden = true
//take screenshot
let layer = UIApplication.sharedApplication().keyWindow!.layer
let scale = UIScreen.mainScreen().scale
UIGraphicsBeginImageContextWithOptions(view.frame.size, false, scale);
layer.renderInContext(UIGraphicsGetCurrentContext()!)
let screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
UIImageWriteToSavedPhotosAlbum(screenshot, nil, nil, nil)
//show UI
buttonTrigger.hidden = false
}
The point is that I am using the camera and putting a picture over any face it detects, and the easiest way to save that to the camera roll is just to hide the UI and screenshot the screen. With this method however, I get a screenshot of the face tracking picture, in the correct position and size, but not of what the camera sees underneath - just white. I am enabling the camera using the CameraEngine framework in the viewDidLoad() like this:
override func viewDidLoad() {
super.viewDidLoad()
self.cameraEngine.startSession()
Is there a better way to screenshot everything to behave like the hardware induced method? Or how could I include what the camera sees in the screenshot?
Thank you!
UPDATE: In case anyone in the future wants to know how I fixed this, because I can't screenshot things I'm not drawing myself, I solved this issue by taking a picture with the camera and setting that image as the background of the view, and then performing the screenshot function and it works!
Starting in iOS 9 it is no longer possible to take a screenshot that includes elements of the screen not drawn by your program. You can only capture your application's views and layers. Apple doesn't expose the function that is triggered by power+home to third party developers.