I have an issue with a OSX application. I want it to display an image, so I create an NSImageView object, and linked it to my view controller. I then ceate a function that should load an image from a selected folder. I get the image url correctly an dtry to load the image onto the NSImageView but that doesn't work (with no rpeorted error). The image is a tiff file, and the isValid variable return false it seems...
imageAve is the name of the NSImageView outlet :
#IBOutlet weak var imageAve: NSImageView!
Here the code of the function in question :
func loadImage() { //load the tiff file
let image_url = String(describing: self.loadedtraces.tracefilesurls[self.indexSelected])
let image_url_cut = String(image_url[image_url.index(image_url.startIndex, offsetBy: 7)...image_url.index(image_url.endIndex, offsetBy: -8)] + "_ave_merged.tif")
if FileManager.default.fileExists(atPath: image_url_cut) { //test if the file exists and that works fine.
let image_average = NSImage(byReferencingFile: image_url_cut)
if (image_average?.isValid == false) {
self.alert.informativeText = "The image is invalid."
self.alert.alertStyle = .informational
self.alert.icon = alert_info_logo
self.alert.beginSheetModal(for: self.view.window!)
} else {
self.imageAve.needsDisplay = true
self.imageAve.image = image_average
}
} else {
self.alert.informativeText = "The average merge image file does not exist in the traces folder."
self.alert.alertStyle = .informational
self.alert.icon = alert_info_logo
self.alert.beginSheetModal(for: self.view.window!)
}
}
Thanks to everyone who might able to help !
Related
So I have a folders of images in firebase and all the folders have a name, when in viewcontriller I press the button with specific name I need to receive images from the folder with same name. I have done it with just for each loop, here is the cod of my realization:
db.collection(name!).getDocuments { (snapshot, error) in
if error == nil && snapshot != nil {
var paths = [String]()
for doc in snapshot!.documents{
paths.append(doc["url"] as! String)
}
for path in paths{
let storageRef = Storage.storage().reference()
// Specify the path
let fileRef = storageRef.child(path)
// Retrive the data
fileRef.getData(maxSize: 5 * 1024 * 1024) { (data, error) in
if error == nil && data != nil{
// Create a UIImage and put it into our array for display
if let image = UIImage(data: data!){
DispatchQueue.main.async {
self.retriewedImages.append(image)
let button = UIButton(frame: CGRect(x: 10+counterX, y: 200+counterY, width: 100, height: 200))
button.setImage(image, for: .normal)
self.view.addSubview(button)
counterY = counterY + 210
if counterY == 420{
counterY = 0
counterX = counterX + 110
}
}
}
}
}
}
}
}
}
I have done in in override func viewDidLoad()
So the main problem is that firstly when view controller appears i have ugly animation when that pictures one by one appear, I need some decision or hove instantly show all of them when that view controller appears (the best way will be if they appear with view contoller), probably i need to use for each loop to create array of pictures and after that instantly show all the array or probably i may preload with the same for each loop photos. I really do not know how to deal with it and maybe someone know how to do it without ugly animation?
I have a function like:
func presentPhotoLibrary() {
let photoLibrary = PHPhotoLibrary.shared()
if PHPhotoLibrary.authorizationStatus(for: .readWrite) == .authorized {
var config = PHPickerConfiguration(photoLibrary: photoLibrary)
config.selectionLimit = 0
let phPicker = PHPickerViewController(configuration: config)
phPicker.delegate = self
present(phPicker, animated: true)
}
}
I also have a collection view that the user can select images from.
When the picker is presented, I want the selected images from the collection view to be shown as selected in the photo library picker. This function is achievable by PHPickerConfiguration 's preselectedAssetIdentifiers for iOS 15. However, I'm trying to have the same behaviour for iOS 14.
Any ideas?
I am grabbing a screenshot of a sub-view in my SwiftUI View to immediately pass to a share sheet in order to share the image.
The view is of a set of questions from a text array rendered as a stack of cards. I am trying to get a screenshot of the question and make it share-able along with a link to the app (testing with a link to angry birds).
I have been able to capture the screenshot using basically Asperi's answer to the below question:
How do I render a SwiftUI View that is not at the root hierarchy as a UIImage?
My share sheet launches, and I've been able to use the "Copy" feature to copy the image, so I know it's actually getting a screenshot, but whenever I click "Message" to send it to someone, or if I just leave the share sheet open, the app crashes.
The message says it's a memory issue, but doesn't give much description of the problem. Is there a good way to troubleshoot this sort of thing? I assume it must be something with how the screenshot is being saved in this case.
Here are my extensions of View and UIView to render the image:
extension UIView {
func asImage() -> UIImage {
let renderer = UIGraphicsImageRenderer(bounds: bounds)
return renderer.image { rendererContext in
layer.render(in: rendererContext.cgContext)
}
}
}
extension View {
func asImage() -> UIImage {
let controller = UIHostingController(rootView: self)
// locate far out of screen
controller.view.frame = CGRect(x: 0, y: CGFloat(Int.max), width: 1, height: 1)
UIApplication.shared.windows.first!.rootViewController?.view.addSubview(controller.view)
let size = controller.sizeThatFits(in: UIScreen.main.bounds.size)
controller.view.bounds = CGRect(origin: .zero, size: size)
controller.view.sizeToFit()
controller.view.backgroundColor = .clear
let image = controller.view.asImage()
controller.view.removeFromSuperview()
return image
}
}
Here's an abbreviated version of my view - the button is about halfway down, and should call the private function at the bottom that renders the image from the View/UIView extensions, and sets the "questionScreenShot" variable to the rendered image, which is then presented in the share sheet.
struct TopicPage: View {
var currentTopic: Topic
#State private var currentQuestions: [String]
#State private var showShareSheet = false
#State var questionScreenShot: UIImage? = nil
var body: some View {
GeometryReader { geometry in
Button(action: {
self.questionScreenShot = render()
if self.questionScreenShot != nil {
self.showShareSheet = true
} else {
print("Did not set screenshot")
}
}) {
Text("Share Question").bold()
}
.sheet(isPresented: $showShareSheet) {
ShareSheet(activityItems: [questionScreenShot!])
}
}
}
private func render() -> UIImage {
QuestionBox(currentQuestion: self.currentQuestions[0]).asImage()
}
}
I've found a solution that seems to be working here. I start the variable where the questionScreenShot gets stored as nil to start:
#State var questionScreenShot: UIImage? = nil
Then I just make sure to set it to 'render' when the view appears, which means it loads the UIImage so if the user clicks "Share Question" it will be ready to be loaded (I think there was an issue earlier where the UIImage wasn't getting loaded in time once the sharing was done).
It also sets that variable back to nil on disappear.
.onAppear {
self.currentQuestions = currentTopic.questions.shuffled()
self.featuredQuestion = currentQuestions.last!
self.questionScreenShot = render()
}
.onDisappear {
self.questionScreenShot = nil
self.featuredQuestion = nil
}
I was following Apple Documentation and example project to load 3d Object using .SCN file with Virtual Object (subclass of SCNReferenceNode) class but suddenly i needed to change the model from .scn to usdz . Now my usdz object is loading successfully but it is not on surface (midway in the air) and i can't interact with it like (tap , pan , rotate) ... Is there any other way to get interaction with usdz object and how can I place it on the surface like I was doing it before with .scn file
For getting model URL (downloaded from server)
static let loadDownloadedModel : VirtualObject = {
let downloadedScenePath = getDocumentsDirectory().appendingPathComponent("\(Api.Params.inputModelName).usdz")
return VirtualObject(url: downloadedScenePath)!
}()
Loading it from URL
func loadVirtualObject(_ object: VirtualObject, loadedHandler: #escaping (VirtualObject) -> Void) {
isLoading = true
loadedObjects.append(object)
// Load the content asynchronously.
DispatchQueue.global(qos: .userInitiated).async {
object.reset()
object.load()
self.isLoading = false
loadedHandler(object)
}
}
Placing in the scene
func placeObjectOnFocusSquare() {
virtualObjectLoader.loadVirtualObject(VirtualObject.loadDownloadedModel) { (loadedObject) in
DispatchQueue.main.async {
self.placeVirtualObject(loadedObject)
self.setupBottomButtons(isSelected: true)
}
}
}
func placeVirtualObject(_ virtualObject: VirtualObject) {
guard let cameraTransform = session.currentFrame?.camera.transform,
let focusSquarePosition = focusSquare.lastPosition else {
statusViewController.showMessage("CANNOT PLACE OBJECT\nTry moving left or right.")
return
}
Api.Params.selectedModel = virtualObject
virtualObject.name = String(Api.Params.inputPreviewId)
virtualObject.scale = SCNVector3(Api.Params.modelXAxis, Api.Params.modelYAxis, Api.Params.modelZAxis)
virtualObject.setPosition(focusSquarePosition, relativeTo: cameraTransform, smoothMovement: false)
updateQueue.async {
self.sceneView.scene.rootNode.addChildNode(virtualObject)
}
}
.usdz object in sceneview
After so many tries , finally i found out that dynamic scaling of the model causing problem , Reference to this
iOS ARKit: Large size object always appears to move with the change in the position of the device camera
I scaled the object to 0.01 for all the axis (x,y and z)
virtualObject.scale = SCNVector3Make(0.01, 0.01, 0.01)
I'm trying to create a multipage PDF file from NSImages in swift on macOS. How do i set the PDFPage label and how do i trigger the generation of the preview thumbnails.
PDFPage has a variable for the label:
https://developer.apple.com/documentation/pdfkit/pdfpage/1504088-label
but i didn't find a way to set the label i tried to set the label to 1 with: page.setValue("1", forKey: "label") but this did nothing
I didn't find a way to trigger the generation of thumbnails.
code example for one page:
//stroyboard pdfView
#IBOutlet weak var myPdfView: PDFView!
//Storyboad PDFThumbnailView
#IBOutlet weak var myPDFThumbnailView:PDFThumbnailView!
//create a new PDFDocument
var myPDFDocument = PDFDocument()
//image path
guard let pngPath = Bundle.main.url(forResource: "example", withExtension: "png") else { return }
//create NSImage
if let firstPageImage = NSImage(contentsOf: pngPath){
//PDFPage
if let page = PDFPage(image: firstPageImage) {
//insert Page in PDFDocument
myPDFDocument.insert(page, at: myPDFDocument.pageCount)
}
}
//set PDFDocument
myPdfView.document = myPDFDocument
//set PDFView
myPDFThumbnailView.pdfView = myPdfView
Expected result:
a thumbnail of the PDF page with the label "1" appears in PDFThumbnailView and the PDF pages are rendered in PDFView.
Actual result:
a blank thumbnail with the label "Label" appears in PDFThumbnailView
and the PDF pages are rendered in PDFView.
EDIT:
My workaround to solve my problems is to save the PDFDocument to disk and reload it. It's not pretty but it's working... any advice is welcome!
myPDFDocument.write(toFile: "path/to/temp/folder/mytemp.pdf")
if let document = PDFDocument(url: URL(fileURLWithPath: "path/to/temp/folder/mytemp.pdf"))
{
myPDFDocument = document
}
There doesn't appear to be a method for setting the label of a PDFPage. The label property is Read-only.
This value is actually the displayed page number, so shouldn't normally need setting.